Spring Remoting - Spring và RMI (P.2)

 

  Trong phần trước, tôi đã giới thiệu viết một ứng dụng RMI cơ bản như thế nào, chúng ta đã thực hiện một cách tiếp cận mới giúp cho việc tạo một ứng dụng trở nên đơn giản hơn, bằng cách không cần tạo stub và skeleton nữa, cũng không cần phải khởi động cửa sổ rmiregistry đen thui và khá.........vô dụng. Chúng ta đã đăng ký tất cả qua một bootstraps đơn giản.

Nhưng mong muốn mọi thứ đơn giản càng đơn giản hơn là yêu cầu chính đáng, vậy thì mời bạn tiếp tục với phần 2 Sự kết hợp Spring và RMI.

 

Phần 2: Spring và RMI:

Ứng dụng demo là một chương trình phân phối tên, tại client, người sử dụng sẽ nhập vào tên của một người nào đó, kết thúc bằng exit. Sau khi kết thúc, Server sẽ thông báo cho client biết tất cả những thông tin nó đã nhận được từ lúc khởi tạo, chi tiết tên từng người được nhập và vào thời gian nào.

deliveries

Nhìn vào kết quả này hy vọng bạn đã hình dung phần nào ứng dụng demo của chúng ta.

Tôi sẽ bắt đầu từ phần Server trước, đơn giản nó luôn là người phải bắt đầu mọi thứ trước khi có ai đó sử dụng.

Server:

IDeliveryService có 2 phương thức để xử lý trên đối tượng Delivery, dưới đây là 2 đoạn mã cho những đối tượng nói trên:

 

Delivery.java

package com.test.rmi.common;

import java.io.Serializable;
import java.util.Date;
import java.text.SimpleDateFormat;

public class Delivery implements Serializable {

    private static final long serialVersionUID = 1L;
    private String requesterName;
    private Date deliveryDate;

    public Delivery(String requesterName, Date deliveryDate) {
        this.requesterName = requesterName;
        this.deliveryDate = deliveryDate;
    }

    public String getRequesterName() {
        return requesterName;
    }

    public void setRequesterName(String requesterName) {
        this.requesterName = requesterName;
    }

    public Date getDeliveryDate() {
        return deliveryDate;
    }

    public void setDeliveryDate(Date deliveryDate) {
        this.deliveryDate = deliveryDate;
    }

    public String toString() {
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss");
        return "[Name =" + requesterName + ", Time of delivery ="
                + fmt.format(deliveryDate) + "]";
    }
}

và:

IDeliveryService .java

package com.test.rmi.common;

import java.util.List;

public interface IDeliveryService {

    public void newDelivery(Delivery delivery);

    public List<Delivery> getDeliveries();
}

Dịch vụ của chúng ta bao gồm 2 phương thức, phương thức thứ nhất có nhiệm vụ phân phối một đối tượng mới (Delivery object) và phương thức thứ 2 sẽ báo cáo chi tiết lại toàn bộ object Delivery mà nó đã phân phối.

Điều lưu ý nhất ở đây là IDeliveryService không cần phải thừa kết Interface java.rmi.Remote, và do đó nó cũng không cần ném ra ngoại lệ java.rmi.RemoteException, Spring sẽ lo liệu điều này cho chúng ta.

Và có một cài đặt cho dịch vụ này là:

DeliveryServiceImpl.java

package com.test.rmi.server;

import com.test.rmi.common.IDeliveryService;
import com.test.rmi.common.Delivery;

import java.util.List;
import java.util.ArrayList;

public class DeliveryServiceImpl implements IDeliveryService {

    private List<Delivery> deliveries = new ArrayList<Delivery>();

    public void newDelivery(Delivery delivery) {
        deliveries.add(delivery);
    }

    public List<Delivery> getDeliveries() {
        return deliveries;
    }
}

Sau khi có những đoạn mã phục vụ cho login dịch vụ của chúng ta, bây giờ là phần quan trọng nhất, cấu hình bean trong IoC container của Spring:

rmi-server-context.xml

<beans>
    <bean id="deliveryService"
        class="com.test.rmi.server.DeliveryServiceImpl">
    </bean>

    <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
        <property name="serviceName" value="delivery-service" />
        <property name="service" ref="deliveryService" />
        <property name="serviceInterface"
            value="com.test.rmi.common.IDeliveryService" />
        <property name="registryPort" value="1234" />
    </bean>
</beans>

Đầu tiên chúng ta tạo một ID cho bean com.test.rmi.server.DeliveryServiceImpl. Sau đó sử dụng RMIServiceExporter để tạo ra một RMI Service:

  • serviceName : chỉ định tên dịch vụ sẽ được map lên Server.
  • service : POJO mà nó sẽ tạo RMI Service.
  • serviceInterface : như tên của nó, đây là interface mà POJO ở trên đã cài đặt, nó là Proxy để "Giữ chỗ".
  • registryPort : cổng chúng ta sẽ mở dịch vụ.

Kết quả thông qua RmiServiceExporter chúng ta sẽ tạo ra một dịch vụ như sau:

rmi://[ServerName]:[Port]/[serviceName]

Tương ứng với khai báo trên, khi deploy trên máy cục bộ là :

rmi://localhost:1234/delivery-service

rmiserverspring

Và đương nhiên chúng ta cần một bootstraps cho dịch vụ của chúng ta:

public class RmiServerTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "com/test/rmi/server/rmi-server-context.xml");
    }
}

Client:

Phần việc còn lại của Client cũng khá dễ dàng vời Spring, RmiProxyFactoryBean sẽ giúp chúng ta nhận một dịch vụ đã được đăng ký trên server:

<beans>
    <bean id="deliveryService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://localhost:1234/delivery-service"/>
        <property name="serviceInterface" value="com.test.rmi.common.IDeliveryService"/>
    </bean>
</beans>

Chúng ta chỉ cần cung cấp địa chỉ của dịch vụ, tiếp theo là chỉ định Interface thế chỗ cho Object trên Server kia.

Và kết thúc ứng dụng của chúng ta, một ứng dụng client sử dụng dịch vụ delivery-service ra đời :

public class RmiClientTest {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "com/test/rmi/client/rmi-client-context.xml");
        IDeliveryService deliveryService = (IDeliveryService) ctx
                .getBean("deliveryService");


        String name = "";
        System.out.print("Please input Name: ");
        while (!(name = br.readLine()).equals("exit")) {
            System.out.println("Hello " + name);
            System.out.print("Please input Name: ");
            deliveryService.newDelivery(new Delivery(name, new Date()));
        }

        List<Delivery> deliveries = deliveryService.getDeliveries();
        System.out.println("Total number of deliveries: " + deliveries.size());
        Iterator<Delivery> it = deliveries.iterator();
        while (it.hasNext()) {
            Delivery delivery = (Delivery) it.next();
            System.out.println(" -" + delivery);
        }
    }
}

Người dùng sẽ lần lượt nhập vào tên mà họ muốn phân phát lên server (thông qua phương thức newDelivery), kết thúc bằng lệnh "exit", khi đó server sẽ thông báo toàn bộ delivery mà nó đã nhận được (Phương thức getDeliveries).

Hãy chạy ứng dụng demo của chúng ta, kết quả bạn đã thấy ở đầu trang và cảm nhận sự thú vị về RMI mà Spring mang lại, tất cả POJO đều có thể trở thành một RMI Service mà không còn cần một interface mang ý nghĩa "Đánh dấu" nữa java.rmi.Remote.

Dowload demo: Spring và RMI

About Langthang

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.
    Blogger Comment
    Facebook Comment

4 comments :