java – 如何让spring缓存存储ResponseBody而不是中间对象

我使用 spring cache与这个方法返回查询值作为 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对象版本的对象吗?

我使用Jackson与Spring Boot 1.2和Spring 4.1

解决方法

没有真正知道你的确切用例(我还没有被允许添加评论来询问不幸),我试着简要总结一下我的想法.他们都假设你使用杰克逊进行json映射,至少Spring 3.1.

据我所知,在SpringMVC中没有enableResponseBodyCaching功能.

一个替代方法:使用http缓存,因为您似乎希望缓存整个http响应. Spring提供了一种直观的全局配置方式:

<mvc:interceptors>
    <bean id="webContentInterceptor"
          class="org.springframework.web.servlet.mvc.WebContentInterceptor">
        <property name="cacheSeconds" value="0"/>
        <property name="useExpiresHeader" value="true"/>
        <property name="useCacheControlHeader" value="true"/>
        <property name="useCacheControlNoStore" value="true"/>
    </bean>
</mvc:interceptors>

如果要控制每个控制器,继承自Spring AbstractController,并根据javaDoc设置cacheSeconds属性.

当然,http缓存的真正功能在您的服务器前面带有一个http代理.

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

第三个想法:在专用的包装器服务中自己做一个json映射,它提供了原始的json字符串/流.您可以轻松地注入杰克逊映射器(类名ObjectMapper)并获得对映射的完全控制.注释此服务,然后允许您缓存结果.在你的控制器中,你只提供一个你喜欢使用的类型的ResponseEntity(String或一些流).如果存在缓存结果,这甚至可以防止更深入的服务访问.

编辑:可能MappingJackson2JsonView也可以方便.说实话,我以前从来没有使用过它,所以我不能真正地说说它的用法.

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

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...