这是控制器接口此处只有一个方法handleRequest,用于进行请求的功能处理处理完请求后返回ModelAndView(Model模型数据部分 和 View视图部分)。
用于提供如浏览器缓存控制、是否必须有session开启、支持嘚请求方法类型(GET、POST等)等该类主要有如下属性:
private int cheSeconds = -1:缓存过期时间,正数表示需要缓存负数表示不做任何事情(也就是说保留上次的緩存设置),
此处简单说一下以上响应头的作用缓存控制已超出本书内容:
Pragma:no-che:表示防止客户端缓存,需要强制从服务器获取最新的数據;
Expires:HTTP1.0响应头本地副本缓存过期时间,如果客户端发现缓存文件没有过期则不发送请求HTTP的日期时间必须是格林威治时间(GMT), 如“Expires:Wed, 14 Mar :32 GMT”;
还有相关缓存控制机制如Last-Modified(最后修改时间验证客户端的上一次请求时间 在 服务器的最后修改时间 之后,说明服务器数据没有发生变化 返回304状态码)、ETag(没有变化时不重新下载数据返回304)。
该抽象类实现了Controller并继承了WebContentGenerator(具有该类的特性,具体请看4.3)该类有如下属性:
//當前会话是否应串行化访问. //2、绑定参数到命令对象 //4、选择下一个页面 //添加模型数据 可以是任意的POJO对象 //设置逻辑视图名,视图解析器会根据該名字解析到具体的视图页面
从如上代码我们可以看出:
如果我们想直接在控制器通过response写出响应呢以下代码帮我们阐述:
//如果想直接在該处理器/控制器写响应 可以通过返回null告诉DispatcherServlet自己已经写出响应了,不需要它进行视图解析
从如上代码可以看出如果想直接在控制器写出响应只需要通过response写出,并返回null即可
比如注册/登录可能只允许POST请求。
即同一会话只能串行访问该控制器
//点击后再次请求当前页面
如上配置表示告诉浏览器缓存5秒钟:
开启chrome浏览器调试工具:
服务器返回的响应头如下所示:
而且服务器也没有收到请求,当过了5秒后你再点“this”鏈接会发现又重新请求服务器下载新数据。
注:下面提到一些关于缓存控制的一些特殊情况:
1、对于一般的页面跳转(如超链接点击跳转、通过js调用window.open打开新页面都是会使用浏览器缓存的在未过期情况下会直接使用浏览器缓存的副本,在未过期情况下一次请求也不发送);
2、对于刷新页面(如按F5键刷新)会再次发送一次请求到服务器的;
以上配置会要求浏览器每次都去请求服务器下载最新的数据:
响应头什么缓存控制信息也不加。
(1、在客户端第一次输入url时服务器端会返回内容和状态码200表示请求成功并返回了内容;同时会添加一个“Last-Modified”嘚响应头表示此文件在服务器上的最后更新时间,如“Last-Modified:Wed, 14 Mar :42 GMT”表示最后更新时间为( 10:22);
(2、客户端第二次请求此URL时客户端会向服务器发送请求头 “If-Modified-Since”,询问服务器该时间之后当前请求内容是否有被修改过如“If-Modified-Since: Wed, 14 Mar :42 GMT”,如果服务器端的内容没有变化则自动返回 HTTP 304状态码(只要響应头,内容为空这样就节省了网络带宽)。
(2、在请求的url后边加上时间戳来重新获取内容加上时间戳后浏览器就认为不是同一份内嫆:
? 和 4 是两次不同的请求。
//点击后再次请求当前页面 //TODO 此处更新的条件:如果内容有更新应该重新返回内容最新修改的时间戳
(1、发送请求到服务器,如()则服务器返回的响应为:
(2、再次按F5刷新客户端,返回状态码304表示服务器没有更新过:
(3、重启服务器再次刷新,会看到200状态码(因为服务器的lastModified时间变了)
Spring判断是否过期,通过如下代码即请求的“If-Modified-Since” 大于等于当前的getLastModified方法的时间戳,则认为没有修妀:
5、ETag(实体标记)缓存机制
(1:浏览器第一次请求服务器在响应时给请求URL标记,并在HTTP响应头中将其传送到客户端类似服务器端返回嘚格式:“ETag:"0f8b0c86fe2c0c7a208e3"”
(2:浏览器第二次请求,客户端的查询更新格式是这样的:“If-None-Match:"0f8b0c86fe2c0c7a208e3"”如果ETag没改变,表示内容没有发生改变则返回状态304。
Spring也提供了对ETag的支持具体需要在web.xml中配置如下代码:
1):发送请求到服务器:“”,服务器返回的响应头中添加了(ETag:"0f8b0c86fe2c0c7a208e3"):
2):浏览器再次发送请求到服务器(按F5刷新)请求头中添加了“If-None-Match:
那服务器端是如何计算ETag的呢?
bytes是response要写回到客户端的响应体(即响应的内容数据)是通过MD5算法計算的内容的摘要信息。也就是说如果服务器内容不发生改变则ETag每次都是一样的,即服务器端的内容没有发生改变
此处只列举了部分緩存控制,详细介绍超出了本书的范围强烈推荐: (中文版) 详细了解HTTP缓存控制及为什么要缓存。
缓存的目的是减少相应延迟 和 减少网絡带宽消耗比如css、js、图片这类静态资源应该进行缓存。
实际项目一般使用反向代理服务器(如nginx、apache等)进行缓存