1. 程式人生 > >利用RMI實現遠端方法呼叫獲取資料庫的內容

利用RMI實現遠端方法呼叫獲取資料庫的內容

最近在研究Java RMI框架的遠端方法呼叫。利用spring對RMI的支援可以非常方便的構建你的分散式應用。
對於spring+RMI的介紹網上有很多,在這裡自己動手寫了一個Spring+mybatis+RMI的簡單應用。實現遠端方法呼叫資料庫。

首先建立一個數據庫,資料庫中只有一張表,非常的簡單。
資料庫

服務端的搭建 ##

搭建好資料庫後就開始編寫程式碼了。首先建立一個Java專案或者Java web專案作為伺服器端。這是伺服器專案的結構:

專案結構

引入專案需要用到的jar包:

專案jar包

對於建立Spring框架和spring整合mybatis比較簡單,在這裡不做過多的敘述,直接上程式碼。

User.java

package org.springmybatis.model;

import java.io.Serializable;

public class User implements Serializable{
    private int id;
    private String username;
    private String password;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public
String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public
User() { super(); } public String toString(){ return "User[id="+id+" , username="+username+" , password="+password+"]"; } }

在這裡需要注意的是此處的entity類實現了Serializable介面,這是因為在RMI分散式應用系統中,伺服器與客戶機之間傳遞的Java物件必須是可序列化的物件。不可序列化的物件不能在物件流中進行傳遞。也就是說如果想要從遠端操作mybatis那麼此處的entity必須序列化。

UserDao.java

package org.springmybatis.dao;

import org.springmybatis.model.User;

public interface UserDao {
    public User getUser(User user);
    public void addUser(User user);
    public void updateUser(User user);
    public void deleteUser(int UserId);
}

UserDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
<mapper namespace="org.springmybatis.dao.UserDao">  
<select id="getUser" parameterType="org.springmybatis.model.User" resultType="org.springmybatis.model.User">  
     SELECT * FROM user WHERE username=#{username} AND password=#{password}  
</select>  
<insert id="addUser" parameterType="org.springmybatis.model.User" flushCache="true">  
    INSERT INTO user (id,username,password) VALUES (#{id},#{username},#{password})  
</insert>  
<update id="updateUser" parameterType="org.springmybatis.model.User">  
    UPDATE user SET password=#{password} WHERE id=#{id}  
</update>  
<delete id="deleteUser" parameterType="int">  
    DELETE FROM user WHERE id=#{id}  
</delete>  
</mapper> 

這裡的UserDao.xml就是mapper對映檔案

mybatis配置檔案也很簡單:
mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC  
     "-//mybatis.org//DTD Config 3.0//EN"  
     "http://mybatis.org/dtd/mybatis-3-config.dtd">  
 <configuration>  
     <mappers>  
         <mapper resource="org/springmybatis/dao/UserDao.xml"/>  
     </mappers>  
 </configuration> 

這是最基礎的spring配置檔案,後續需要在此整合RMI框架:
ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
    <property name="driverClassName">  
         <value>org.gjt.mm.mysql.Driver</value>  
    </property>  
    <property name="url">  
        <value>jdbc:mysql://localhost:3306/springmybatisrmi?useUnicode=true&amp;characterEncoding=UTF-8</value>  
    <!--springmybaitis是我的資料庫  -->
    </property>  
    <property name="username">  
        <value>root</value>  
    </property>  
    <property name="password">  
        <value>admin</value>  
    </property>  
</bean>

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
     <property name="dataSource" ref="jdbcDataSource" />  
     <property name="configLocation" value="classpath:mybatis-config.xml"></property>  
</bean>

<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">  
     <property name="mapperInterface" value="org.springmybatis.dao.UserDao"></property>  
     <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>  
</bean>
</beans>  

至此整個spring+mybatis框架就搭建好了,然後我們編寫一個測試類,用來檢測框架是否搭建成功。

UserController.java

package org.springmybatis.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springmybatis.dao.UserDao;
import org.springmybatis.model.User;

public class UserController {
    public static void main(String[] args) {
         ApplicationContext ctx=null;
         ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
         UserDao userDao=(UserDao) ctx.getBean("userDao");
         User user=new User();
         //新增兩條資料
         user.setId(1);
         user.setUsername("ltx");
         user.setPassword("123");
         userDao.addUser(user);
         user.setId(2);
         user.setUsername("ltxltx");
         user.setPassword("123");
         userDao.addUser(user);
         System.out.println("新增成功");
         //查詢資料
         user.setUsername("ltxltx");
         user.setPassword("123");
         System.out.println(userDao.getUser(user).toString());
         user.setUsername("ltx");
         user.setPassword("123");
         System.out.println(userDao.getUser(user).toString());
         //修改資料
         user.setId(2);
         user.setPassword("95");
         userDao.updateUser(user);
         System.out.println("修改成功");
        //刪除資料
         userDao.deleteUser(1);
         userDao.deleteUser(2);
         System.out.println("刪除成功");       
    }
}

執行一下程式,如果控制檯輸出了
這裡寫圖片描述
表明執行成功。

接下來就要往服務端新增RMI框架了。
首先我們需要做的是將服務端的介面包裝,並建立此介面的實現類。這一步的目的是隱藏服務端的mybatis,提供新的介面給客戶端呼叫,讓客戶端就像在本地使用spring+mybatis訪問資料庫一樣。

RUserDao.java

package org.springmybatis.dao;

import org.springmybatis.model.User;

public interface RUserDao {
    public User getUser(User user);
    public void addUser(User user);
    public void updateUser(User user);
    public void deleteUser(int userId);
}

RUserDaoImpl.java

package org.springmybatis.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springmybatis.model.User;

public class RUserDaoImpl implements RUserDao {
    @Autowired
    private UserDao userDao;

    @Override
    public User getUser(User user) {
        // TODO Auto-generated method stub
        return userDao.getUser(user);
    }
    @Override
    public void addUser(User user) {
        // TODO Auto-generated method stub
         this.userDao.addUser(user);
    }

    @Override
    public void updateUser(User user) {
        // TODO Auto-generated method stub
         this.userDao.updateUser(user);
    }
    @Override
    public void deleteUser(int userId) {
        // TODO Auto-generated method stub
        this.userDao.deleteUser(userId);
    }
}

在這裡需要注意的是,我使用了@Autowried註解來實現spring中Bean的建立和自動裝配。我們需要在spring配置檔案中新增一行程式碼:

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

接下來我們需要在spring配置檔案中新增RMI支援,在ApplicationContext.xml檔案中新增以下內容:

<bean id="RuserDaoImpl" class="org.springmybatis.dao.RUserDaoImpl" scope="prototype" />
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
    <!-- 將遠端介面實現類物件設定到RMI服務中 -->
    <property name="service" ref="RuserDaoImpl" />
    <!-- 設定RMI服務名,為RMI客戶端依據此服務名獲取遠端介面實現類物件引用奠定基礎 -->
    <property name="serviceName" value="ruserdao" />
    <!-- 將遠端介面設定為RMI服務介面 -->
    <property name="serviceInterface" value="org.springmybatis.dao.RUserDao" />
    <!-- 為RMI服務端遠端物件登錄檔設定埠號-->
    <property name="registryPort" value="9090" />
</bean>

至此就完成了RMI服務端的搭建。

客戶端的搭建 ##

首先在搭建客戶端之前,先說一說我遇到的一個問題。當我搭建完成客戶端之後,執行程式碼發現報了這麼一個異常no security manager: RMI class loader disabled

在網上搜了一下之後發現這個異常的原因是客戶端的包路徑與服務端的包路徑不一致,改成一致就ok了。

首先建立一個Java或者Javaweb專案,同時引用服務端的專案。或者你也可以選擇將服務端的User.java和RUserDao.java拷貝到客戶端來。當然了,你要注意客戶端的包路徑必須與服務端的包路徑一致。

下面是我客戶端的專案結構:
這裡寫圖片描述

首先是客戶端的spring配置檔案:

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <!--RMI客戶端-->
    <bean id="dataExchangeProxyService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> 
        <property name="serviceUrl" value="rmi://localhost:9090/ruserdao"/>
        <property name="serviceInterface" value="org.springmybatis.dao.RUserDao"/>
        <!-- 當連線失敗時是否重新整理遠端呼叫stub -->
        <property name="refreshStubOnConnectFailure" value="true"/>
    </bean>
</beans>

啟動檔案RMIClient.java:

package org.springmybatis.test;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springmybatis.dao.RUserDao;
import org.springmybatis.model.User;

public class RMIClient {

    public static void main(String[] args){

        ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/spring/applicationContext.xml");
        RUserDao userdao =  (RUserDao) ctx.getBean("dataExchangeProxyService");
         User user=new User();
         //新增兩條資料
         user.setId(1);
         user.setUsername("ltx");
         user.setPassword("123");
         //userdao.addUser(user);
         user.setId(3);
         user.setUsername("ltxltx");
         user.setPassword("123");
         userdao.addUser(user);
         System.out.println("新增成功");
         userdao.deleteUser(1);
         //userdao.deleteUser(2);
    }
}

至此整個專案就完成了。
在這裡我們呼叫服務端暴露出來的介面RUserDao來訪問服務端的資料庫,實現了RMI的遠端呼叫。

相關推薦

利用RMI實現遠端方法呼叫獲取資料庫內容

最近在研究Java RMI框架的遠端方法呼叫。利用spring對RMI的支援可以非常方便的構建你的分散式應用。 對於spring+RMI的介紹網上有很多,在這裡自己動手寫了一個Spring+mybatis+RMI的簡單應用。實現遠端方法呼叫資料庫。 首先建立

使用RMI實現遠端方法呼叫

題目如下: 開發一個稱為“城市資訊”伺服器的應用程式,這個城市資訊伺服器的客戶程式通過提供一個城市名,獲得這個城市的相關資訊。在此應用程式中,伺服器程式只提供兩個方法:一個獲取人口;另一個獲取溫度。 而且必須用RMI去實現。 (1)定義一個遠端介面MyRmi 檔名:My

rabbitmq學習(四):利用rabbitmq實現遠端rpc呼叫

一、rabbitmq實現rpc呼叫的原理 ·rabbitmq實現rpc的原理是:客戶端向一個佇列中傳送訊息,並註冊一個回撥的佇列用於接收服務端返回的訊息,該訊息需要宣告一個叫做correaltionId的屬性,該屬性將是該次請求的唯一標識。服務端在接受到訊息(在需要時可以驗證correaltionId)後,

RMI進行遠端方法呼叫(2006-10-26 09:48:08)

用RMI進行遠端方法呼叫 (2006-10-26 09:48:08)        遠端方法呼叫(RMI)機制可以把面向物件的思想進一步擴充套件,因為你可以呼叫的物件不僅可以在本機上,也可以在別的主

android開發中通過aidl實現遠端方法呼叫

在安卓開發過程中我們可能見過這樣的問題,就是在一個應用中呼叫另一個應用中的服務,並呼叫該服務中的方法。 我們可能對呼叫服務並不陌生,可是要執行服務中的方法,卻不能直接呼叫。因為兩個服務和呼叫它的程式屬

簡單實現Java的RMI——遠端方法呼叫

一、RMI簡介: 說到RMI就不得不說RPC了。 RPC:(Remote Procedure Call),遠端過程呼叫。 RMI(Remote Method Invocation),遠端方法呼叫。 RPC和RMI是有區別的,RPC中是通過網路服務協議向遠端主機發送請求,RPC遠端主機就去搜索與之相匹配

java反射機制(2)- 實踐:反射機制+動態代理實現模擬RMI遠端方法呼叫

1 涉及主要知識點   1、RMI(Remote Method Invocation):遠端方法呼叫是一種計算機之間利用遠端物件互相呼叫實現雙方通訊的一種通訊機制。使用這種機制,某一臺計算機上

RMI 遠端方法呼叫

1、服務端定義服務介面,該介面必須繼承於Remote介面,然後定義介面方法,介面方法必須丟擲RemoteException異常: public interface IntHelloRmi extends Remote { public String helloRmi() throws Re

rmi遠端方法呼叫

Java RMI 是遠端方法呼叫機制(Remote Method Invocation)。它能夠在某個java虛擬機器上呼叫另一個java虛擬機器中物件的方法。用此方法呼叫的遠端物件必須實現遠端介面。 現在大名鼎鼎的ejb和web service都是基於RMI

利用sp_addlinkedserver實現遠端資料庫連結

--檢視當前連結情況: select * from sys.servers; --使用 sp_helpserver 來顯示可用的伺服器 Exec sp_helpserver --刪除已經存在的某個連結 Exec sp_droplinkedsrvlogin 伺服器別名

Java遠端方法呼叫,RMI入門教程

、什麼是RMI      Java遠端方法呼叫,即Java RMI(Java Remote Method Invocation)是Java程式語言裡,一種用於實現遠端過程呼叫的應用程式程式設計介面。它使客戶機上執行的程式可以呼叫遠端伺服器上的物件。遠端方法呼叫特

遠端方法呼叫RMI初步

在各層面的網路程式設計中,會接觸到各種協議(protocol)。網路協議(network protocol、簡稱協議)是資料格式的形式化描述和交換那些資料的規則集。大多數典型的應用都有了標準化的網路協議,如FTP、HTTP、Internet Protocol (網際網路協議、IP)等等。 在面向物件程式中,

遠端方法呼叫RMI

RMI(Remote Method Invocation)遠端方法呼叫是一種計算機之間利用遠端物件互相呼叫實現雙方通訊的一種通訊機制。使用這種機制,某一臺計算機上的物件可以呼叫另外 一臺計算機上的物

遠端方法呼叫——RMI

RMI RMI  (Remote  Method  Invocation)是Java用於實現透明遠端呼叫的重要機制。在遠端呼叫中,客戶端僅有伺服器端提供的介面 。通過此介面實現對遠端伺服器端的呼叫。其威力就體現在它強大的開發分散式網路應用的能力上,是純Java的網路分散式應

Spring RMI實現遠端呼叫

1. Spring 除了使用基於 HTTP 協議的遠端呼叫方案,還為開發者提供了基於 RMI 機制的遠端呼叫方法, RMI 遠端呼叫網路通訊實現是基於 TCP/IP 協議完成的,而不是通過 HTTP 協議。 在 Spring RMI 實現中,集成了標準的 RMI-JRIM

利用Python實現遠端控制電腦

具體功能原始碼中展現的也非常清楚,我就不一一描述了。 原始碼: import itchat import os import time import cv2 sendMsg = u"{訊息助手}:暫時無法回覆" usageMsg = u"使用方法:\n1.執行CM

利用opensips實現freeswitch負載均衡的資料庫死鎖問題

多個freeswitch實現負載均衡,要使用同一個資料庫,這樣每個freeswitch都要建立到資料庫的連線,在每個呼叫結束時,都要到資料庫中刪除一些資料,比如要到calls表刪除呼叫資訊,如果多個freeswitch同時進行刪除操作,有可能會產生死鎖,比如: 2018-0

PHP實現遠端過程呼叫RPC

一、初識RPC RPC(Remote Procedure Call)—遠端過程呼叫,它是一種通過網路從遠端計算機程式上請求服務,而不需要了解底層網路技術的協議。 二、工作原理 執行時,一次客戶機對伺服器的RPC呼叫,其內部操作大致有如下十步: 1.呼叫客戶端控制代碼;執行傳送引數

Java遠端方法呼叫

一、入門篇 Java RMI指的是遠端方法呼叫(Remote Method Invocation). 它是一種機制, 能夠讓不同作業系統之間程式實現方法呼叫.  比如: 一臺電腦上的Java程式

完整JavaWeb專案筆記 第五部分-通過方法控制代碼實現動態方法呼叫

文章目錄 一 方法控制代碼 二 如何使用方法控制代碼 三 核心Servlet的大致框架構建 一 方法控制代碼   方法控制代碼是Java7的JSR 292版本中新增的功能,我簡單介紹下。方法控制代碼和反射是較為類似