經理提出新的需求,需要知道每天微信推送了多少條模板消息,成功多少條,失敗多少條,想到用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);