最近使用了下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>