如何为使用Spring Cache缓存的Spring Web Service设置正确的Last-Modified标头值?

Naz*_*zar 3 java spring caching spring-mvc spring-cache

我有这样的Spring MVC控制器:

@Controller
@RequestMapping(value = "/user")
public class UserController {
   .....      
   @Cacheable(value = "users", key = "#id")
   @RequestMapping(value = "/get", method = RequestMethod.GET)
   @ResponseBody
   public User getUser(Long id){
       return userService.get(id);
   }
   ....
}
Run Code Online (Sandbox Code Playgroud)

我想将标题Last-Modified添加到GetUser Web服务的HTTP响应中.
如何在我的商店中添加缓存时获得正确的日期?
如何将此日期的Last-Modified标题添加到Spring Controller方法的响应中?

Ral*_*lph 10

Spring有一个已经建立的支持来处理last-modifiedIf-Modified-Since标头中的从动请求处理方法.

它基于 WebRequest.checkNotModified(long lastModifiedTimestamp)

这个例子只取自java doc:

对于修改后的案例和未修改的案例,这也将透明地设置适当的响应头.典型用法:

 @RequestMapping(value = "/get", method = RequestMethod.GET)
 public String myHandleMethod(WebRequest webRequest, Model model) {
    long lastModified = // application-specific calculation
    if (request.checkNotModified(lastModified)) {
      // shortcut exit - no further processing necessary
      return null;
    }
    // further request processing, actually building content
    model.addAttribute(...);
    return "myViewName";
}
Run Code Online (Sandbox Code Playgroud)

但是您的@Cacheable注释是一个问题,因为它会阻止执行该方法(对于第二次调用),因此request.checkNotModified不会调用该注释.- 如果缓存很重要,那么您可以@Cacheable从控制器方法中删除注释,并将其放在request.checkNotModified完成后调用的内部方法上.

 //use selfe in order to use annotation driven advices
 @Autowire
 YourController selfe;

 @RequestMapping(value = "/get", method = RequestMethod.GET)
 public String myHandleMethod(WebRequest webRequest, Model model) {
    long lastModified = // application-specific calculation
    if (request.checkNotModified(lastModified)) {
      // shortcut exit - no further processing necessary
      return null;
    } else {  
      return selfe.innerMyHandleMethod(model);
    }
}

@Cacheable(value = "users", key = "#id")
public String innerMyHandleMethod(Model model) {   
    model.addAttribute(...);
    return "myViewName";
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*yer 5

这个怎么样:

@Controller
@RequestMapping(value = "/user")
class UserController {

    @Cacheable(value = "users", key = "#id")
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<User> getUser(Long id) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Last-Modified", dateFormat.format(new Date()));
        return new ResponseEntity<SecurityProperties.User>(headers, userService.get(id), HttpStatus.OK);
    }
}
Run Code Online (Sandbox Code Playgroud)