Java Rmi的練習

最近做了個Java Rmi的小例子,把代碼貼出來,和大家交流交流。也是網上搜羅。一些達人朋友的技術成果。呵呵!!!

Java Rmi指的是遠程方法調用 (Remote Method Invocation)。做Java分佈式開發用的!!!

什麼是分佈式開發,舉個小例子哇:小Z是四川人,戶籍肯定是在四川的戶籍數據庫裏,前陣子在山西報名學駕校,山西這邊的系統要查詢小Z的戶籍信息,應該就是通過遠程調用四川系統的接口,返回小Z的信息。四川、山西兩套獨立管理戶籍的系統,通過計算機網絡連在一起,看似一個整體一樣。這就是分佈式系統的妙用。(這也許是胡編,把大概的意思說明白就行了,也許政府的系統更高級呢?呵呵)

上個小例子吧:Server端和Client端兩個獨立的工程:(發現JDK1.5+,搭建RMI程序很是方便,很多方法大家可以查看JDK的API幫助文檔)

Server端:需要開通接口方法,以便Client端調用。

RMI接口方法調用,首先就是定義一個接口吧:

/**
 * JAVA RMI Server端,開放給客戶端的方法
 */
package com.zyujie.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;

import com.zyujie.pojo.UserInfo;

public interface UserInfoInterface extends Remote{

	/*
	 * 獲取用戶名稱
	 */
	public String getUserName() throws RemoteException;
	
	/*
	 * 獲取用戶密碼
	 */
	public String getUserPassword() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個JavaBean
	 */
	public UserInfo getUserInfo() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個map
	 */
	public Map<String,String> getUserInfoMap() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個List套javabean
	 */
	public List<UserInfo> getUserInfoListBean() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個List套map的方式
	 */
	public List<Map<String,String>> getCityInfoListMap() throws RemoteException;
}

有了接口,Server端,得有一個接口的實現類,好做一些DAO數據查詢啊,什麼的。

/**
 * RMI開放接口的實現類
 */
package com.zyujie.rmi;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.zyujie.pojo.UserInfo;

public class UserInfoImpl implements UserInfoInterface {

	public UserInfo getUserInfo() throws RemoteException {
		UserInfo userInfo = new UserInfo();
		userInfo.setUser_id("admin");
		userInfo.setUser_name("系統管理員");
		userInfo.setUser_password("888888");
		userInfo.setUser_email("[email protected]");
		userInfo.setUser_dept("信息化建議中心");
		return userInfo;
	}

	public String getUserName() throws RemoteException {
		return "系統管理員";
	}

	public String getUserPassword() throws RemoteException {
		return "888888";
	}

	/*
	 * 獲取用戶基本信息,此方法返回值是一個map
	 */
	public Map<String,String> getUserInfoMap() throws RemoteException{
		Map<String,String> map = new HashMap<String, String>();
		map.put("UserId", "admin");
		map.put("UserPassword", "888888");
		return map;
	}
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個List套javabean
	 */
	public List<UserInfo> getUserInfoListBean() throws RemoteException{
		List<UserInfo> list = new ArrayList<UserInfo>();
		UserInfo userOne = new UserInfo();
		userOne.setUser_id("userOne");
		userOne.setUser_name("用戶111");
		userOne.setUser_password("111111");
		userOne.setUser_email("[email protected]");
		userOne.setUser_dept("行政部");
		list.add(userOne);
		
		UserInfo userTwo = new UserInfo();
		userTwo.setUser_id("userTwo");
		userTwo.setUser_name("用戶222");
		userTwo.setUser_password("222222");
		userTwo.setUser_email("[email protected]");
		userTwo.setUser_dept("人力資源部");
		list.add(userTwo);
		
		UserInfo userThree = new UserInfo();
		userThree.setUser_id("userThree");
		userThree.setUser_name("用戶333");
		userThree.setUser_password("333333");
		userThree.setUser_email("[email protected]");
		userThree.setUser_dept("銷售部");
		list.add(userThree);
		return list;
	}
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個List套map的方式
	 */
	public List<Map<String,String>> getCityInfoListMap() throws RemoteException{
		List<Map<String,String>> list = new ArrayList<Map<String,String>>();
		Map<String,String> mapSY = new HashMap<String, String>();
		mapSY.put("cityName", "瀋陽");
		mapSY.put("cityArea", "東北");
		list.add(mapSY);
		Map<String,String> mapBJ = new HashMap<String, String>();
		mapBJ.put("cityName", "北京");
		mapBJ.put("cityArea", "華北");
		list.add(mapBJ);
		Map<String,String> mapSH = new HashMap<String, String>();
		mapSH.put("cityName", "上海");
		mapSH.put("cityArea", "華東");
		list.add(mapSH);
		Map<String,String> mapGZ = new HashMap<String, String>();
		mapGZ.put("cityName", "廣州");
		mapGZ.put("cityArea", "華南");
		list.add(mapGZ);
		Map<String,String> mapXA = new HashMap<String, String>();
		mapXA.put("cityName", "西安");
		mapXA.put("cityArea", "西北");
		list.add(mapXA);
		Map<String,String> mapCD = new HashMap<String, String>();
		mapCD.put("cityName", "成都");
		mapCD.put("cityArea", "西南");
		list.add(mapCD);
		return list;
	}
}

由於涉及到JavaBean的網絡傳輸,所以這裏做了一個JavaBean,再序列化。

package com.zyujie.pojo;

/**
 * 爲了在RMI中傳遞Java Object,我們把userinfo作爲一個javabean,並序列化。
 */
import java.io.Serializable;

public class UserInfo implements Serializable{

	private static final long serialVersionUID = 1L;

	private String user_id;
	
	private String user_name;
	
	private String user_password;
	
	private String user_email;
	
	private String user_dept;

	public String getUser_id() {
		return user_id;
	}

	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}

	public String getUser_name() {
		return user_name;
	}

	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}

	public String getUser_password() {
		return user_password;
	}

	public void setUser_password(String user_password) {
		this.user_password = user_password;
	}

	public String getUser_email() {
		return user_email;
	}

	public void setUser_email(String user_email) {
		this.user_email = user_email;
	}

	public String getUser_dept() {
		return user_dept;
	}

	public void setUser_dept(String user_dept) {
		this.user_dept = user_dept;
	}
}

下面是在Server端註冊接口方法,和開放端口了哇

/**
 * 程序的入口類,主要是註冊你已經實現的RMI接口,並開放端口給客戶端
 */
package com.zyujie.rmi;

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

public class AppEntry {

	public static void main(String[] args) throws AlreadyBoundException, RemoteException {
		UserInfoImpl userInfoImpl = new UserInfoImpl();
		//使用提供的特定端口導出遠程對象,以便能夠接收傳入的調用。 
		UserInfoInterface userInfoInterface = (UserInfoInterface)UnicastRemoteObject.exportObject(userInfoImpl,0);
		//創建並導出接受指定 port 請求的本地主機上的 Registry 實例
		Registry registry = LocateRegistry.createRegistry(8080); 
		//綁定對此註冊表中指定 name 的遠程引用。 
		registry.rebind("UserInfo", userInfoInterface); 
		System.out.println("服務器已經準備就緒,可隨時調用。"); 
	}
}

Server端就編寫完成,下面是Client端,通常Server端會把接口類,實體類,打成jar包,發給客戶端。但我這裏就直接在客戶端再寫一次接口和JavaBean

接口同服務端接口一樣:

package com.zyujie.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;

import com.zyujie.pojo.UserInfo;

public interface UserInfoInterface extends Remote{

	/*
	 * 獲取用戶名稱
	 */
	public String getUserName() throws RemoteException;
	
	/*
	 * 獲取用戶密碼
	 */
	public String getUserPassword() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個JavaBean
	 */
	public UserInfo getUserInfo() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個map
	 */
	public Map<String,String> getUserInfoMap() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個List套javabean
	 */
	public List<UserInfo> getUserInfoListBean() throws RemoteException;
	
	/*
	 * 獲取用戶基本信息,此方法返回值是一個List套map的方式
	 */
	public List<Map<String,String>> getCityInfoListMap() throws RemoteException;
}

實體類和服務端實體類一樣:

package com.zyujie.pojo;

/**
 * 爲了在RMI中傳遞Java Object,我們把userinfo作爲一個javabean,並序列化。
 */
import java.io.Serializable;

public class UserInfo implements Serializable{

	private static final long serialVersionUID = 1L;

	private String user_id;
	
	private String user_name;
	
	private String user_password;
	
	private String user_email;
	
	private String user_dept;

	public String getUser_id() {
		return user_id;
	}

	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}

	public String getUser_name() {
		return user_name;
	}

	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}

	public String getUser_password() {
		return user_password;
	}

	public void setUser_password(String user_password) {
		this.user_password = user_password;
	}

	public String getUser_email() {
		return user_email;
	}

	public void setUser_email(String user_email) {
		this.user_email = user_email;
	}

	public String getUser_dept() {
		return user_dept;
	}

	public void setUser_dept(String user_dept) {
		this.user_dept = user_dept;
	}
}

爲了不出錯,包名和路徑名都完全一樣。當然用jar是最好的。

下面是Client調用類了。配上IP地址,端口號,和遠程方法引用名。就可以了。

/**
 * 客戶端調用RMI遠程接口。
 */
package com.zyujie.rmi;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.List;
import java.util.Map;

import com.zyujie.pojo.UserInfo;

public class AppTest {

	public static void main(String[] args) {
		try {
			//返回指定的 host 和 port 上對遠程對象 Registry 的引用。如果 host 爲 null,則使用本地主機。 
			Registry registry = LocateRegistry.getRegistry("127.0.0.1", 8080);
			//返回註冊表中綁定到指定 name 的遠程引用
			UserInfoInterface userInfoInterface = (UserInfoInterface) registry.lookup("UserInfo");
			
			System.out.println("/*****************RMI String 返回********************/");
			System.out.println("用戶名稱:" + userInfoInterface.getUserName());
			System.out.println("用戶密碼:" + userInfoInterface.getUserPassword());
			
			System.out.println("/*****************RMI JavaBean 返回********************/");
			UserInfo userInfo = userInfoInterface.getUserInfo();
			System.out.println("用戶部門:" + userInfo.getUser_dept());
			System.out.println("用戶郵箱號:" + userInfo.getUser_email());
			
			System.out.println("/*****************RMI Map 返回********************/");
			Map<String,String> map = userInfoInterface.getUserInfoMap();
			System.out.println("Map用戶編號:" + map.get("UserId"));
			System.out.println("Map用戶密碼:" + map.get("UserPassword"));
			
			System.out.println("/*****************RMI List<Object> List套JavaBean 返回********************/");
			List<UserInfo> userList = userInfoInterface.getUserInfoListBean();
			for (int i = 0; i < userList.size(); i++) {
				UserInfo users = (UserInfo)userList.get(i);
				System.out.println("用戶名稱:" + users.getUser_name() + "--部門:" + users.getUser_dept() + "--郵箱:" + users.getUser_email());
			}
			
			System.out.println("/*****************RMI List套Map 返回********************/");
			List<Map<String,String>> cityList = userInfoInterface.getCityInfoListMap();
			for (int i = 0; i < cityList.size(); i++) {
				Map<String,String> mapCity = (Map<String,String>)cityList.get(i);
				System.out.println("城市名稱:" + mapCity.get("cityName") + "----區域:" + mapCity.get("cityArea"));
			}
			
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Client端也編寫完成,運行Server端工程裏的AppEntry,控制檯打印:服務器已經準備就緒,可隨時調用。

再運行Client端工程裏的AppTest,控制檯打印結果:

/*****************RMI String 返回********************/
用戶名稱:系統管理員
用戶密碼:888888
/*****************RMI JavaBean 返回********************/
用戶部門:信息化建議中心
用戶郵箱號:[email protected]
/*****************RMI Map 返回********************/
Map用戶編號:admin
Map用戶密碼:888888
/*****************RMI List<Object> List套JavaBean 返回********************/
用戶名稱:用戶111--部門:行政部--郵箱:[email protected]
用戶名稱:用戶222--部門:人力資源部--郵箱:[email protected]
用戶名稱:用戶333--部門:銷售部--郵箱:[email protected]
/*****************RMI List套Map 返回********************/
城市名稱:瀋陽----區域:東北
城市名稱:北京----區域:華北
城市名稱:上海----區域:華東
城市名稱:廣州----區域:華南
城市名稱:西安----區域:西北
城市名稱:成都----區域:西南

JAVA RMI的小例子就成功實現了。小例子中返回了幾種開發中很常用的結構類型。

發佈了40 篇原創文章 · 獲贊 26 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章