如何让Spring缓存存储ResponseBody而不是中间对象 [英] How to have spring cache store the ResponseBody and not the intermediary object

查看:137
本文介绍了如何让Spring缓存存储ResponseBody而不是中间对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I use spring cache with this method which returns the queried value as JSON:

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

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

This works fine and the HugeValue-object is stored in the cache (Hazelcast in this case). I want to further improve this because the time taken to create JSON from the HugeValue is quite high. Can I tell spring cache to cache the JSON-ified version of my object ?

我使用Jackson与Spring Boot 1.2和Spring 4.1

I use Jackson with Spring Boot 1.2 and Spring 4.1

推荐答案

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

Without really knowing your exact use case (I'm not yet allowed to add comments for asking unfortunately), I try to give a short summary on the ideas I have in mind. They all assume that you use Jackson for json mapping and at least Spring 3.1.

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

There is no enableResponseBodyCaching feature in SpringMVC as far as I know.

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

First alternative: Use http caching because it seems like you really want to cache the whole http response. Spring offers a straight forward way of global configuration:

<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>

如果您希望控制每个Controller,请继承Spring AbstractController 和根据javaDoc设置cacheSeconds属性。

If you wish to control this per Controller, inherit from Spring AbstractController and set cacheSeconds property according to javaDoc.

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

True power of http caching comes with a http proxy in front of your server of course.

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

Second idea: Implement your own subclass of MappingJackson2HttpMessageConverter. In writeInternal() you could add some logic which accesses a cache to retrieve an already mapped version instead of mapping the input object. This approach means that you will hit your services in order to retrieve the java object behind the Json stream. If this is fine for you because there is also caching at some point, this approach is worth a try imho.

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

Third idea: Do the json mapping on your own in a dedicated wrapper service which provides raw json strings/streams. You can easily inject the Jackson mapper (class name ObjectMapper) and gain full control over the mapping. Annotating this service then allows you to cache the results. In your Controller you only provide a ResponseEntity of the according type you whish to use (String or some stream). This would even prevent deeper service access if there is a cached result present.

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

Probably the MappingJackson2JsonView could also get handy. To be honest, I never worked with it before so I can't really say something about its usage.

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

Hope that helps and/or gives inspiration! Cheers

这篇关于如何让Spring缓存存储ResponseBody而不是中间对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆