经理提出新的需求,需要知道每天微信推送了多少条模板消息,成功多少条,失败多少条,想到用Redis缓存,网上查了一些资料,Redis中有方法increment,测试代码如下
Controller
import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @author wangqq * @version 创建时间:2018年8月10日 下午2:30:47 * 类说明 */ @Controller @RequestMapping("test") public class TestController { @Resource private TestService testService; @RequestMapping("testRedis") @ResponseBody public int testRedis (){ return testService.testRedis (); } }
Service
import javax.annotation.Resource; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; /** * @author wangqq * @version 创建时间:2018年8月10日 下午2:32:13 * 类说明 */ @Service public class TestService { @Resource RedisTemplate<String,Object> redisTemplate; @Resource(name="redisTemplate") private ValueOperations<String,Object> ops; public int testRedis() { try { //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1 ops.increment("success", 1); return (int) ops.get("success"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return 0 ; } }
直接使用ops.get("success"),会出现错误,报错信息 Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException。 根据信息,可以看到是反序列化出错,上网查一下,貌似是因为JDK序列化之后,反序列化失败。解决办法:
第一种解决办法
用 redisTemplate.boundValueOps("success").get(0, -1)获得key值
import javax.annotation.Resource; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; /** * @author wangqq * @version 创建时间:2018年8月10日 下午2:32:13 * 类说明 */ @Service public class TestService { @Resource RedisTemplate<String,Object> redisTemplate; @Resource(name="redisTemplate") private ValueOperations<String,Object> ops; public int testRedis() { try { //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1 ops.increment("success", 1); //return (int) ops.get("success"); return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1)); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return 0 ; } }
页面显示为2,因为第一次已经成功了,只是get失败了
第二种解决办法
添加一个方法 getKey
import javax.annotation.Resource; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Service; /** * @author wangqq * @version 创建时间:2018年8月10日 下午2:32:13 * 类说明 */ @Service public class TestService { @Resource RedisTemplate<String,Object> redisTemplate; @Resource(name="redisTemplate") private ValueOperations<String,Object> ops; public int testRedis() { try { //此方法会先检查key是否存在,存在+1,不存在先初始化,再+1 ops.increment("success", 1); //return (int) ops.get("success"); //return Integer.valueOf(redisTemplate.boundValueOps("success").get(0, -1)); return (int) getKey("success"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return 0 ; } public long getKey(final String key) { return redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer(); byte[] rowkey = redisSerializer.serialize(key); byte[] rowval = connection.get(rowkey); try { String val = redisSerializer.deserialize(rowval); return Long.parseLong(val); } catch (Exception e) { return 0L; } } }); } }
页面返回
最后一步,设置每天零点过期,重新计数
//当天时间 Date date = new Date(); //当天零点 date = DateUtils.truncate(date, Calendar.DAY_OF_MONTH); //第二天零点 date = DateUtils.addDays(date, +1); redisTemplate.expireAt("success", date);