最近使用了下RMI,简单记录下java
直接上代码:web
两个web项目调用,客户端须要把服务端要调用的接口在本地定义。redis
服务端:
spring
接口定义:LoginInfoServiceapp
public String say(String name); public String loginRmi(String loginname, String password, String appId, boolean isManager);
接口实现:LoginInfoServiceImplide
@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配置文件spa
//先后省略 <beans:import resource="rmiConfig.xml" />
-------------------------------逗比分割线-------------------------------------------prototype
客户端:debug
客户端接口:
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>