如何让Spring缓存存储ResponseBody而不是中间对象

我使用spring cache和this方法,它将查询的值作为JSON返回:

@RequestMapping("/getById") @ResponseBody @Cacheable public HugeValue getHugeValueFromSlowFoo( @RequestParam(value = "id", defaultValue = "") String id ) { return Foo.getById( id ); } 

这工作正常,HugeValue对象存储在缓存中(在本例中为Hazelcast)。 我想进一步改进这个,因为从HugeValue创建JSON的时间非常长。 我可以告诉spring cache缓存我对象的JSON-ified版本吗?

我使用Jackson和Spring Boot 1.2以及Spring 4.1

在没有真正了解您的确切用例的情况下(我还不允许在不幸的情况下添加评论),我尝试简要总结一下我的想法。 他们都假设您使用Jackson进行json映射,至少使用Spring 3.1

据我所知,SpringMVC中没有enableResponseBodyCachingfunction。

第一种选择:使用http缓存,因为您似乎真的想要缓存整个http响应。 Spring提供了一种直接的全局配置方式:

         

如果您希望控制每个Controller,请inheritanceSpring AbstractController并根据javaDoc设置cacheSeconds属性。

当然,http缓存的真正威力来自于服务器前面的http代理。

第二个想法:实现您自己的MappingJackson2HttpMessageConverter子类。 在writeInternal()您可以添加一些访问缓存的逻辑来检索已映射的版本,而不是映射输入对象。 这种方法意味着您将点击您的服务以检索Json流后面的java对象。 如果这对你来说没问题,因为在某些时候也有缓存,这种方法值得一试。

第三个想法:在一个提供原始json字符串/流的专用包装器服务中自己进行json映射。 您可以轻松注入Jackson映射器(类名称ObjectMapper )并获得对映射的完全控制。 注释此服务然后允许您缓存结果。 在您的控制器中,您只提供您要使用的相应类型的ResponseEntity (字符串或某些流)。 如果存在缓存结果,这甚至会阻止更深入的服务访问。

编辑:可能MappingJackson2JsonView也可以派上用场。 说实话,我之前从未使用它,所以我无法真正说出它的用法。

希望有助于和/或给予灵感! 干杯

我认为这可行。

 public interface HugeValueService{ public String getHugeValueFromSlowFoo(String id); } public class HugeValueServiceImpl implements HugeValueService{ @Cacheable public String getHugeValueFromSlowFoo(String id ) { return Foo.getById( id ); } } Your Class ---------- @RequestMapping("/getById") @ResponseBody public HugeValue getHugeValueFromSlowFoo( @RequestParam(value = "id", defaultValue = "") String id ) { return hugeValueService.getHugeValueFromSlowFoo(id); } 

祝你好运!!!

缓存json并手动将其放入响应中。

 public void getHugeValueFromSlowFoo( @RequestParam(value = "id", defaultValue = "") String id, ServletResponse resp ) { String jsonSerializedHugeValue = Bar.getById(id); // serialize manually with ObjectMapper resp.getWriter().write(jsonSerializedHugeValue); resp.setContentType("application/json"); resp.flushBuffer(); }