Please install JDK 1.3.1_02 or later with Java Plugin to view this page. Also, this page is best viewed with browsers (for examples, Mozilla 0.99 or later, IE 6.x or later) with CSS2 support. This document is provided as is. You are welcomed to use it for non-commercial purpose.
//
// Step 1. Create Interface
//
// Note: interface must extend java.rmi.Remote
//
public interface HelloIF extends java.rmi.Remote {
// the single method to be implemented: getHello
public String getHello()
throws java.rmi.RemoteException;
}
//
// Step 2. Create Interface Implementation
//
import java.rmi.*;
import java.rmi.server.*;
public class HelloImpl extends UnicastRemoteObject implements HelloIF
{
private String serviceName;
public HelloImpl(String s) throws RemoteException {
super();
serviceName = s;
}
public String getHello() throws RemoteException {
return "Hello World";
}
public static void main( String argv[] )
{
System.setSecurityManager(new RMISecurityManager());
try {
HelloImpl obj = new HelloImpl("HelloService");
// 你可以更改成你所需要的 hostname,甚至可以另外以
// hostname:port 來設定另一個 port,例如
// "//penguin.im.cyut.edu.tw:2110/HelloService".
Naming.rebind("//penguin.im.cyut.edu.tw/HelloService", obj);
System.out.println("HelloService registered.");
} catch (Exception e) {
System.out.println("HelloImpl Err: " + e.getMessage());
e.printStackTrace();
}
}
}
//
// Step 3. Create the client
//
import java.rmi.*;
public class HelloClient
{
public static void main( String argv[] )
{
String message = null;
try {
// 如果不是使用預設的 port,你也必須更改成 hostname:port, ex.
// "rmi://penguin.im.cyut.edu.tw:2110/HelloService"
HelloIF obj = (HelloIF) Naming.lookup(
"rmi://penguin.im.cyut.edu.tw/HelloService");
message = obj.getHello();
System.out.println(message);
} catch (Exception e)
{
System.out.println("HelloService exception: " +
e.getMessage());
e.printStackTrace();
}
}
}
grant {
permission java.net.SocketPermission "*:1024-","connect,accept";
permission java.net.SocketPermission "*:80","connect";
};
//
// Create Interface
//
public interface QueryIF extends java.rmi.Remote {
public java.util.Vector getSalary(int salary)
throws java.rmi.RemoteException;
}
//
// Step 2. Create Interface Implementation
//
import java.rmi.*;
import java.rmi.server.*;
import java.sql.*;
import java.util.*;
public class QueryImpl extends UnicastRemoteObject implements QueryIF
{
private String serviceName;
public QueryImpl(String s) throws RemoteException {
super();
serviceName = s;
}
public Vector getSalary(int salary) throws RemoteException {
Connection conn = null;
ResultSet rs = null;
Vector v = new Vector();
String qs = "select fname, lname, ssn, salary from employee " +
"where salary >= " +
String.valueOf(salary);
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// 請將下列的 UID, PWD 作適當的改變
conn = DriverManager.getConnection("jdbc:odbc:samples", UID, PWD);
Statement st = conn.createStatement();
rs = st.executeQuery(qs);
while(rs.next())
for(int i=1; i<=4; i++)
v.add(rs.getString(i));
// Clean up
rs.close();
st.close();
conn.close();
} catch (SQLException sqle) {
System.out.println("QueryImpl SQLException " + sqle.getMessage());
System.exit(0);
} catch (Exception e) {
System.out.println("QueryImpl Err: " + e.getMessage());
System.exit(1);
}
return v;
}
public static void main( String argv[] )
{
System.setSecurityManager(new RMISecurityManager());
try {
QueryImpl obj = new QueryImpl("QueryService");
// 請將下列的 hostname 作適度的改變
Naming.rebind("//hostname/QueryService", obj);
System.out.println("QueryService registered.");
} catch (Exception e) {
System.out.println("QueryImpl Err: " + e.getMessage());
}
}
}
import java.rmi.*;
import java.sql.*;
import java.util.*;
public class QueryClient
{
public static void main( String argv[] )
{
Vector v = null;
try {
// 這裡的 hostname 應該改成和 QueryImpl.java 相同的 hostname
QueryIF obj = (QueryIF) Naming.lookup(
"rmi://hostname/QueryService");
v = obj.getSalary(30000);
Enumeration e = v.elements();
StringBuffer sb = new StringBuffer();
int count = 0;
while(e.hasMoreElements())
{
for(int i=0; i<4; i++)
sb.append(e.nextElement() + "\t| ");
sb.append("\n");
}
System.out.println("" + sb);
} catch (Exception e) {
System.out.println("QueryService exception: " +
e.getMessage());
}
}
}
import java.rmi.*;
public class ListServices
{
public static void main( String argv[] )
{
if(argv.length != 1)
{
System.out.println("Usage: java ListServices hostname");
System.exit(0);
}
try {
String [] slist = Naming.list("rmi://" + argv[0] + "/");
if(slist.length == 0)
System.out.println("Currently, there is no registered services.");
else
for(int i=0; i<slist.length; i++)
System.out.println(slist[i]);
} catch (Exception e) {
System.out.println("ListServices exception: " +
e.getMessage());
}
}
}
RMI Client <--> (rmiregistry + RmiJdbc Server) <--> DB Server在以下的說明中,我們假設 client 是一部 win32 的電腦,rmiregistry 和 RmiJdbc Server 的電腦是 penguin,而資料庫伺服器就是系上的 SQL Server。執行 RMI Client 之前,必須先在 penguin 執行下列步驟:
import java.awt.*;
import javax.swing.*;
import java.sql.*;
import java.rmi.*;
import java.net.InetAddress;
/**
* This is a sample program for RmiJdbc client/server jdbc Driver
* RmiJdbc relies on Java RMI for jdbc objects distribution
*/
public class TestClient {
public static void main(String[] args) {
try {
// 非常有意思的用法,利用 showMessageDialog 可以內含其他
// 物件的方式來把 JPasswordField 包到 showMessageDialog
// 使得密碼的輸入不會被見到!
JLabel name=new JLabel("User Name");
JTextField uname=new JTextField();
JLabel passwd=new JLabel("Password");
JPasswordField pword=new JPasswordField();
Object[] ob={name,uname,passwd,pword};
JOptionPane.showMessageDialog(null, ob);
// getPassword() 會傳回 char[] 所以需要被 String() 來轉換
String uid = uname.getText();
String pwd = new String(pword.getPassword());
// Register RmiJdbc Driver in jdbc DriverManager
// On some platforms with some java VMs, newInstance() is necessary...
Class.forName("org.objectweb.rmijdbc.Driver").newInstance();
// Database URL. 請使用 db 的 url,例如,如果是 jdbc-odbc,
// 那麼 url 只是 "jdbc:odbc:samples"
String url = "jdbc:microsoft:sqlserver://db_host_ip:1433";
// Database Host. IP number or Internet name, and port number.
// RmiJdbc server installs it own in port 1099. You can change this.
String rmiHost = new String("//rmi_server_host:1099");
// RmiJdbc URL is of the form:
// jdbc:rmi:///
Connection c = DriverManager.getConnection("jdbc:rmi:"
+ rmiHost + "/" + url, uid, pwd);
Statement st = c.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM bookstores");
ResultSetMetaData md = rs.getMetaData();
while(rs.next()) {
System.out.print("\n | ");
for(int i=1; i<= md.getColumnCount(); i++) {
System.out.print(rs.getString(i) + " | ");
}
}
System.out.println("");
rs.close();
c.close();
} catch(Exception e) {
e.printStackTrace();
}
System.exit(1);
}
}
<applet code="TestApplet.class" archive="RmiJdbc.jar" width="450" height="250"> </applet>
import java.sql.*;
import java.awt.*;
import javax.swing.*;
public class TestApplet extends JApplet {
Connection con;
Statement sentence;
ResultSet rs;
String field1;
String field2;
JTextArea status;
JLabel comment;
public void init() {
comment = new JLabel("Database Results:");
status = new JTextArea("Launching program...\n", 10, 35);
Container c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.CENTER));
c.add(comment);
c.add(new JScrollPane(status));
JLabel name=new JLabel("User Name");
JTextField uname=new JTextField();
JLabel passwd=new JLabel("Password");
JPasswordField pword=new JPasswordField();
Object[] ob={name,uname,passwd,pword};
JOptionPane.showMessageDialog(null, ob);
String uid = uname.getText();
String pwd = new String(pword.getPassword());
status.append("Connecting Database.\n");
try {
Class.forName("org.objectweb.rmijdbc.Driver").newInstance();
} catch (Exception e) {
status.append("Error: " + e);
return;
}
try {
String url = "jdbc:microsoft:sqlserver://db_host:1433";
// Database Host. IP number or Internet name, and port number.
// RmiJdbc server installs it own in port 1099. You can change this.
String rmiHost = new String("//rmi_host:1099");
// Connection..
con = DriverManager.getConnection("jdbc:rmi:" + rmiHost +
"/" + url, uid, pwd);
sentence = con.createStatement();
try {
rs = sentence.executeQuery("SELECT * FROM books");
java.sql.ResultSetMetaData md = rs.getMetaData();
while(rs.next()) {
status.append("\n | ");
for(int i=1; i<= md.getColumnCount(); i++) {
status.append(rs.getString(i) + " | ");
}
}
status.append("\n");
} catch (SQLException e) {};
} catch (Exception e) {
status.append("Error: " + e);
return;
}
} // init
}
//
// Create Interface
//
public interface QueryIF extends java.rmi.Remote {
public java.sql.ResultSet getSalary(int salary)
throws java.rmi.RemoteException;
}
//
// Step 2. Create Interface Implementation
//
import java.rmi.*;
import java.rmi.server.*;
import java.sql.*;
import java.util.*;
import java.io.*;
public class QueryImpl extends UnicastRemoteObject implements QueryIF
{
private String serviceName;
private static Connection conn = null;
private ResultSet rs = null;
public QueryImpl(String s) throws RemoteException {
super();
serviceName = s;
}
public java.sql.ResultSet getSalary(int salary) throws RemoteException {
String qs = "select * from bookstores " +
"where rank >= " +
String.valueOf(salary);
try {
Statement st = conn.createStatement();
rs = st.executeQuery(qs);
} catch (SQLException sqle) {
System.out.println("QueryImpl SQLException " + sqle.getMessage());
System.exit(0);
} catch (Exception e) {
System.out.println("getQuery: QueryImpl Err: " + e.getMessage());
System.exit(1);
}
return rs;
}
public static void main( String argv[] )
{
System.setSecurityManager(new RMISecurityManager());
// 把 connection 移到這哩,可以降低 connection 的數目
try {
Class.forName("org.objectweb.rmijdbc.Driver").newInstance();
// 請將下列的 hostname, db_host:port, UID, PWD 作適當的改變
conn = DriverManager.getConnection(
"jdbc:rmi://hostname:1099/" +
"jdbc:microsoft:sqlserver://db_host:port",
UID, PWD);
QueryImpl obj = new QueryImpl("QueryService");
// 請將下列的 hostname 作適度的改變
Naming.rebind("//hostname/QueryService", obj);
System.out.println("QueryService registered.");
} catch (IOException e) {
System.out.println("Load driver error.");
System.exit(1);
} catch (SQLException e) {
System.out.println("DB connection error.");
System.exit(2);
} catch (Exception e) {
System.out.println("main: QueryImpl Err: " + e.getMessage());
}
}
}
import java.rmi.*;
import java.sql.*;
import java.util.*;
public class QueryClient
{
public static void main( String argv[] )
{
ResultSet v = null;
try {
// 這裡的 hostname 應該改成和 QueryImpl.java 相同的 hostname
QueryIF obj = (QueryIF) Naming.lookup(
"rmi://hostname/QueryService");
v = obj.getSalary(10);
StringBuffer sb = new StringBuffer();
while(v.next())
{
for(int i=1; i<4; i++)
sb.append(v.getString(i) + "\t| ");
sb.append("\n");
}
System.out.println("" + sb);
} catch (Exception e) {
System.out.println("QueryService exception: " +
e.getMessage());
}
}
}