这次是用java实现RMI 的远程调用:
编写的过程大致为:
1. 首先我们的启动Mysqlserver ,然后再里面建立一个数据库,以便我们在数据库中插入存放学生信息等。
2. 先编写一个接口DataServer,并且继承Remote类,然后再接口里面写上服务器端能实现的方法,然后再定义一个类DataServerImpl 继承UnicastRemoteObject 在实现接口DataServer,并且一一实现它定义在借口里面得到方法,这里我们重新写了一个类DBManager,用来实现与数据库的连接,包括插入数据,根据学号、姓名等进行查询等操作,其源代码见附件。
3. 下面就是需要使用rmic命令进行编译DataServerImpl文件,并且产生两个文件,产生这两个文件后就可以编写服务器端的代码了,主要是在主函数中生成一个DataServerImpl对象,然后在绑定一个端口在程序中,在绑定一个url地址,来绑定服务的对象,这样服务器端的程序就写好了。
4. 下面就是写客户端的代码了。
5. 首先是通过Naming.lookup(url),(url)就是服务器端指定的url地址这样就可以得到一个DataServer的对象,然后得到这样一个对象后就可以调用它的方法了。这样也就实现了调用远程服务器端的代码了,所以说这样RMI就比本上写完了。
首先是编写远程的接口调用函数:
<span style="font-size:16px;">import java.rmi.Remote; import java.rmi.RemoteException; public interface DataServer extends Remote { public void CreateTable() throws RemoteException; public void insert(int id ,String name,double Score) throws RemoteException; public double select(int id)throws RemoteException; public double select (String name)throws RemoteException; } </span>
由于代码中使用到了与数据库的连接,所以写了一个数据库的管理类,代码如下:
<span style="font-size:16px;">import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; public class DBManager { private static String user = "root"; private static String pass = "123456"; private static String className ="com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql://localhost:3306/students"; private static Connection conn; private static java.sql.Statement state; public static void init() { try { Class.forName(className); conn = DriverManager.getConnection(url,user,pass); state =conn.createStatement(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void CreateTable(){ String sql = "create table student (id int Primary key, name char (20),score double);"; try { state.execute(sql); } catch (SQLException e) { e.printStackTrace(); } } public static void insert(int id,String name,double score) { String sql = "insert into student values("+id+",'"+name+"',"+score+");"; try { state.execute(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static double select(int id) { String sql = "select score from student where id = "+id+";"; double result= 0; try { ResultSet rs = state.executeQuery(sql); while(rs.next()) { result = rs.getDouble("score"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } public static double select(String name) { String sql = "select score from student where name = '"+name+"';"; double result= 0; try { ResultSet rs = state.executeQuery(sql); while(rs.next()) { result = rs.getDouble("score"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } } </span>
下面就是编写实现类,要继承UnicastRemoteObject,并且实现上面定义的接口。
<span style="font-size:16px;">import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class DataServerImpl extends UnicastRemoteObject implements DataServer { static { DBManager.init(); } public DataServerImpl() throws RemoteException { super(); // TODO Auto-generated constructor stub } @Override public void CreateTable() throws RemoteException { DBManager.CreateTable(); } @Override public void insert(int id, String name, double score) throws RemoteException { DBManager.insert(id, name, score); } @Override public double select(int id) throws RemoteException { // TODO Auto-generated method stub double score = DBManager.select(id); return score; } @Override public double select(String name) throws RemoteException { double score = DBManager.select(name); return score; } } </span>
这样就基本上完成了,然后就是编写服务端的代码:
<span style="font-size:16px;">import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; public class RMIServer { public static void main(String[] args) { try { DataServerImpl dataServer = new DataServerImpl(); LocateRegistry.createRegistry(1111); //这里,服务端口号可任意指定 Naming.rebind("//localhost:1111/showScore", dataServer); System.out.println("服务已经启动。。"); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } </span>
使用命令空间绑定服务的地址,以及服务的名称,以便客户端实现远程调用。客户端的代码如下:
<span style="font-size:16px;">import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.util.Scanner; public class RMIClient { public static void main(String[] args) { Scanner sc = new Scanner(System.in); try { DataServer dataServer = (DataServer)Naming.lookup("//localhost:1111/showScore"); System.out.println("首先创建一个数据表,student"); dataServer.CreateTable(); System.out.println("创建成功。。"); boolean isrunning = true; while(isrunning) { System.out.println("请您按照数字选择操作。\n1.插入数据 2.按学号查找 3.按姓名查找 0.退出"); int select = sc.nextInt(); if(select == 1) { System.out.println("请您依次输入学生的学号、姓名、成绩:"); int num = sc.nextInt(); String name = sc.next(); double score = sc.nextDouble(); dataServer.insert(num, name, score); } else if(select == 2) { System.out.println("请您输入学生的学号:"); int num = sc.nextInt(); double score = dataServer.select(num); System.out.println("学号: "+num +" 成绩为: "+ score); } else if(select == 3) { System.out.println("请您输入学生的姓名:"); String name = sc.next(); double score = dataServer.select(name); System.out.println("姓名: "+name +" 成绩为: "+ score); } else if(select == 0) { isrunning = false; } else { System.out.println("输入有误,请您重新输入!"); } } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NotBoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } </span>
这样就基本上的完成了所有的工作。。。