我现在的编程方法,不再是以前的整块应用,和C/S应用的两层架构,现在流行的编程方式是三层架构,就是表示层,商业逻辑,还有数据库都相互独立。
    远程方法调用正是基于三层架构设计的中间层。远程方法调用的原理是桩和骨架结构。主要有三层,分别是桩/骨架层,远程引用层,还有传输层。
    要完成一个简单的RMI应用要分为以下几个简单的步骤:
    1。定义远程接口
    2。定义和实现RMI服务器类
    3。定义和实现客户端类
    4。编译以上的源码
    5。生成桩/骨架
    6。创建安全策略
    7。启动RMI注册表
    8。启动服务器
    9。启动客户端
 
我们来做一个例子,在服务器上有一个连接数据库,插入值的方法,我们在客户端要使用这个方法,来真正的插入一个值!
    第一步:先编写一个接口AccountServer.java,这个接口要继承Remote接口,并且提供一个远程方法insertDetails(),这个方法要抛出RemoteException异常,代码如下:

    import java.rmi.Remote;
import java.rmi.RemoteException;

public interface AccountServer extends Remote
{
    public String insertDetails(String firstName, String lastName,
            String phone, String income, String accountType)
            throws RemoteException;
}

    第二步:实现远程对象类,就是RMI服务器,AccountServerImpl.java,这个类要继承UnicastRemoteObject类,并且要实现自己写的远程接口类AccountServer,首先要定义远程对象构造器,然后就是要实现远程接口中的方法,这个方法来连接mysql数据库,并且插入值.然后我们main方法中,设置安全管理程序,然后创建远程对象,接着注册远程对象.代码如下:

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class AccountServerImpl extends UnicastRemoteObject implements
        AccountServer
{
    private Connection con;

    public AccountServerImpl() throws RemoteException
    {
        super();
    }

    public String insertDetails(String firstName, String lastName,
            String phone, String income, String accountType)
            throws RemoteException
    {
        int rowsAffected = 0;
        String sReturn = "fail";
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager
                    .getConnection(
                            "jdbc:mysql://127.0.0.1/jsptest?useUnicode=true&characterEncoding=GBK",
                            "root", "");
            PreparedStatement ps = con
                    .prepareStatement("insert into User_info values(?,?,?,?,?)");
            ps.setString(1, "firstName");
            ps.setString(2, "lastName");
            ps.setString(3, "phone");
            ps.setString(4, "income");
            ps.setString(5, "accountType");

            rowsAffected = ps.executeUpdate();

            if (rowsAffected > 0)
            {
                sReturn = "success";
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();           
        }
        return sReturn;
    }

    public static void main(String[] args)
    {
 //设置安全管理程序
        System.setSecurityManager(new RMISecurityManager());

        try
        {
     //创建远程对象
            AccountServerImpl as = new AccountServerImpl();
            //注册远程对象
            Naming.rebind("AccountServer", as);
            System.out.println("RMI服务器启动成功");
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
        catch (Exception e1)
        {
            e1.printStackTrace();
        }
    }

}
       第三步:编写客户端代码,Client.java 这个代码中有两个重要的任务,就是得到远程对象的应用,然后调用远程对象,其余的都是界面部分,就不再讲解,代码如下:

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.Naming;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Client
{
    public static void main(String[] args)
    {
        ClientFrame frame = new ClientFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.show();
    }
}

class ClientFrame extends JFrame
{
    public ClientFrame()
    {
        setTitle("客户端");
        setSize(200, 220);

        Container con = getContentPane();
        ClientPanel panel = new ClientPanel();
        con.add(panel);
    }
}

class ClientPanel extends JPanel
{
    private JLabel lfirst, llast, lphone, lincome, ltype;

    private JTextField ffirst, flast, fphone, fincome, ftype;

    private JButton submit;

    public ClientPanel()
    {
        lfirst = new JLabel("   姓:");
        llast = new JLabel("   名:");
        lphone = new JLabel("电话:");
        lincome = new JLabel("来自:");
        ltype = new JLabel("类型:");

        ffirst = new JTextField(10);
        flast = new JTextField(10);
        fphone = new JTextField(10);
        fincome = new JTextField(10);
        ftype = new JTextField(10);

        submit = new JButton(" 提  交 ");
        submit.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {
                    //得到远程对象
                    AccountServer as = (AccountServer) Naming
                            .lookup("rmi://localhost/AccountServer");
                    String firstName = ffirst.getText();
                    String lastName = flast.getText();
                    String phone = fphone.getText();
                    String income = fincome.getText();
                    String accountType = ftype.getText();
             //调用远程方法
                    String str = as.insertDetails(firstName, lastName, phone,
                            income, accountType);
                    if ("fail".equals(str))
                    {
                        JOptionPane.showMessageDialog(null, "插入失败");
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(null, "插入成功");
                    }

                }
                catch (Exception e2)
                {
                    e2.printStackTrace();
                }
            }
        });

        add(lfirst);
        add(ffirst);
        add(llast);
        add(flast);
        add(lphone);
        add(fphone);
        add(lincome);
        add(fincome);
        add(ltype);
        add(ftype);
        add(submit);
    }
}

       第四步:在Dos下,进入代码所在目录,使用javac *.java 来编译所有代码
       第五步:在class文件所在目录使用 rmic AccountServerImpl来生成桩和骨架(AccountServerImpl_Skel.class和AccountServerImpl.Stub.class)
       第六步:用policytool工具来创建安全策略文件,放开所有的权限,保存.java.policy文件在C:\Documents and Settings\Administrator文件夹下
       第七步:使用start rmiregistry命令来启动注册表,默认使用1099端口,我们不需要改变
       第八步:java -Djava.rmi.server.codebase=file:/e:/aa/ -classpath .;%CLASSPATH% AccountServerImpl来启动服务器,注意由于服务器中要使用Mysql数据库,所有我们引入使用数据库的jar包,将mysql的jar包添加的CLASSPATH,就OK呢
       第九步:使用java Client来启动客户端,和得到图形界面的客户端,填入数据,点击提交,数据就会添加进入数据库

附:
数据库名称:jsptest
表名:user_info
表结构:
CREATE TABLE user_info (
  firstName varchar(50) NOT NULL default '',
  lastName varchar(50) NOT NULL default '',
  phone varchar(20) NOT NULL default '',
  income varchar(30) NOT NULL default '',
  accountType varchar(50) NOT NULL default '',
  PRIMARY KEY  (firstName)
)