使用 继承 AbstractController 重写 Spring3MVC 学习笔记 一 内的Controller 处理器/页面控制器
HelloWorldController.java
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; import org.springframework.web.servlet.mvc.Controller; public class HelloWorldController extends AbstractController{ // public ModelAndView handleRequest(HttpServletRequest arg0, // HttpServletResponse arg1) throws Exception { // // //1、收集参数、验证参数 // //2、绑定参数到命令对象 // //3、将命令对象传入业务对象进行业务处理 // //4、选择下一个页面 // ModelAndView mv = new ModelAndView(); // //添加模型数据可以是任意的POJO对象 // mv.addObject("message", "Hello World!"); // //设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面 // mv.setViewName("hello"); // return mv; // // } @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { //1、收集参数、验证参数 //2、绑定参数到命令对象 //3、将命令对象传入业务对象进行业务处理 //4、选择下一个页面 ModelAndView mv = new ModelAndView(); //添加模型数据可以是任意的POJO对象 mv.addObject("message", "Hello World!"); //设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面 mv.setViewName("hello"); return mv; } }
AbstractController 该抽象类实现了Controller,并继承了WebContentGenerator
该类有如下属性:
boolean synchronizeOnSession = false:表示该控制器是否在执行时同步session,从而保证该会话的用户串行访问该控
制器。
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { //委托给WebContentGenerator 进行缓存控制 checkAndPrepare(request, response, this instanceof LastModified); //当前会话是否应串行化访问. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { return handleRequestInternal(request, response); } } } return handleRequestInternal(request, response); }
可以看出AbstractController 实现了一些特殊功能,如继承了WebContentGenerator 缓存控制功能,并提供了可选的会话
的串行化访问功能。而且提供了handleRequestInternal 方法,因此我们应该在具体的控制器类中实现
handleRequestInternal方法,而不再是handleRequest。
WebContentGenerator
用于提供如浏览器缓存控制、是否必须有session 开启、支持的请求方法类型(GET、POST 等)等,该类主要有如下
属性:
Set<String> supportedMethods:设置支持的请求方法类型,默认支持“GET”、“POST”、“HEAD”,如果我们想支持
“PUT”,则可以加入该集合“PUT”。
boolean requireSession = false:是否当前请求必须有session,如果此属性为true,但当前请求没有打开session将抛出
HttpSessionRequiredException异常;
boolean useExpiresHeader = true:是否使用HTTP1.0 协议过期响应头:如果true则会在响应头添加:“Expires:”;需
要配合cacheSeconds 使用;
boolean useCacheControlHeader = true:是否使用HTTP1.1 协议的缓存控制响应头,如果true则会在响应头添加;需
要配合cacheSeconds 使用;
boolean useCacheControlNoStore = true:是否使用HTTP 1.1 协议的缓存控制响应头,如果true则会在响应头添加;需
要配合cacheSeconds 使用;
private int cacheSeconds = -1:缓存过期时间,正数表示需要缓存,负数表示不做任何事情(也就是说保留上次的缓存
设置),
1、cacheSeconds =0 时,则将设置如下响应头数据:
Pragma:no-cache // HTTP 1.0 的不缓存响应头
Expires:1L // useExpiresHeader=true时,HTTP 1.0
Cache-Control :no-cache // useCacheControlHeader=true时,HTTP 1.1
Cache-Control :no-store // useCacheControlNoStore=true时,该设置是防止Firefox 缓存
2、cacheSeconds>0 时,则将设置如下响应头数据:
Expires:System.currentTimeMillis() + cacheSeconds * 1000L // useExpiresHeader=true时,HTTP 1.0
Cache-Control :max-age=cacheSeconds // useCacheControlHeader=true时,HTTP 1.1
3、cacheSeconds<0 时,则什么都不设置,即保留上次的缓存设置。
此处简单说一下以上响应头的作用,缓存控制已超出本书内容:
HTTP1.0缓存控制响应头
Pragma:no-cache:表示防止客户端缓存,需要强制从服务器获取最新的数据;
Expires:HTTP1.0 响应头,本地副本缓存过期时间,如果客户端发现缓存文件没有过期则不发送请求,HTTP 的日
期时间必须是格林威治时间(GMT), 如“Expires:Wed, 14 Mar 2012 09:38:32 GMT”;
HTTP1.1缓存控制响应头
Cache-Control :no-cache 强制客户端每次请求获取服务器的最新版本,不经过本地缓存的副本验证;
Cache-Control :no-store 强制客户端不保存请求的副本,该设置是防止Firefox 缓存
Cache-Control:max-age=[秒] 客户端副本缓存的最长时间,类似于HTTP1.0 的Expires,只是此处是基于请求的
相对时间间隔来计算,而非绝对时间。
还有相关缓存控制机制如Last-Modified(最后修改时间验证,客户端的上一次请求时间在 服务器的最后修改时间之
后,说明服务器数据没有发生变化返回 304 状态码)、ETag(没有变化时不重新下载数据,返回304)。
该抽象类默认被AbstractController 和WebContentInterceptor 继承。