在SpringBoot中缓存计算的响应

时间:2019-04-12 21:31:06

标签: spring spring-boot spring-mvc caching

我有一个RestController返回一些本地化的实体,例如翻译成用户要求的语言的书籍标题和说明。

@RestController
public class BooksResource {

    @Autowired
    private BookService bookService;

    @GetMapping("/books")
    public List<Book> findBooks(
            @RequestParam(required = false) Boolean active,
            @RequestHeader(value = "accept-language", defaultValue = "*") String acceptedLanguages) {
        return bookService.findAll(active, acceptedLanguages);
    }

    @GetMapping("/books/{bookId}")
    public Book findBook(
            @PathVariable String bookId,
            @RequestHeader(value = "accept-language", defaultValue = "*") String acceptedLanguages) {
        return bookService.findById(bookId, acceptedLanguages);
    }
}

我有很多不同的客户端发出相同的请求,但是每个客户端都不经常重复请求。

我正在寻找一种通过一组请求参数和标头来缓存本地化响应(完全计算/渲染的json)的方法。

我知道我可以在资源方法上添加使用Cacheable,并使用KeyGeneratoraccept-language标头(可能是媒体类型,以及其他类型)创建缓存键我想要的参数。

但是,这将缓存对象,而不是呈现的json(或XML)。

我已经阅读了documentation on caching static assets,但这只是设置缓存控制标头。

如果它们已经被缓存了,我想避免这些对象的序列化。

我可以更改资源方法以返回ResponseEntity<String>并自己处理渲染,但是我必须为每个我们要支持的新媒体类型在每个资源方法中更改代码。

我已经考虑过使用HandlerInterceptor,但是它会在响应呈现之前对其进行处理。

我认为我可以使用自定义CacheProvider,但这似乎需要大量工作。

1 个答案:

答案 0 :(得分:0)

为此,您可以使用Filter。那些可以读取渲染的输出流,也可以对其进行写入。如果您使用委托的过滤器代理对其进行设置,则它也可以访问诸如@Cacheable之类的spring服务和注释。

您最好利用您提到的那些缓存控制标头。在这种情况下,用户方将知道这些XML有效期有多长时间。无论如何,缓存这样的信息(例如Varnish)有更好的解决方案。