本文共 4291 字,大约阅读时间需要 14 分钟。
Servlet的生态中,提供了一种友好机制用来提高系统的响应速度,当客户端查询的数据在没有变化的情况下直接返回,以减少服务器压力和网络传输的压力。Spring MVC也很好的继承了该机制,下面我们就学习下怎么使用LastModified。
public class MyServlet extends HttpServlet{ /** * */ private static final long serialVersionUID = -2471386444207404619L; private static Long count= -1L; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { System.out.println("req...."); count= System.currentTimeMillis(); resp.getWriter().write("hello" +count); } @Override public long getLastModified(HttpServletRequest req) { return count; }}
Spring-mvc.xml配置如下:
因为handler是Servlet,所以此处使用了BeanNameUrlHandlerMapping和SimpleServletHandlerAdapter。
然后在对该请求的时候,就能在request headers中发现If-Modified-Since头信息,response中发现Last-Modified。
public class InfoController extends AbstractController implements LastModified{ private static Long count= -1L; public String test() { return "hello"; } @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { count= System.currentTimeMillis(); response.getWriter().write("hello" +count); return null; } @Override public long getLastModified(HttpServletRequest request) { // TODO Auto-generated method stub return count; } }
因为handler是Controller,所以Adapter使用了SimpleControllerHandlerAdapter。
请求的时候在request headers中发现If-Modified-Since头信息,response中发现Last-Modified。
@RestController@RequestMapping("/info")public class JJController { private static Long count = 0L; @GetMapping("/jj") public String test(WebRequest request) { if(request.checkNotModified(count)) { return null; } System.out.println("******************************8"); count = System.currentTimeMillis(); return "hello"; }}
为了找到对应的处理器和正确处理请求,handlerMapping和handlerAdapter的配置如上。
但是并没有实现LastModified接口,原因,请看源码RequestMappingHandlerAdapter(由于3.2版本之后,AnnotationMethodHandlerAdapter已经不被推荐使用,替代为RequestMappingHandlerAdapter)中的描述:
我们再看看 WebRequest中关于checkNotModified方法的说明:
/** * Check whether the requested resource has been modified given the * supplied last-modified timestamp (as determined by the application). *This will also transparently set the "Last-Modified" response header * and HTTP status when applicable. *
Typical usage: *
* 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"; * }*This method works with conditional GET/HEAD requests, but * also with conditional POST/PUT/DELETE requests. *
Note: you can use either * this {@code #checkNotModified(long)} method; or * {@link #checkNotModified(String)}. If you want enforce both * a strong entity tag and a Last-Modified value, * as recommended by the HTTP specification, * then you should use {@link #checkNotModified(String, long)}. *
If the "If-Modified-Since" header is set but cannot be parsed * to a date value, this method will ignore the header and proceed * with setting the last-modified timestamp on the response. * @param lastModifiedTimestamp the last-modified timestamp in * milliseconds that the application determined for the underlying * resource * @return whether the request qualifies as not modified, * allowing to abort request processing and relying on the response * telling the client that the content has not been modified */ boolean checkNotModified(long lastModifiedTimestamp);
大意就是注解方式中,一个controller会有多个方法,我们只能给每个@requestMapping的方法进行一次判断,只要传入WebRequest参数,并调用其checkNotModified(lastModified)方法,为true则return null,表示内容没有被更改过,不需要重新查询。这个方法只能是在Get或者Head请求中适用。其中的例子代码如下:
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"; }转载地址:http://aasqi.baihongyu.com/