Redis缓存List时遇ResponseEntity序列化异常求助
问题原因分析
你遇到的异常是因为**@Cacheable注解会自动缓存方法的返回值**,而你的方法返回的ResponseEntity<?>类并未实现Serializable接口,Redis默认的序列化器要求缓存对象必须可序列化,因此抛出了序列化失败的异常。同时你手动通过RedisTemplate操作缓存的逻辑,和@Cacheable的自动缓存逻辑存在重复冲突。
解决方案
方案一:移除@Cacheable,完全手动管理缓存
既然你已经自己实现了缓存的判断、读取、写入逻辑,直接去掉@Cacheable注解即可避免自动缓存ResponseEntity的问题。同时要确保NoteResponse类实现Serializable接口,否则手动存入Redis时也会报错。
修改后的服务方法代码:
@Autowired private RedisTemplate<String, Object> redisTemplate; // 移除@Cacheable注解 public ResponseEntity<?> getAllNotes(Integer userId) { String cacheKey = "notes"; // 补充定义缓存key String userIdAsKey = userId.toString(); // 补充定义用户ID对应的哈希key HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash(); // 检查缓存中是否存在该用户的笔记 if (hashOperations.hasKey(cacheKey, userIdAsKey)) { List<NoteResponse> noteResponses = (List<NoteResponse>) hashOperations.get(cacheKey, userIdAsKey); return ResponseEntity.ok(noteResponses); } List<Note> notes = noteRepository.findAllByUserId(userId); List<NoteResponse> noteResponses = Helper.getNoteResponse(notes); hashOperations.put(cacheKey, userIdAsKey, noteResponses); return ResponseEntity.ok(noteResponses); }
NoteResponse类需实现序列化:
public class NoteResponse implements Serializable { // 类成员变量与方法 private static final long serialVersionUID = 1L; // 建议添加序列化版本号 }
方案二:保留@Cacheable,让Spring自动管理缓存
如果想利用@Cacheable的自动缓存能力,需修改方法返回值为要缓存的List<NoteResponse>,将ResponseEntity的包装逻辑移到Controller层,同时保证NoteResponse实现Serializable接口。
服务层方法修改:
@Autowired private RedisTemplate<String, Object> redisTemplate; @Cacheable(value = "notes", key = "#userId") public List<NoteResponse> getAllNotes(Integer userId) { List<Note> notes = noteRepository.findAllByUserId(userId); return Helper.getNoteResponse(notes); }
Controller层调用并包装:
@GetMapping("/notes") public ResponseEntity<?> getAllNotes(@RequestParam Integer userId) { List<NoteResponse> noteResponses = noteService.getAllNotes(userId); return ResponseEntity.ok(noteResponses); }
内容的提问来源于stack exchange,提问作者retr0
相关产品推荐
相关产品推荐

