利用RMI实现远程方法调用获取数据库的内容

来源:互联网 发布:mac版flash cs5 编辑:程序博客网 时间:2024/05/29 06:29

最近在研究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的远程调用。

原创粉丝点击