Java Rmi 简明教程

Java RMI - Database Application

在上一章中,我们创建了一个示例 RMI 应用程序,其中客户端调用一个显示 GUI 窗口(JavaFX)的方法。

在本章中,我们将举例了解客户端程序如何检索驻留在服务器上的 MySQL 数据库中的一个表中的记录。

假设我们在数据库 details 中有一个表,名为 student_data 如下所示。

+----+--------+--------+------------+---------------------+
| ID | NAME   | BRANCH | PERCENTAGE | EMAIL               |
+----+--------+--------+------------+---------------------+
|  1 | Ram    | IT     |         85 | ram123@gmail.com    |
|  2 | Rahim  | EEE    |         95 | rahim123@gmail.com  |
|  3 | Robert | ECE    |         90 | robert123@gmail.com |
+----+--------+--------+------------+---------------------+

假设用户名为 myuser ,密码为 password

Creating a Student Class

使用 settergetter 方法创建一个 Student 类,如下所示。

public class Student implements java.io.Serializable {
   private int id, percent;
   private String name, branch, email;

   public int getId() {
      return id;
   }
   public String getName() {
      return name;
   }
   public String getBranch() {
      return branch;
   }
   public int getPercent() {
      return percent;
   }
   public String getEmail() {
      return email;
   }
   public void setID(int id) {
      this.id = id;
   }
   public void setName(String name) {
      this.name = name;
   }
   public void setBranch(String branch) {
      this.branch = branch;
   }
   public void setPercent(int percent) {
      this.percent = percent;
   }
   public void setEmail(String email) {
      this.email = email;
   }
}

Defining the Remote Interface

定义远程接口。此处,我们定义名为 Hello 的远程接口,其中有一个名为 getStudents () 的方法。此方法返回包含 Student 类对象的列表。

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.*;

// Creating Remote interface for our application
public interface Hello extends Remote {
   public List<Student> getStudents() throws Exception;
}

Developing the Implementation Class

创建一个类并实现上面创建的 interface.

此处,我们正在实现 Remote interfacegetStudents() 方法。当您调用此方法时,它会检索名为 student_data 的表的记录。使用其 setter 方法将这些值设置到 Student 类,将其添加到一个列表对象并返回该列表。

import java.sql.*;
import java.util.*;

// Implementing the remote interface
public class ImplExample implements Hello {

   // Implementing the interface method
   public List<Student> getStudents() throws Exception {
      List<Student> list = new ArrayList<Student>();

      // JDBC driver name and database URL
      String JDBC_DRIVER = "com.mysql.jdbc.Driver";
      String DB_URL = "jdbc:mysql://localhost:3306/details";

      // Database credentials
      String USER = "myuser";
      String PASS = "password";

      Connection conn = null;
      Statement stmt = null;

      //Register JDBC driver
      Class.forName("com.mysql.jdbc.Driver");

      //Open a connection
      System.out.println("Connecting to a selected database...");
      conn = DriverManager.getConnection(DB_URL, USER, PASS);
      System.out.println("Connected database successfully...");

      //Execute a query
      System.out.println("Creating statement...");

      stmt = conn.createStatement();
      String sql = "SELECT * FROM student_data";
      ResultSet rs = stmt.executeQuery(sql);

      //Extract data from result set
      while(rs.next()) {
         // Retrieve by column name
         int id  = rs.getInt("id");

         String name = rs.getString("name");
         String branch = rs.getString("branch");

         int percent = rs.getInt("percentage");
         String email = rs.getString("email");

         // Setting the values
         Student student = new Student();
         student.setID(id);
         student.setName(name);
         student.setBranch(branch);
         student.setPercent(percent);
         student.setEmail(email);
         list.add(student);
      }
      rs.close();
      return list;
   }
}

Server Program

RMI 服务器程序应实现远程接口或扩展实现类。此处,我们应创建一个远程对象并将其绑定到 RMI registry

以下是此应用程序的服务器程序。此处,我们将扩展上面创建的类,创建一个远程对象并使用绑定名称 hello 将其注册到 RMI 注册表中。

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server extends ImplExample {
   public Server() {}
   public static void main(String args[]) {
      try {
         // Instantiating the implementation class
         ImplExample obj = new ImplExample();

         // Exporting the object of implementation class (
            here we are exporting the remote object to the stub)
         Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

         // Binding the remote object (stub) in the registry
         Registry registry = LocateRegistry.getRegistry();

         registry.bind("Hello", stub);
         System.err.println("Server ready");
      } catch (Exception e) {
         System.err.println("Server exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

Client Program

以下是此应用程序的客户端程序。此处,我们正在获取远程对象并调用名为 getStudents() 的方法。它从列表对象中检索表记录并显示它们。

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

public class Client {
   private Client() {}
   public static void main(String[] args)throws Exception {
      try {
         // Getting the registry
         Registry registry = LocateRegistry.getRegistry(null);

         // Looking up the registry for the remote object
         Hello stub = (Hello) registry.lookup("Hello");

         // Calling the remote method using the obtained object
         List<Student> list = (List)stub.getStudents();
         for (Student s:list)v {

            // System.out.println("bc "+s.getBranch());
            System.out.println("ID: " + s.getId());
            System.out.println("name: " + s.getName());
            System.out.println("branch: " + s.getBranch());
            System.out.println("percent: " + s.getPercent());
            System.out.println("email: " + s.getEmail());
         }
      // System.out.println(list);
      } catch (Exception e) {
         System.err.println("Client exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

Steps to Run the Example

以下是运行我们的 RMI 示例所需的步骤。

Step 1 − 打开已存储所有程序的文件夹,并按以下操作编译所有 Java 文件。

Javac *.java
stored programs

Step 2 − 使用以下命令启动 rmi 注册表。

start rmiregistry
start execution

这会在一个单独的窗口中启动一个 rmi 注册表,如下所示。

separate window

Step 3 − 按以下操作运行服务器类文件。

Java Server
run server

Step 4 - 如下所示运行客户端类文件。

java Client
client file