码农小汪-SpringMVC -Controller 接口控制器详解1

来源:互联网 发布:无法登录战网检查网络 编辑:程序博客网 时间:2024/06/05 21:05

Controller 接口控制器详解

Controller 控制器,是 MVC 中的部分 C,为什么是部分呢?因为此处的控制器主要负责功能处理部分

  1. 收集、验证请求参数并绑定到命令对象;
  2. 将命令对象交给业务对象,由业务对象处理并返回模型数据;
  3. 返回ModelAndView(Model部分是业务对象返回的模型数据,视图部分为逻辑视图名)。

还记得DispatcherServlet吗?主要负责整体的控制流程的调度部分:
1. 负责将请求委托给控制器进行处理;
2. 根据控制器返回的逻辑视图名选择具体的视图进行渲染(并把模型数据传入)

因此MVC中完整的C(包含控制逻辑+功能处理)由(DispatcherServlet + Controller)组成。
因此此处的控制器是Web MVC中部分,也可以称为页面控制器、动作、处理器。

spring Web MVC支持多种类型的控制器,比如实现Controller接口,从Spring2.5开始支持注解方式的控制器(如@Controller、@RequestMapping、@RequestParam、@ModelAttribute等),我们也可以自己实现相应的控制器(只需要定义相应的HandlerMapping和HandlerAdapter即可)。

Controller接口

package org.springframework.web.servlet.mvc;public interface Controller {       ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;}

Spring默认提供了一些Controller接口的实现以方便我们使用,具体继承体系

这里写图片描述

http://jinnianshilongnian.iteye.com/blog/1608234
1. WebContentGenerator
用于提供如浏览器缓存控制、是否必须有session开启、支持的请求方法类型(GET、POST等)等,该类主要有
Set< String> supportedMethods:设置支持的请求方法类型,默认支持“GET”、“POST”、“HEAD”,如果我们想支持“PUT”,则可以加入该集合“PUT”。
private int cacheSeconds = -1:缓存过期时间,正数表示需要缓存,负数表示不做任何事情(也就是说保留上次的缓存设置),
2. 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。

AbstractController使用方法:

public class HelloWorldController extends AbstractController {    @Override    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {        //1、收集参数        //2、绑定参数到命令对象        //3、调用业务对象        //4、选择下一个页面        ModelAndView mv = new ModelAndView();        //添加模型数据 可以是任意的POJO对象        mv.addObject("message", "Hello World!");        //设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面        mv.setViewName("hello");        return mv;    }}

直接通过response写响应

如果我们想直接在控制器通过response写出响应呢,以下代码帮我们阐述:

public class HelloWorldWithoutReturnModelAndViewController extends AbstractController {    @Override    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {        resp.getWriter().write("Hello World!!");                //如果想直接在该处理器/控制器写响应 可以通过返回null告诉DispatcherServlet自己已经写出响应了,不需要它进行视图解析        return null;    }}

<!— 在chapter4-servlet.xml配置处理器 --><bean name="/helloWithPOST" class="cn.javass.chapter4.web.controller.HelloWorldController">        <property name="supportedMethods" value="POST"></property></bean>

当前请求的session前置条件检查,如果当前请求无session将抛出HttpSessionRequiredException异常:

<!— 在chapter4-servlet.xml配置处理器 --><bean name="/helloRequireSession"class="cn.javass.chapter4.web.controller.HelloWorldController">        <property name="requireSession" value="true"/></bean>
0 0
原创粉丝点击