我使用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
在没有真正了解您的确切用例的情况下(我还不允许在不幸的情况下添加评论),我尝试简要总结一下我的想法。他们都假设你使用杰克逊进行json映射,至少 春季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>
如果你希望控制每个Controller,继承Spring 一个AbstractController 并根据javaDoc设置cacheSeconds属性。
当然,http缓存的真正威力来自于服务器前面的http代理。
第二个想法: 实现自己的子类 MappingJackson2HttpMessageConverter。在 writeInternal()
您可以添加一些访问缓存的逻辑来检索已映射的版本,而不是映射输入对象。这种方法意味着您将点击您的服务以检索Json流后面的java对象。如果这对你来说没问题,因为在某些时候也有缓存,这种方法值得一试。
第三个想法: 在提供原始json字符串/流的专用包装器服务中自己进行json映射。您可以轻松注入杰克逊映射器(类名称 ObjectMapper)并完全控制映射。注释此服务然后允许您缓存结果。在您的控制器中,您只提供一个 ResponseEntity 您要使用的相应类型(字符串或某些流)。如果存在缓存结果,这甚至会阻止更深入的服务访问。
编辑:可能是 MappingJackson2JsonView 也可以派上用场。说实话,我之前从未使用它,所以我无法真正说出它的用法。
希望有助于和/或给予灵感!
干杯
在没有真正了解您的确切用例的情况下(我还不允许在不幸的情况下添加评论),我尝试简要总结一下我的想法。他们都假设你使用杰克逊进行json映射,至少 春季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>
如果你希望控制每个Controller,继承Spring 一个AbstractController 并根据javaDoc设置cacheSeconds属性。
当然,http缓存的真正威力来自于服务器前面的http代理。
第二个想法: 实现自己的子类 MappingJackson2HttpMessageConverter。在 writeInternal()
您可以添加一些访问缓存的逻辑来检索已映射的版本,而不是映射输入对象。这种方法意味着您将点击您的服务以检索Json流后面的java对象。如果这对你来说没问题,因为在某些时候也有缓存,这种方法值得一试。
第三个想法: 在提供原始json字符串/流的专用包装器服务中自己进行json映射。您可以轻松注入杰克逊映射器(类名称 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();
}