标签:
导入SpringMVC只需要加入jar包就行了。
<!-- 配置 SpringMVC 的 DispatcherServlet --><servlet><servlet-name>springDispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!-- Map all requests to the DispatcherServlet for handling --><servlet-mapping><servlet-name>springDispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
<!-- 配置自动扫描的包 --><context:component-scan base-package="com.atguigu.springmvc"></context:component-scan>
<!-- 配置视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"></property><property name="suffix" value=".jsp"></property></bean>有多种视图解析器: 待补
不管目标方法返回的是什么类型是String、ModelAndView还是View都,SpringMVC都会把它转换为ModelAndView类型,然后通过视图解析器得到真正的物理视图,一个View对象,然后调用renderview得到响应结果。InternalResourceViewResolver是支持InternalResourceView的视图解析器
InternalResourceViewResolver? JSP 是最常见的视图技术,可以使用InternalResourceViewResolver 作为视图解析器:

@Componentpublic class HelloView implements View{@Overridepublic String getContentType() {return "text/html";}@Overridepublic void render(Map<String, ?> model, HttpServletRequest request,HttpServletResponse response) throws Exception {response.getWriter().print("hello view, time: " + new Date());}}
<!-- 配置视图 BeanNameViewResolver 解析器: 使用视图的名字来解析视图 --><!-- 通过 order 属性来定义视图解析器的优先级, order 值越小优先级越高 --><bean class="org.springframework.web.servlet.view.BeanNameViewResolver"><property name="order" value="100"></property></bean>
@RequestMapping("/testView")public String testView(){System.out.println("testView");return "helloView";}
default-servlet-handler 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求, 就将该请求交由 WEB 应用服务器默认的Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理- 一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>这个一般都是必加的。他的加入可以防止RequestMapping不会失效
? <mvc:annotation-driven /> 会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter 与ExceptionHandlerExceptionResolver 三个bean。? 还将提供以下支持:– 支持使用 ConversionService 实例对表单参数进行类型转换– 支持使用 @NumberFormat annotation、@DateTimeFormat注解完成数据类型的格式化– 支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证– 支持使用 @RequestBody 和 @ResponseBody 注解

@RequestMapping("/delete/{id}")public String delete(@PathVariable("id") Interger id){...}
– value:参数名
– required:是否必须。默认为 true, 表示请求参数中必须包含对应
的参数,若不存在,将抛出异常
@RequestMapping("/xxx")public String delete(@RequestParam(value="userName",required=false) String userName,@RequestParam("age") int age){...}
public String handle(@CookieValue(value="sessionId",required=false) StringsessionID)
控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息。
Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。– 如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传- 递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数
据,也可以向模型中添加新的属性数据.
在方法定义上使用 @ModelAttribute 注解:Spring MVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法
/*** 运行流程:* 1. 执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象, 把对象放入到了 Map 中. 键为: user* 2. SpringMVC 从 Map 中取出 User 对象, 并把表单的请求参数赋给该 User 对象的对应属性.* 3. SpringMVC 把上述对象传入目标方法的参数.** 注意: 在 @ModelAttribute 修饰的方法中, 放入到 Map 时的键需要和目标方法入参类型的第一个字母小写的字符串一致!** SpringMVC 确定目标方法 POJO 类型入参的过程* 1. 确定一个 key:* 1). 若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写* 2). 若使用了 @ModelAttribute 来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值.* 2. 在 implicitModel 中查找 key 对应的对象, 若存在, 则作为入参传入* 1). 若在 @ModelAttribute 标记的方法中在 Map 中保存过, 且 key 和 1 确定的 key 一致, 则会获取到.* 3. 若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰,* 若使用了该注解, 且 @SessionAttributes 注解的 value 属性值中包含了 key, 则会从 HttpSession 中来获取 key 所* 对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常.* 4. 若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则* 会通过反射来创建 POJO 类型的参数, 传入为目标方法的参数* 5. SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中.** 源代码分析的流程* 1. 调用 @ModelAttribute 注解修饰的方法. 实际上把 @ModelAttribute 方法中 Map 中的数据放在了 implicitModel 中.* 2. 解析请求处理器的目标参数, 实际上该目标参数来自于 WebDataBinder 对象的 target 属性* 1). 创建 WebDataBinder 对象:* ①. 确定 objectName 属性: 若传入的 attrName 属性值为 "", 则 objectName 为类名第一个字母小写.* *注意: attrName. 若目标方法的 POJO 属性使用了 @ModelAttribute 来修饰, 则 attrName 值即为 @ModelAttribute* 的 value 属性值** ②. 确定 target 属性:* > 在 implicitModel 中查找 attrName 对应的属性值. 若存在, ok* > *若不存在: 则验证当前 Handler 是否使用了 @SessionAttributes 进行修饰, 若使用了, 则尝试从 Session 中* 获取 attrName 所对应的属性值. 若 session 中没有对应的属性值, 则抛出了异常.* > 若 Handler 没有使用 @SessionAttributes 进行修饰, 或 @SessionAttributes 中没有使用 value 值指定的 key* 和 attrName 相匹配, 则通过反射创建了 POJO 对象** 2). SpringMVC 把表单的请求参数赋给了 WebDataBinder 的 target 对应的属性.* 3). *SpringMVC 会把 WebDataBinder 的 attrName 和 target 给到 implicitModel.* 近而传到 request 域对象中.* 4). 把 WebDataBinder 的 target 作为参数传递给目标方法的入参.*/
/*** @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值),* 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值)** 注意: 该注解只能放在类的上面. 而不能修饰放方法.*/
? 1. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象? 2. DataBinder 调用装配在 Spring MVC 上下文中的ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中? 3. 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData 对象? 4. Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参其运行流程如下图所示:

<mvc:annotation-driven/> 默认创建的ConversionService 实例即为FormattingConversionServiceFactroyBean? FormattingConversionServiceFactroyBean 内部已经注册了 :– NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性使用 @NumberFormat 注解– JodaDateTimeFormatAnnotationFormatterFactroy:支持对日期类型的属性使用 @DateTimeFormat 注解
@DateTimeFormat(pattern="yyyy/MM/dd")private Date birthday;@NumberFormat(pattern="#,###.##")
? 由 @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定? @InitBinder方法不能有返回值,它必须声明为void。? @InitBinder方法的参数通常是是 WebDataBinder
@InitBinderpublic void initBinder(WebDataBinder dataBinder){dataBinder.setDisallowedFields("xxx");}

如图所示,通俗的讲,就是将输入流变成java对象,把java对象变成输出流。
@ResponseBody@RequestMapping("/testHttpMessageConverter")public String testHttpMessageConverter(@RequestBody String body){System.out.println(body);return "helloworld! " + new Date();}
<mvc:interceptors><!-- 配置自定义的拦截器 --><bean class="com.atguigu.springmvc.interceptors.FirstInterceptor"></bean><!-- 配置拦截器(不)作用的路径 --><mvc:interceptor><mvc:mapping path="/emps"/><bean class="com.atguigu.springmvc.interceptors.SecondInterceptor"></bean></mvc:interceptor></mvc:interceptors>
/*** 该方法在目标方法之前被调用.* 若返回值为 true, 则继续调用后续的拦截器和目标方法.* 若返回值为 false, 则不会再调用后续的拦截器和目标方法.** 可以考虑做权限. 日志, 事务等.*/@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {System.out.println("[FirstInterceptor] preHandle");return true;}
/*** 调用目标方法之后, 但渲染视图之前.* 可以对请求域中的属性或视图做出修改.*/@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {System.out.println("[FirstInterceptor] postHandle");}
/*** 渲染视图之后被调用. 释放资源*/@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {System.out.println("[FirstInterceptor] afterCompletion");}

Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。其有几个实现类,常见的如下:
ExceptionHandlerExceptionResolverResponseStatusExceptionResolverDefaultHandlerExceptionResolver
ExceptionHandlerExceptionResolver :
/*** 1. 在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象* 2. @ExceptionHandler 方法的入参中不能传入 Map. 若希望把异常信息传导页面上, 需要使用 ModelAndView 作为返回值* 3. @ExceptionHandler 方法标记的异常有优先级的问题.* 4. @ControllerAdvice: 如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常,* 则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常.*/@ExceptionHandler({ArithmeticException.class})public ModelAndView handleArithmeticException(Exception ex){System.out.println("出异常了: " + ex);ModelAndView mv = new ModelAndView("error");mv.addObject("exception", ex);return mv;}
@ControllerAdvicepublic class SpringMVCTestExceptionHandler {@ExceptionHandler({ArithmeticException.class})public ModelAndView handleArithmeticException(Exception ex){...}}
其余略:可翻看佟刚的SpringMVC的PPT。

HandlerExecutionChain:里面包含了handler的目标方法和拦截器通过HandlerMapping获取。HandlerMapping定义了请求到处理器的映射。HandlerAdapter处理请求到目标方法中很多的处理在里面操作。
标签:
原文地址:http://www.cnblogs.com/You0/p/5843789.html