Sử dụng RMI với APPLET

Khi viết chương trình ứng dụng nhúng applet mà sử dụng RMI thì có một sổ điểm đặc biệt cần lưu ý. Các chương trình applet có bộ quản lý an ninh riêng bởi vì nó phải thực hiện bên trong trình duyệt. Vì vậy, không cần sử dụng RMISecuri tyManager ờ chương trình khách.

Ngoài ra ta cũng cần quan tâm nơi cất giữ các tệp *_stub.class, *Server. class. Khi mở một trang Web với thẻ APPLET, trình duyệt sẽ nạp những tệp trên và tham chiểu đến thẻ này. Vì thế, các đối tượng phục vụ bắt buộc phải có mặt trên cùng máy của trang Web. Nghĩa là trên máy phục vụ phải có:

  • Trang Web
  • Mã của chương trình applet
  • Các lơp Stub
  • Các đối tượng phục vụ
  • Bộ đăng ký RMI registry

Ví dụ 2.3. Ta xây dựng một chương trình WarehouseApplet để thực hiện như ờ ví dụ 2.2.

Khi thực hiện các chương trình applet, ta cần phân tán các tệp mã lệnh như sau:

  • java . rmi . registry. Re gist rylmpl ờ đâu đó trên máy chủ và bộ đăng kỷ registry phải được chạy trước khi khởi động applet.
  • Warehouse Server ờ đâu đó trên máy chủ và bộ đăng ký registry phải được chạy trước khi khởi động
  • Warehouse Imp 1 có thể ờ đâu đó trên máy chủ sao cho WarehouseServer có thể tìm được nó.
  • WarehouseApplet để ờ thư mục mà thẻ APPLET tham chiếu được.
  • Các tệp lớp class phải ở cùng thư mục của WarehouseApplet.
  • Chương trình applet tìm các đối tượng trong danh sách đăng ký RMI registry trên máy, nơi chứa chính applet đó. Để tim được máy cùa nó, ta sử dụng getCodeBase () và phương thức getHost ().

String url = getCodeBase().getHost(); url = “mỉ://” + url;

centralWarehouse = (Warehouse)Naming.lookup(url +

“/centralWarehouse”);

Chương trình WarehouseApplet được viết như sau.

import j ava.awt.*;

import java.awt.event.*;

import java.applet.*;

import java.util.*;

import java.rmi.*;

import java.rmi.server.*;

import j avax.swing,*;

public class WarehouseApplet extends JApplet implements ActionListener{

public void init(){ initui();

String url = getCodeBase() .getHost (); url = “rmi://” + url; try {

centralWarehouse = (Warehouse)Naming.lookup (url + “/central_warehouse”);

}catch(Exception e){

showStatus(“Error: Can’t connect to warehouse! ” + e);

}

}

private void callWarehouse(Customer c){ try {

products = centralWarehouse.find (c); //descriptionListModel. clear () ; result.setText(c + “\n”); for(int i = 0; i < products.size (); i + + ) { Product p = (Product)products.get(i); String t = p.getDescription() + “\n”; result.append(t);

}

}catch(Exception e){

showStatus(“Error: ” + e);

}

}

public void actionPerformed(ActionEvent evt){

Object[] hobbyObjects = hobbies.getSelectedValues();

String[] hobbyStrings = new String[hobbyQbjects.length]; System.arraycopy(hobbyObjects, 0, hobbyStrings, 0, hobbyObjects.length );

Customer c = new Customer(Integer.parselnt(age.get1Text()), (male.isSelected()? Product.MALE : 0)

+ (female.isSelected()? Product.FEMALE : 0) , hobbyStrings); callWarehouse(c);

}

private void initUI(){

getContentPane () .setLayout(new GridBagLayout()};

GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 100;

gbc.weighty = 0;

add(new JLabel(“Age:”) , gbc, 0, 0, 1, 1); age = new JTextField(4) ; age.setText(“20”) ; add(age, gbc, 1, 0, 1, 1);

male = new JCheckBox(“Hale” , true);

add(male, gbc, 0, 1, 1, 1);

female = new JCheckBox(“Female”, true);

add(female, gbc, 1, 1, 1, 1);

gbc.weighty = 100;

add(new JLabe1 (“Hobbies”), gbc, 0, 2, 1, 1);

String[] choices = {“Ghrdaning”, “Beauty”, “Gcnputers”, “Household”) ; gbc.fill = GridBagConstraints.BOTH; hobbies = new JList (choices);

add(new JScrollPane(hobbies), gbc, 1,2, 1,1); gbc.weighty = 0;

gbc.fill = GridBagConstraints.NONE;

JButton submitButton = new JButton(“Submit”); add(submitButton, gbc, 0,3, 2,1); submitButton.addActionListener(this); gbc.weighty = 100;

gbc.fill = GridBagConstraints.BOTH; result = new JTextArea(4, 40); result.setEditable(false); add(result, gbc, 0, 4, 2,1);

}

private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h){ gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w;

gbc.gridheight = h; getContentPane().add(c, gbc);

}

private Warehouse centralWarehouse;

private JTextField age;

private JCheckBox male, female;

private JList hobbies; //, descriptions;

private JTextArea result;

private JButton submitButton;

private Vector products;

// private DefaultListModel descriptionListModel;

}

Như đã nói ở trên, đối với các chương trình applet không cần sữ dụng bộ RMISecurityManager nên cũng không cần soạn thào tệp client.policy. Như chúng ta đã biết để chạy được chương trinh applet thì phải nhúng chúng vào thè APPLET của HTML, ví dụ tệp WarehouseApplet. html đơn giản nhất có dạng:

<applet code = “WarehouseApplet.class’’ heìght=”300” wìdth=”300”> </applet>

Quá trình dịch, thực hiện chương trình WarehouseApplet triệu gọi từ xa cũng gồm năm bước, trong đó bốn bước đầu giống như ờ ví dụ 2.1. Bước thứ năm có thề sử dụng trình duyệt IE để mờ tệp WarehouseApplet.html hoặc sử dụng appletviewer cùa JDK.

D: \users\Server\warehouse>C:\j2sdkl.4.0\bin\

appletviewer warehouseApplet.html