• Redis的发布订阅在SpringMVC(或xml配置)项目中使用(注意版本兼容问题)


    在Spring中使用 Redis ,除了需要 jedis.jar 外,还需要下载 spring-data-redis.jar,打开网址 https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis , 

    注意 spring5以上需要配置 spring-data-redis 2.0

    基于spring主版本为4.3.13.RELEASE的项目,测试以下对应版本可用。

    spring-data-redis版本

    jedis版本

    备注

    1.5.2.RELEASE

    2.7.3

    1.6.0.RELEASE

    2.7.2  2.7.3

    1.6.2.RELEASE

    2.8.0

    1.8.1.RELEASE

    2.9.0

    1.8.4.RELEASE

    2.9.0

    项目中使用的版本:

    spring-data-redis-1.6.6.RELEASE.jar   jedis-2.9.0.jar

    项目结构

     

    1、客户端(订阅):

    redis.properties

    1. #redis pool config
    2. redis.pool.maxActive=1000
    3. redis.pool.maxIdle=100
    4. redis.pool.maxWaitMillis=10000
    5. redis.pool.testOnBorrow=true
    6. #redis config
    7. redis.host=192.168.0.198
    8. redis.port=6379
    9. redis.timeout=6000
    10. redis.password=123456
    11. redis.dbindex=8
    12. redis.usePool=1
    13. redis.default.expire=1800000
    14. redis.topicName=message

     applicationContext-redis.xml

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    4. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    5. xmlns:context="http://www.springframework.org/schema/context"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    7. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    10. <description>Redis configurationdescription>
    11. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    12. <property name="maxIdle" value="${redis.pool.maxIdle}">property>
    13. <property name="maxTotal" value="${redis.pool.maxActive}" />
    14. <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
    15. <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
    16. bean>
    17. <bean id="jedisConnectionFactory"
    18. class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    19. destroy-method="destroy">
    20. <property name="poolConfig" ref="jedisPoolConfig">property>
    21. <property name="hostName" value="${redis.host}">property>
    22. <property name="port" value="${redis.port}">property>
    23. <property name="password" value="${redis.password}">property>
    24. <property name="timeout" value="${redis.timeout}">property>
    25. bean>
    26. <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    27. <bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
    28. <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    29. <property name="connectionFactory" ref="jedisConnectionFactory" />
    30. <property name="keySerializer" ref="stringRedisSerializer" />
    31. <property name="valueSerializer" ref="stringRedisSerializer" />
    32. bean>
    33. <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    34. <property name="connectionFactory" ref="jedisConnectionFactory" />
    35. <property name="keySerializer">
    36. <bean
    37. class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    38. property>
    39. <property name="valueSerializer">
    40. <bean
    41. class="org.springframework.data.redis.serializer.StringRedisSerializer">
    42. bean>
    43. property>
    44. bean>
    45. <bean id="redisMessageListener" class="com.gy.xf.listener.RedisMessageListener">
    46. <property name="stringRedisTemplate" ref="redisTemplate">property>
    47. bean>
    48. <bean id="topicContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy">
    49. <property name="connectionFactory" ref="jedisConnectionFactory">property>
    50. <property name="taskExecutor">
    51. <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
    52. <property name="poolSize" value="3">property>
    53. bean>
    54. property>
    55. <property name="messageListeners">
    56. <map>
    57. <entry key-ref="redisMessageListener">
    58. <bean class="org.springframework.data.redis.listener.ChannelTopic" >
    59. <constructor-arg value="${redis.topicName}">constructor-arg>
    60. bean>
    61. entry>
    62. map>
    63. property>
    64. bean>
    65. beans>

    RedisMessageListener.java

    1. package com.gy.xf.listener;
    2. import com.alibaba.fastjson.JSON;
    3. import com.fasterxml.jackson.databind.ObjectMapper;
    4. import com.gy.xf.entity.redis.AlarmInfo;
    5. import com.gy.xf.util.RedisCacheUtils;
    6. import com.sun.org.apache.regexp.internal.RE;
    7. import org.apache.commons.lang.StringUtils;
    8. import org.apache.http.HttpEntity;
    9. import org.apache.http.HttpStatus;
    10. import org.apache.http.entity.StringEntity;
    11. import org.apache.http.util.EntityUtils;
    12. import org.slf4j.Logger;
    13. import org.slf4j.LoggerFactory;
    14. import org.springframework.beans.factory.annotation.Autowired;
    15. import org.springframework.data.redis.connection.Message;
    16. import org.springframework.data.redis.connection.MessageListener;
    17. import org.springframework.data.redis.core.StringRedisTemplate;
    18. /**
    19. * Redis 发布订阅监听类
    20. */
    21. public class RedisMessageListener implements MessageListener {
    22. private Logger logger = LoggerFactory.getLogger(RedisMessageListener.class);
    23. // @Autowired
    24. private StringRedisTemplate stringRedisTemplate;// = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");
    25. //初始化JSON解析器
    26. public ObjectMapper mapper = new ObjectMapper();
    27. @Override
    28. public void onMessage(Message message, byte[] bytes) {
    29. //获取消息
    30. byte[] body = message.getBody();
    31. //使用值序列化器转换
    32. String msgBody = (String) stringRedisTemplate.getValueSerializer().deserialize(body);
    33. //获取channel
    34. // byte[] channel = message.getChannel();
    35. // String channelName = (String) stringRedisTemplate.getValueSerializer().deserialize(channel);
    36. //渠道名称转换
    37. // String bytesStr = new String(bytes);
    38. //logger.info("Redis监听消息:直接获取渠道名称 = " + bytesStr);
    39. logger.info("警情处理(Redis缓存): 本条消息处理开始.................................");
    40. AlarmInfo model = JSON.parseObject(msgBody , AlarmInfo.class);
    41. if (null != model){
    42. //判断groupId是否在专职队单位id表中
    43. String groupIdList = RedisCacheUtils.getStr(RedisCacheUtils.KEY_ALARM_GROUPIDS);
    44. if (!StringUtils.isEmpty(groupIdList)){
    45. if(groupIdList.indexOf(model.getGroupId())!=-1){
    46. String alarmKey = RedisCacheUtils.KEY_ALARM_GROUPID_PREFIX + model.getGroupId();
    47. RedisCacheUtils.set(alarmKey , model.getUploadId() , RedisCacheUtils.KEY_ALARM_TIMEOUT);//0 或 null 标示永不不超时
    48. logger.info("警情处理(Redis缓存): 将专职队调派信息写入缓存。groupId:{} , uploadId:{} " , new Object[]{
    49. model.getGroupId() , model.getUploadId()
    50. });
    51. }else{
    52. logger.info("警情处理(Redis缓存): 非专职队调派信息,不处理!!!groupId:{} , uploadId:{} " , new Object[]{
    53. model.getGroupId() , model.getUploadId()
    54. });
    55. // if(model.getGroupId().indexOf(groupIdList)!=-1){
    56. // logger.info("警情处理(缓存): 非专职队调派信息,不处理。groupId:{} , uploadId:{} " , new Object[]{
    57. // model.getGroupId() , model.getUploadId()
    58. // });
    59. // }
    60. }
    61. }else{
    62. logger.error("警情处理(Redis缓存): 读取专职队单位id缓存数据不存在,请检查!!!");
    63. }
    64. }
    65. logger.info("警情处理(Redis缓存): 本条消息处理完毕.................................");
    66. }
    67. /**
    68. * 发送消息
    69. * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    70. * @return
    71. * @throws Exception
    72. public void sendMessage(String sysId, String postData) {
    73. try {
    74. String access_token = CacheUtils.getStr(CacheUtils.KEY_WX_ACCESS_TOKEN);
    75. if (StringUtils.isEmpty(access_token)){
    76. logger.error("Redis监听消息:发送消息,获取 access_token 失败,数据不存在, sysId = {} " , sysId);
    77. }
    78. //拼接url
    79. String url = Constants.GET_TEMPLATE_MESSAGE_PREFIX + "access_token=" + access_token;
    80. //请求返回结果
    81. WxRequestReult result = null;
    82. //请求地址
    83. //logger.info("发送模板消息给用户 , 请求url = " + url);
    84. CloseableHttpClient httpClient = HttpClients.custom().build();
    85. //创建post请求及设置参数
    86. HttpPost httpPost = new HttpPost(url);
    87. httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
    88. StringEntity stringEntity = new StringEntity(postData , Constants.UTF_8);
    89. httpPost.setEntity(stringEntity);
    90. //发送请求
    91. CloseableHttpResponse response = httpClient.execute(httpPost);
    92. //设置 post 参数
    93. final int statusCode = response.getStatusLine().getStatusCode();
    94. int code = HttpStatus.SC_OK;
    95. HttpEntity entity = response.getEntity();
    96. //处理数据
    97. if (code == statusCode && entity != null) {
    98. result = mapper.readValue(EntityUtils.toString(entity) , WxRequestReult.class);
    99. response.close();
    100. httpClient.close();
    101. }
    102. logger.info("Redis监听消息:发送消息 , sysId = {} , 请求结果 = {}" , sysId , mapper.writeValueAsString(result) );
    103. //如果访问失败了则返回 null
    104. } catch (Exception e){
    105. e.printStackTrace();
    106. logger.info("Redis监听消息:发送消息 , sysId = {} , 出现异常 = {}" , sysId , e.getMessage());
    107. }
    108. }
    109. */
    110. public StringRedisTemplate getStringRedisTemplate() {
    111. return stringRedisTemplate;
    112. }
    113. public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
    114. this.stringRedisTemplate = stringRedisTemplate;
    115. }
    116. }

    RedisCacheUtils.java

    1. package com.gy.xf.util;
    2. import org.apache.commons.lang.StringUtils;
    3. import org.springframework.data.redis.core.BoundHashOperations;
    4. import org.springframework.data.redis.core.RedisTemplate;
    5. import org.springframework.data.redis.core.StringRedisTemplate;
    6. import org.springframework.util.CollectionUtils;
    7. import java.util.Map;
    8. import java.util.Set;
    9. import java.util.concurrent.TimeUnit;
    10. /**
    11. * Redis 缓存工具类
    12. */
    13. public class RedisCacheUtils {
    14. /** Redis 发布订阅模式: 与redis配置文件的redis.topicName一致 */
    15. public static final String REDIS_CHANNEL_NAME = "message";
    16. /** 固定token: 16位 , Aes加密作为 key 参数 */
    17. public static final String CSRFTOKEN = "fireoms2021kqxlr";
    18. /**
    19. * app端登录用户用户唯一id token key 前缀
    20. */
    21. public static final String USER_ID_TOKEN_KEY_PREFIX = "user:lid_";
    22. /**
    23. * app端登录用户 token key 前缀
    24. */
    25. public static final String USER_TOKEN_KEY_PREFIX = "user:u_";
    26. /**
    27. * app端消息推送用户 token key 前缀
    28. */
    29. public static final String PUSH_TOKEN_KEY_PREFIX = "push:u_";
    30. //登录用户过期时间(7天后)
    31. public static final long TOKEN_EXPIRE_TIME_USER = 7 * 24 * 60 * 60;//(用户过期时间)
    32. //单位id列表
    33. public static final String KEY_ALARM_GROUPIDS = "alarm:groupIds";
    34. //单位警情数据前缀
    35. public static final String KEY_ALARM_GROUPID_PREFIX = "alarm:groupId_";
    36. //redis中key的超时时间
    37. public static final long KEY_ALARM_TIMEOUT = 12 * 60 * 60;//单位为秒,2小时(7200秒)
    38. /** --------------------- 微信公众平台:Redis 参数 --------------------- */
    39. //redis中key的超时时间
    40. public static final long KEY_WX_TIMEOUT = 7200;//单位为秒,2小时
    41. //公众号中访问access_token: 2小时过期
    42. public static final String KEY_WX_ACCESS_TOKEN = "wx:access_token";
    43. //公众号网页开发中的jsapi中请求的票据:2小时过期
    44. public static final String KEY_WX_TICKET = "wx:ticket";
    45. //接收公众号消息数据
    46. public static final String KEY_WX_USER_PREFIX = "wx:u_";
    47. /**
    48. * 生成签名及判断签名是否相同
    49. */
    50. public static boolean isEqualsSignData(String clientSignData, String data){
    51. String signData = MD5.Md5(data);
    52. if (clientSignData.equals(signData)){
    53. return true;
    54. }
    55. return false;
    56. }
    57. /** redis操作模板,面向对象的模板 */
    58. private static StringRedisTemplate stringRedisTemplate
    59. = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");
    60. private static RedisTemplate redisTemplate
    61. = (RedisTemplate) SpringUtil.getBean("redisTemplate");
    62. /**
    63. * 删除缓存
    64. * 根据key精确匹配删除
    65. *
    66. * @param key
    67. */
    68. @SuppressWarnings("unchecked")
    69. public static void del(String... key) {
    70. if (key != null && key.length > 0) {
    71. if (key.length == 1) {
    72. redisTemplate.delete(key[0]);
    73. } else {
    74. redisTemplate.delete(CollectionUtils.arrayToList(key));
    75. }
    76. }
    77. }
    78. /**
    79. * (根据key精确匹配删除)
    80. * @param key
    81. */
    82. public static void deleteByKey(String key) {
    83. if (key != null) {
    84. redisTemplate.delete(key);
    85. }
    86. }
    87. /**
    88. * 批量删除
    89. * (该操作会执行模糊查询,请尽量不要使用,以免影响性能或误删)
    90. *
    91. * @param pattern
    92. */
    93. public void batchDel(String... pattern) {
    94. for (String kp : pattern) {
    95. redisTemplate.delete(redisTemplate.keys(kp + "*"));
    96. }
    97. }
    98. /**
    99. * 取得缓存(int型)
    100. *
    101. * @param key
    102. * @return
    103. */
    104. public Integer getInt(String key) {
    105. String value = stringRedisTemplate.boundValueOps(key).get();
    106. if (StringUtils.isNotEmpty(value)) {
    107. return Integer.valueOf(value);
    108. }
    109. return null;
    110. }
    111. /**
    112. * 取得缓存(字符串类型)
    113. *
    114. * @param key
    115. * @return
    116. */
    117. public static String getStr(String key) {
    118. return stringRedisTemplate.boundValueOps(key).get();
    119. }
    120. /**
    121. * 取得缓存(字符串类型)
    122. *
    123. * @param key
    124. * @return
    125. */
    126. public static String getStr(String key, boolean retain) {
    127. String value = stringRedisTemplate.boundValueOps(key).get();
    128. if (!retain) {
    129. redisTemplate.delete(key);
    130. }
    131. return value;
    132. }
    133. /**
    134. * 模糊查询(根据规则) 返回 keys
    135. * @param pattern
    136. * @return
    137. */
    138. public static Set searchKeys(String pattern){
    139. return stringRedisTemplate.keys(pattern);
    140. }
    141. /**
    142. * 获取缓存
    143. * 注:基本数据类型(Character除外),请直接使用get(String key, Class clazz)取值
    144. *
    145. * @param key
    146. * @return
    147. */
    148. public static Object getObj(String key) {
    149. return redisTemplate.boundValueOps(key).get();
    150. }
    151. /**
    152. * 获取缓存
    153. * 注:java 8种基本类型的数据请直接使用get(String key, Class clazz)取值
    154. *
    155. * @param key
    156. * @param retain
    157. * 是否保留
    158. * @return
    159. */
    160. public Object getObj(String key, boolean retain) {
    161. Object obj = redisTemplate.boundValueOps(key).get();
    162. if (!retain) {
    163. redisTemplate.delete(key);
    164. }
    165. return obj;
    166. }
    167. /**
    168. * 获取缓存
    169. * 注:该方法暂不支持Character数据类型
    170. *
    171. * @param key
    172. * key
    173. * @param clazz
    174. * 类型
    175. * @return
    176. */
    177. @SuppressWarnings("unchecked")
    178. public T get(String key, Class clazz) {
    179. return (T) redisTemplate.boundValueOps(key).get();
    180. }
    181. /**
    182. * 获取缓存json对象
    183. *
    184. * @param key
    185. * key
    186. * @param clazz
    187. * 类型
    188. * @return
    189. * @throws Exception
    190. @SuppressWarnings("unchecked")
    191. public T getJson(String key, Class clazz) throws Exception {
    192. String jsonStr=null;
    193. jsonStr=stringRedisTemplate.boundValueOps(key).get();
    194. if(jsonStr==null){
    195. return null;
    196. }else{
    197. return (T) JsonUtil.jsonToBean(jsonStr, clazz);
    198. }
    199. } */
    200. /**
    201. * 将value对象写入缓存
    202. *
    203. * @param key
    204. * @param value
    205. * @param time
    206. * 失效时间(秒)
    207. */
    208. public static void set(String key, Object value, Long time) {
    209. if (value.getClass().equals(String.class)) {
    210. stringRedisTemplate.opsForValue().set(key, value.toString());
    211. } else if (value.getClass().equals(Integer.class)) {
    212. stringRedisTemplate.opsForValue().set(key, value.toString());
    213. } else if (value.getClass().equals(Double.class)) {
    214. stringRedisTemplate.opsForValue().set(key, value.toString());
    215. } else if (value.getClass().equals(Float.class)) {
    216. stringRedisTemplate.opsForValue().set(key, value.toString());
    217. } else if (value.getClass().equals(Short.class)) {
    218. stringRedisTemplate.opsForValue().set(key, value.toString());
    219. } else if (value.getClass().equals(Long.class)) {
    220. stringRedisTemplate.opsForValue().set(key, value.toString());
    221. } else if (value.getClass().equals(Boolean.class)) {
    222. stringRedisTemplate.opsForValue().set(key, value.toString());
    223. } else {
    224. redisTemplate.opsForValue().set(key, value);
    225. }
    226. if (time != null && time > 0) {
    227. redisTemplate.expire(key, time, TimeUnit.SECONDS);
    228. stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
    229. }
    230. }
    231. /**
    232. * 将value对象以JSON格式写入缓存
    233. *
    234. * @param key
    235. * @param value
    236. * @param time
    237. * 失效时间(秒)
    238. public void setJson(String key, Object value, Long time) {
    239. stringRedisTemplate.opsForValue().set(key, JsonUtil.toJsonString(value));
    240. if (time!=null&&time > 0) {
    241. stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
    242. }
    243. }
    244. */
    245. /**
    246. * 更新key对象field的值
    247. *
    248. * @param key
    249. * 缓存key
    250. * @param field
    251. * 缓存对象field
    252. * @param value
    253. * 缓存对象field值
    254. public void setJsonField(String key, String field, String value) {
    255. JSONObject obj = JSON.parseObject(stringRedisTemplate.boundValueOps(key).get());
    256. obj.put(field, value);
    257. stringRedisTemplate.opsForValue().set(key, obj.toJSONString());
    258. }
    259. */
    260. /**
    261. * 递减操作
    262. *
    263. * @param key
    264. * @param by
    265. * @return
    266. */
    267. public double decr(String key, double by) {
    268. return redisTemplate.opsForValue().increment(key, -by);
    269. }
    270. /**
    271. * 递增操作
    272. *
    273. * @param key
    274. * @param by
    275. * @return
    276. */
    277. public double incr(String key, double by) {
    278. return redisTemplate.opsForValue().increment(key, by);
    279. }
    280. /**
    281. * 获取double类型值
    282. *
    283. * @param key
    284. * @return
    285. */
    286. public double getDouble(String key) {
    287. String value = stringRedisTemplate.boundValueOps(key).get();
    288. if (StringUtils.isNotBlank(value)) {
    289. return Double.valueOf(value);
    290. }
    291. return 0d;
    292. }
    293. /**
    294. * 设置double类型值
    295. *
    296. * @param key
    297. * @param value
    298. * @param time
    299. * 失效时间(秒)
    300. */
    301. public void setDouble(String key, double value, Long time) {
    302. stringRedisTemplate.opsForValue().set(key, String.valueOf(value));
    303. if (time!=null&&time > 0) {
    304. stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
    305. }
    306. }
    307. /**
    308. * 设置double类型值
    309. *
    310. * @param key
    311. * @param value
    312. * @param time
    313. * 失效时间(秒)
    314. */
    315. public void setInt(String key, int value, Long time) {
    316. stringRedisTemplate.opsForValue().set(key, String.valueOf(value));
    317. if (time!=null&&time > 0) {
    318. stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
    319. }
    320. }
    321. /**
    322. * 将map写入缓存
    323. *
    324. * @param key
    325. * @param map
    326. * @param time
    327. * 失效时间(秒)
    328. */
    329. public void setMap(String key, Map map, Long time) {
    330. redisTemplate.opsForHash().putAll(key, map);
    331. }
    332. /**
    333. * 将map写入缓存
    334. *
    335. * @param key
    336. * @param map
    337. * @param time
    338. * 失效时间(秒)
    339. @SuppressWarnings("unchecked")
    340. public void setMap(String key, T obj, Long time) {
    341. Map map = (Map)JsonUtil.parseObject(obj, Map.class);
    342. redisTemplate.opsForHash().putAll(key, map);
    343. }
    344. */
    345. /**
    346. * 向key对应的map中添加缓存对象
    347. *
    348. * @param key
    349. * @param map
    350. */
    351. public void addMap(String key, Map map) {
    352. redisTemplate.opsForHash().putAll(key, map);
    353. }
    354. /**
    355. * 向key对应的map中添加缓存对象
    356. *
    357. * @param key
    358. * cache对象key
    359. * @param field
    360. * map对应的key
    361. * @param value
    362. * 值
    363. */
    364. public void addMap(String key, String field, String value) {
    365. redisTemplate.opsForHash().put(key, field, value);
    366. }
    367. /**
    368. * 向key对应的map中添加缓存对象
    369. *
    370. * @param key
    371. * cache对象key
    372. * @param field
    373. * map对应的key
    374. * @param obj
    375. * 对象
    376. */
    377. public void addMap(String key, String field, T obj) {
    378. redisTemplate.opsForHash().put(key, field, obj);
    379. }
    380. /**
    381. * 获取map缓存
    382. *
    383. * @param key
    384. * @param clazz
    385. * @return
    386. public Map mget(String key, Class clazz) {
    387. BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(key);
    388. return boundHashOperations.entries();
    389. }*/
    390. /**
    391. * 获取map缓存中的某个对象
    392. *
    393. * @param key
    394. * @param field
    395. * @param clazz
    396. * @return
    397. */
    398. @SuppressWarnings("unchecked")
    399. public T getMapField(String key, String field, Class clazz) {
    400. return (T) redisTemplate.boundHashOps(key).get(field);
    401. }
    402. /**
    403. * 获取map缓存
    404. *
    405. * @param key
    406. * @param clazz
    407. * @return
    408. public T getMap(String key, Class clazz) {
    409. BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(key);
    410. Map map = boundHashOperations.entries();
    411. return JsonUtil.parseObject(map, clazz);
    412. } */
    413. /**
    414. * 删除map中的某个对象
    415. *
    416. * @author lh
    417. * @date 2016年8月10日
    418. * @param key
    419. * map对应的key
    420. * @param field
    421. * map中该对象的key
    422. */
    423. public void delMapField(String key, String... field) {
    424. BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(key);
    425. boundHashOperations.delete(field);
    426. }
    427. /**
    428. * 指定缓存的失效时间
    429. *
    430. * @author FangJun
    431. * @date 2016年8月14日
    432. * @param key
    433. * 缓存KEY
    434. * @param time
    435. * 失效时间(秒)
    436. */
    437. public void expire(String key, Long time) {
    438. if (time!=null&&time > 0) {
    439. redisTemplate.expire(key, time, TimeUnit.SECONDS);
    440. }
    441. }
    442. /**
    443. * 添加set
    444. *
    445. * @param key
    446. * @param value
    447. */
    448. public void sadd(String key, String... value) {
    449. redisTemplate.boundSetOps(key).add(value);
    450. }
    451. /**
    452. * 删除set集合中的对象
    453. *
    454. * @param key
    455. * @param value
    456. */
    457. public void srem(String key, String... value) {
    458. redisTemplate.boundSetOps(key).remove(value);
    459. }
    460. /**
    461. * set重命名
    462. *
    463. * @param oldkey
    464. * @param newkey
    465. */
    466. public void srename(String oldkey, String newkey) {
    467. redisTemplate.boundSetOps(oldkey).rename(newkey);
    468. }
    469. /**
    470. * 短信缓存
    471. *
    472. * @author fxl
    473. * @date 2016年9月11日
    474. * @param key
    475. * @param value
    476. * @param time
    477. public void setIntForPhone(String key, Object value, int time) {
    478. stringRedisTemplate.opsForValue().set(key, JsonUtil.toJsonString(value));
    479. if (time > 0) {
    480. stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
    481. }
    482. }
    483. */
    484. /**
    485. * 模糊查询keys
    486. *
    487. * @param pattern
    488. * @return
    489. */
    490. public static Set keys(String pattern) {
    491. return redisTemplate.keys(pattern);
    492. }
    493. /**
    494. *
    495. * @Description (检查key是否存在,返回boolean值 )
    496. * @author feizhou
    497. * @Date 2018年5月29日下午5:37:40
    498. * @version 1.0.0
    499. * @param key
    500. * @return
    501. */
    502. public Boolean ishasKey(String key) {
    503. return stringRedisTemplate.hasKey(key);
    504. }
    505. }

    SpringUtil.java

    1. package com.gy.xf.util;
    2. import org.springframework.beans.BeansException;
    3. import org.springframework.context.ApplicationContext;
    4. import org.springframework.context.ApplicationContextAware;
    5. import org.springframework.stereotype.Component;
    6. /**
    7. * 工具类 - Spring
    8. * @author zgp2010
    9. *
    10. */
    11. public class SpringUtil implements ApplicationContextAware {
    12. private static ApplicationContext applicationContext;
    13. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    14. SpringUtil.applicationContext = applicationContext;
    15. }
    16. public static ApplicationContext getApplicationContext() {
    17. return applicationContext;
    18. }
    19. /**
    20. * 根据Bean名称获取实例
    21. *
    22. * @param name
    23. * Bean注册名称
    24. *
    25. * @return bean实例
    26. *
    27. * @throws BeansException
    28. */
    29. public static Object getBean(String name) throws BeansException {
    30. return applicationContext.getBean(name);
    31. }
    32. }

    applicationContext.xml

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    4. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    5. xmlns:context="http://www.springframework.org/schema/context"
    6. xmlns:cache="http://www.springframework.org/schema/cache"
    7. xmlns:jee="http://www.springframework.org/schema/jee"
    8. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    9. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    11. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
    12. http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
    13. http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd" >
    14. <bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    15. <property name="jndiName" value="java:comp/env/jdbc/MSSQLDS">property>
    16. bean>
    17. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    18. <property name="dataSource"><ref bean="dataSource" />property>
    19. bean>
    20. <bean name="new_dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    21. <property name="jndiName" value="java:comp/env/jdbc/MSSQLDSALARM">property>
    22. bean>
    23. <bean id="newjdbcTemple" class="org.springframework.jdbc.core.JdbcTemplate">
    24. <property name="dataSource" ref="new_dataSource"/>
    25. bean>
    26. <bean id="transactionManager"
    27. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    28. <property name="dataSource"><ref bean="dataSource" />property>
    29. bean>
    30. <bean id="dataSourceTransactionManager"
    31. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    32. <property name="dataSource"><ref bean="dataSource" />property>
    33. bean>
    34. <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
    35. <bean id="springUtil" class="com.gy.xf.util.SpringUtil" lazy-init="false" />
    36. <context:property-placeholder location="classpath*:*.properties">context:property-placeholder>
    37. <import resource="com/gy/xf/spring/spring-admin.xml" />
    38. <cache:annotation-driven cache-manager="springCacheManager" proxy-target-class="false"/>
    39. <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    40. <property name="configLocation" value="classpath:ehcache-settings.xml"/>
    41. <property name="shared" value="true">property>
    42. bean>
    43. <bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    44. <property name="cacheManager" ref="ehcacheManager"/>
    45. bean>
    46. <import resource="applicationContext-redis.xml">import>
    47. beans>

    2、服务端(发布):
     

    说明:服务端和客户端的redis连接参数都是一样的,这里不再重复贴出配置文件。

    服务端发布内容,用到的是 redisTemplate中的 convertAndSend(String channel, Object message) 方法。只要服务端和客户端配置的channel名字是一样的,服务端发送客户端订阅了就能收到。

    /** Redis 发布订阅模式: 与redis配置文件的redis.topicName一致 */
    public static final String REDIS_CHANNEL_NAME = "message";

    1. public void convertAndSend(String channel, Object message) {
    2. Assert.hasText(channel, "a non-empty channel is required");
    3. final byte[] rawChannel = this.rawString(channel);
    4. final byte[] rawMessage = this.rawValue(message);
    5. this.execute(new RedisCallback() {
    6. public Object doInRedis(RedisConnection connection) {
    7. connection.publish(rawChannel, rawMessage);
    8. return null;
    9. }
    10. }, true);
    11. }
    12. 实际用法,在控制器类中或工具类中 注入 RedisTemplate类 或者 StringRedisTemplate 类,在需要发布消息的地方执行 convertAndSend 方法即可。

      1. AlarmInfo model = new AlarmInfo(groupId , uploadId);
      2. String postData = JSON.toJSONString(model);
      3. logger.info("地理信息系统调派专职队车辆,参数:{}" , postData);
      4. stringRedisTemplate.convertAndSend(RedisCacheUtils.REDIS_CHANNEL_NAME , postData);

    13. 相关阅读:
      Spring @ComponentScan 自定义扫描规则
      【OpenMMLab】AI实战营第二期Day5:MMPretrain代码课
      Win10电脑任务栏没有蓝牙图标的简单解决方法
      chrome安装vue devtools
      基于YOLOV8模型的农作机器和行人目标检测系统(PyTorch+Pyside6+YOLOv8模型)
      搭建Github图床
      C语言用筛选法求 100 之内的素数(挖去 1,被除数平方根)
      python 虚拟环境管理
      面向大规模队列,百万并发的多优先级消费系统设计
      学习在php中将特大数字转成带有千/万/亿为单位的字符串
    14. 原文地址:https://blog.csdn.net/zgphacker2010/article/details/127136955