最近使用了下RMI,简单记录下
直接上代码:
两个web项目调用,客户端需要把服务端要调用的接口在本地定义。
服务端:
接口定义:LoginInfoService
public String say(String name);
public String loginRmi(String loginname, String password, String appId, boolean isManager);
接口实现:LoginInfoServiceImpl
@Override
public String say(String name){
System.out.println("你好,我的名字:"+name+"...............");
return "你好,我的名字::"+name+"...............";
}
@Override
public String loginRmi(String loginname, String password, String appId,
boolean isManager) {
ServiceResult<LoginInfo> result = new ServiceResult<LoginInfo>();
//省略一片逻辑实现
return JSONObject.toJSONString(result);
}
服务端配置文件:rmiConfig.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/context
http://www.springframework.org/schema/context/spring-context-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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="loginInfoService" class="info.hequ.authorizationService.serviceImpl.LoginInfoServiceImpl" scope="prototype">
</bean>
<!-- 将类暴露成为一个RMI服务 -->
<bean id="springRmiTest" class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- 服务类 -->
<property name="service" ref="loginInfoService" />
<!-- 服务名 -->
<property name="serviceName" value="memberLoginService" />
<!-- 服务接口 -->
<property name="serviceInterface" value="info.hequ.authorizationService.service.LoginInfoService" />
<!-- 服务端口 -->
<property name="registryPort" value="1099" />
<!-- 其他属性自己查看org.springframework.remoting.rmi.RmiServiceExporter的类,就知道支持的属性了-->
</bean>
</beans>
springMVC配置文件中引入rmiConfig.xml配置文件
//前后省略
<beans:import resource="rmiConfig.xml" />
-------------------------------逗比分割线-------------------------------------------
客户端:
客户端接口:
public interface RmiService {
public String loginRmi(String loginname, String password, String appId, boolean isManager);
public String say(String name);
}
客户端配置:
<!-- ****************rmi******************** -->
<!--客户端-->
<beans:bean id="rmiService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<!--此处的memberLoginService和服务端的serviceName对应-->
<beans:property name="serviceUrl" value="rmi://192.168.0.115:1099/memberLoginService"/>
<beans:property name="serviceInterface" value="info.hequ.conference.service.RmiService"/>
</beans:bean>
客户端测试:
RmiCtl
@Autowired
private RmiService rmiService;
@RequestMapping(value="/rmiTest")
public void test(){
String loginname = "18701878888";
String password = "1234561";
System.out.println("rmi:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
String resultObj = rmiService.loginRmi(loginname, password, "76862628", true);
System.out.println(resultObj+"...obj");
ServiceResult<LoginInfo> result = JSONObject.parseObject(resultObj, ServiceResult.class);
System.out.println(result.getCode());
System.out.println("rmi:...."+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
}
接下来就测试咯,
和http比起来还是快了一些的
-----------------------------------------------------
和redis整合出现了反序列化问题(spring-data-redis ):
spring-data-redis 对 key 和 value 都进行了序列化 变成byte[] 再调用对应的redis java client进行存储的。 那应该就是通过spring-data-redis进入redis的key变了
spring-data-redis 中的核心操作类是 RedisTemplate<K, V>
可以看出 key 和 value 都是泛型的,这就涉及到将类型进行序列化的问题了
所就在 RedisTemplate 中还有几个 RedisSerializer
private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
private RedisSerializer keySerializer = null;
private RedisSerializer valueSerializer = null;
private RedisSerializer hashKeySerializer = null;
private RedisSerializer hashValueSerializer = null;
private RedisSerializer<String> stringSerializer = new StringRedisSerializer();
如果没有特殊的设置,key 和 value 都是使用 defaultSerializer = new JdkSerializationRedisSerializer(); 进行序列化的。
对于 key = "AAAA" value = "cccc" 的情况, server 端运行的情况如下
"SET" "\xac\xed\x00\x05t\x00\x04AAAA" "\xac\xed\x00\x05t\x00\x04cccc"
"GET" "\xac\xed\x00\x05t\x00\x04AAAA"
如果项目中只使用了string的 key 和 value ,显然这样不适合在sever上进行debug
通过下面的配置,可以改成使用StringRedisSerializer对 key 和 value 进行序列化
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory" >
<property name="KeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
<property name="ValueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
</bean>
这样就能在 server 上找到你原来的 key 了
对于Hash结构内部的 key 和 value 可以添加如下配置
<property name="HashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
<property name="HashValueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
最后附上redis配置文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300" />
<property name="maxActive" value="600" />
<property name="maxWait" value="1000" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="192.168.0.115" p:port="6379" p:password=""
p:pool-config-ref="poolConfig"
/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<!-- 如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast to String!!!-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<!-- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> -->
</property>
</bean>
</beans>