简体   繁体   English

Spring Cacheable 除非条件不起作用

[英]Spring Cacheable unless condition doesn't work

I have developed a REST end-point in Springboot that takes a String ID and responds with a ModelAndView .我在 Springboot 中开发了一个 REST 端点,它采用String ID 并以ModelAndView响应。 This end-point is marked with @Cacheable annotation.这个端点用@Cacheable注释标记。 Now there are two things that can happen at the given end-point.现在,在给定的终点可能会发生两件事。

Case 1: The request ID exists in the DB and yields a URL to which redirection needs to happen.情况 1:请求 ID 存在于数据库中,并产生一个需要重定向到的 URL。 In this case, response should be cached so that upon consecutive requests of the same ID, the result can be served from Cache在这种情况下,应该缓存响应,以便在相同 ID 的连续请求时,可以从缓存中提供结果

Case 2: The requested ID doesn't exist in the DB and thus redirection should happen to a specific URL and no caching should be done in this scenario.情况 2:请求的 ID 在数据库中不存在,因此重定向应该发生在特定的 URL 上,并且在这种情况下不应该进行缓存。

So below is my method所以下面是我的方法

@GetMapping("{id}")
    @Cacheable(value = "url-single", key = "#id", unless = "#result.view!=\"redirect:/notfound\"")
    public ModelAndView redirect(@PathVariable("id") String id, ServletRequest servletRequest,
            ServletResponse servletResponse) {
        HttpServletRequest request = HttpServletRequest.class.cast(servletRequest);
        LOG.info("Redirection request from: {} for Short URL Key: {}", request.getRemoteAddr(), id);
        try {
            Optional<String> originalUrlOptional = urlManagerService.retrieveOriginalUrl(id);
            if (originalUrlOptional.isPresent() && !StringUtils.isEmpty(originalUrlOptional.get())) {
                LOG.info("Found Original URL: {} for Short URL Key: {}", originalUrlOptional.get(), id);
                return new ModelAndView("redirect:https://" + originalUrlOptional.get());
            }

        } catch (NoSuchElementException e) {
            LOG.error("Error while redirecting: {}", e.getMessage(), e);
        }
        return new ModelAndView("redirect:/notfound");
    }

If I understand it correctly from here , the keyword unless in @Cacheable applies to the return type and in order to access any particular member variable of the return type object, we have to refer to it as #result.attributeName <comparison> <value> .如果我从这里正确理解它,关键字unless @Cacheable适用于返回类型,并且为了访问返回类型对象的任何特定成员变量,我们必须将其称为#result.attributeName <comparison> <value> .

So why isn't anything being stored in my Redis cache?那么为什么我的 Redis 缓存中没有存储任何内容呢? If I remove the unless condition, everything gets stored.如果我删除unless条件,一切都会被存储。 Is the condition not correct?条件不正确吗?

I have been looking at your unless statement:我一直在看你的除非声明:

unless = "#result.view!=\"redirect:/notfound\""

so this means that it WONT be cached if the result.view IS NOT redirect:/notfound.所以这意味着如果 result.view 没有重定向:/notfound,它就不会被缓存。

My assumption is that you want to cache it, except when redirect:/notfound.我的假设是你想缓存它,除非重定向:/notfound。 There is a "double negative" here.这里有一个“双重否定”。

So you probably should use:所以你可能应该使用:

unless = "#result.view==\"redirect:/notfound\""

(so use '==' instead of '!=') (所以使用 '==' 而不是 '!=')

Let me know if this works!让我知道这个是否奏效!

I found where I was going wrong after playing with the unless conditional keyword for awhile.在使用了unless条件关键字一段时间后,我发现了哪里出错了。 The #result inside the double quotes (") of the unless keyword is literally the object to returned. What that means is that, you can call whatever method can be called on that object. unless关键字的双引号 (") 内的#result字面上是要返回的对象。这意味着,您可以调用可以在该对象上调用的任何方法。

The statement "#result.view==\\"redirect:/notfound\\"" was failing because the object didn't expose any member variable called view .语句"#result.view==\\"redirect:/notfound\\""失败,因为该对象没有公开任何名为view成员变量。 Using the expression unless = "#result.getViewName().equals(\\"redirect:/notfound\\")" actually did the trick because there was a method getViewName() on the object that returned String and calling equals() on it did the actual comparison.使用表达式unless = "#result.getViewName().equals(\\"redirect:/notfound\\")"实际上做到了这一点,因为对象上有一个方法getViewName()返回 String 并在其上调用equals()做了实际的比较。

I guess I got stuck here because I wasn't not familiar with Spring Expression Language or SpEL我想我被困在这里是因为我不熟悉Spring Expression LanguageSpEL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM