微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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也可以方便.说实话,我以前从来没有使用过它,所以我不能真正地说说它的用法.

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

原文地址:https://www.jb51.cc/java/126273.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐