云自无心水自闲

天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!
posts - 288, comments - 524, trackbacks - 0, articles - 6
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Java5.0中RMI的改变--使用更容易

Posted on 2006-03-03 13:34 云自无心水自闲 阅读(866) 评论(0)  编辑  收藏 所属分类: Java
在Java5.0中对于RMI的使用发生了一些改变, 使得RMI的使用更加容易方便.
一. 定义RMI接口, 这一步最简单, 与以前相比, 也没有变化.
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Payment extends Remote {
    
public double calculatePayment(double principal, double annualRate, int terms)
                    
throws RemoteException;
}

注意点:
1. 必须继承java.rmi.Remote
2. 接口中的方法必须抛出java.rmi.RemoteException异常

二. 定义远程类实现接口
与以前相比, 也没有发生变化

import java.rmi.RemoteException;

public class PaymentImpl implements Payment {

    
public double calculatePayment(double principal, double annRate, int years)
                                  
throws RemoteException {
        
double monthlyInt = annRate / 12;
        
double monthlyPayment = (principal * monthlyInt)
                    
/ (1 - Math.pow(1/ (1 + monthlyInt), years * 12));
        
return format(monthlyPayment, 2);
    }

    
public double format(double amount, int places) {
        
double temp = amount; 
        temp 
= temp * Math.pow(10, places);
        temp 
= Math.round(temp);
        temp 
= temp/Math.pow(10, places);
        
return temp;
    }

}

注意点:
1. 远程对象必须实现第一步定义的接口, 在这里是Payment接口.
2. 远程对象中可以定义接口中不包括的方法, 比如: format, 但是这些方法不能远程使用.
3. 实现远程方法时, 可以不抛出java.rmi.RemoteException异常


三. 定义远程服务
此处与以前相比, 发生了一些变化, 需要注意.

 

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
    
public class Server {
    
    
public Server() {}

    
public static void main(String args[]) {
    
    
try {
        PaymentImpl robj 
= new PaymentImpl();
        Payment stub 
= (Payment) UnicastRemoteObject.exportObject(robj, 0);

        Registry registry 
= LocateRegistry.getRegistry();
        registry.bind(
"Mortgage", stub);
        System.out.println(
"Mortgage Server is ready to listen");

    }
 catch (Exception e) {
        System.err.println(
"Server exception thrown: " + e.toString());
        e.printStackTrace();
    }

    }

}


而传统的做法是这样的:
public class Server extends java.rmi.server.UnicastRemoteObject implements aRemoteInterface{
    public Server(int port) {
         super(port);
    }
    ....
    Naming.bind(uniqueName, this);
    ....
}
 
请自行进行比较.

四. 定义客户端类
相应地, 这部分也有了变化.

 

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
    
private static Payment stub = null;
    
private Client() {}

    
public static void main(String[] args) {

    
double payment, principal = 80000;
        
double annualInterest = .065;
        
int years = 15;
    
try {
        Registry reg 
= LocateRegistry.getRegistry("localhost");
        stub 
= (Payment) reg.lookup("Mortgage");
        
    }
 catch (Exception e) {
        System.err.println(
"Client exception thrown: " + e.toString());
        e.printStackTrace();
    }

    
        
if (args.length == 3{
           
try {
              principal 
= Double.parseDouble(args[0]);
              annualInterest 
= Double.parseDouble(args[1]);
              years 
= Integer.parseInt(args[2]);
           }

           
catch (Exception e) {
              System.out.println(
"Wrong input " + e.getMessage() );
              System.exit(
0);
           }

           print(principal, annualInterest, years);
        
        }
 else {
            System.out.println(
"Usage: java Client principal annualInterest years ");
            System.out.println(
"\nFor example: java Client 80000 .065 15 ");
            System.out.println(
"\nYou will get the output like the following: \n");
        print(principal, annualInterest, years);
            System.exit(
0);
        }
        
        
    }

    
    
public static void print(double pr, double annRate, int years){
        
double mpayment = 0;
        
try {
            mpayment 
= stub.calculatePayment(pr, annRate, years);
        }
catch(Exception e) {
            System.out.println(
"Remote method exception thrown: " + e.getMessage());
        }

        System.out.println(
"The principal is $" + (int)pr);
        System.out.println(
"The annual interest rate is " + annRate*100 +"%");
        System.out.println(
"The term is " + years + " years");
        System.out.println(
"Your monthly payment is $" + mpayment);
    }

}



注意点: lookup服务的方法与以前是不同的

五. 测试使用
现在我们有了4个类
Payment.java-- a remote interface
PaymentImpl.java-- a remote object class
Server.java-- an RMI server
Client.java-- an RMI client

1. 我们把它们都放到一个目录下, 比如: 以 c:\myrmi
2. 使用javac编译这4个类. javac -d . Payment.java PaymentImpl.java Server.java Client.java
3. 注意: Java5.0的新特性, 现在在不需要在启动服务之前生成Stub了, stub现在自动生成.
而在Java5.0以前是需要用rmic手工生成的.
4. start rmiregistry, 出现一个窗口, 不要关闭.
5. start java Server, 出现一个窗口, 显示 Mortgage server is ready to listen...
6. 启动客户端java Client, 如果出现
The principal is $150000
The annual interest rate is 6.0%
The term is 15 years
Your monthly payment is $1265.79
那就大功告成了.

注意点: 安全策略机制进行了弱化, 不再需要指定策略文件 授这个权,那个权的了.




只有注册用户登录后才能发表评论。


网站导航: