1 Spring MVC概述
1.1 概述
Spring MVC是Spring提供的一个强大而灵活的web框架。借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单。这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中。
Spring MVC主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成。他的两个核心是两个核心:
处理器映射:选择使用哪个控制器来处理请求
视图解析器:选择结果应该如何渲染
通过以上两点,Spring MVC保证了如何选择控制处理请求和如何选择视图展现输出之间的松耦合。
1.2 SpringMVC运行原理
![](https://i-blog.csdnimg.cn/blog_migrate/6db47f5d9a454ddfe445b48728acc650.png)
(1) Http请求:客户端请求提交到DispatcherServlet。
(2)寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。
(3)调用处理器:DispatcherServlet将请求提交到Controller。
(4)(5)调用业务处理和返回结果:Controller调用业务逻辑处理后,返回ModelAndView。
(6)(7)处理视图映射并返回模型:DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
(8) Http响应:视图负责将结果显示到客户端。
1.3 SpringMVC接口解释
(1)DispatcherServlet接口:
Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给SpringController之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
(2)HandlerMapping接口:
能够完成客户请求到Controller映射。
(3)Controller接口:
需要为并发用户处理上述请求,因此实现Controller接口时,必须保证线程安全并且可重用。Controller将处理用户请求,这和Struts Action扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。
从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观考虑,Controller是单个Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。
(4)ViewResolver接口:
Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。
1.4 DispatcherServlet:
是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项:
(1)截获符合特定格式的URL请求。
(2)初始化DispatcherServlet上下文对应WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
(3)初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。
1.5 SpringMVC配置
1.5.1 项目整体结构
![](https://i-blog.csdnimg.cn/blog_migrate/20b394825650e60baacbcd21fe7775ab.png)
1.5.2 web.xml
(1)在web.xml文件中进行配置,在配置中设置springmvc-context.xml的路径,代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/eb147aa4b159db69ca23a1a1881b680a.png)
1.5.3 springmvc-context.xml配置bean对象
(2)配置springmvc-context.xml文件,这一部分主要是开启注解功能、配置试图解析器,代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/05d751653c88f033a064599d9ce8f03d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f2e744ace99b7dc8f542fb7e468f11d9.png)
1.5.4 jsp页面
(3)配置文件完成了,下面开始写代码,
两个jsp界面:
create.jsp
![](https://i-blog.csdnimg.cn/blog_migrate/518ce61f60d1454dfa339c7a1dc06471.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e4394f121a331b517df87d1bc71fde82.png)
detail.jsp
![](https://i-blog.csdnimg.cn/blog_migrate/3001b3233679b819e7222c4b4218bfc3.png)
1.5.5 Controller层
UserController.Java
packagecom.zjn.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zjn.entity.User;
/**
*用户管理
* @authorzjn
*/
@Controller
public class UserController{
@RequestMapping("")
publicString Create(Model model) {
return "create";
}
@RequestMapping("/save")
public String Save(@ModelAttribute("form") User user,Model model) {
// user:视图层传给控制层的表单对象;model:控制层返回给视图层的对象
model.addAttribute("user", user);
return "detail";
}
}
1.5.6 数据实体层
User.java
packagecom.zjn.entity;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
/**
* @authorzjn
*/
private static final long serialVersionUID = 1L;
private Integer id; // id
private String name; // name
private String pwd; // pwd
private Integer age; // age
private Date creatTime; // creatTime
publicInteger getId() {
returnid;
}
public voidsetId(Integer id) {
this.id = id;
}
publicString getName() {
returnname;
}
public voidsetName(String name) {
this.name = name;
}
publicString getPwd() {
returnpwd;
}
public voidsetPwd(String pwd) {
this.pwd = pwd;
}
publicInteger getAge() {
returnage;
}
public voidsetAge(Integer age) {
this.age = age;
}
publicDate getCreatTime() {
returncreatTime;
}
public voidsetCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
}
1.5.7 运行结果
初始页面:
![](https://i-blog.csdnimg.cn/blog_migrate/3ff0bb946237979ed30ff8682d388e96.png)
输入参数:
![](https://i-blog.csdnimg.cn/blog_migrate/bb819338874be1a876e28585024107d5.png)
点击创建:
![](https://i-blog.csdnimg.cn/blog_migrate/3f8943f67d4e9ad9aaac76f3434561ff.png)
源码下载地址: SpringMVC项目源码下载
2 配置说明
2.1 spring-mvc.xml配置说明
2.1.1 节点说明
1.自动扫描
![](https://i-blog.csdnimg.cn/blog_migrate/410712e7dbaa4057a407ca834b46d0ef.png)
2.注解驱动
![](https://i-blog.csdnimg.cn/blog_migrate/99aa336537bd14786a9a307b52442d87.png)
3.静态资源处理
![](https://i-blog.csdnimg.cn/blog_migrate/b170c6fbfc45aba3b4f8ce843db74b1c.png)
4.避免IE执行AJAX时,返回JSON出现下载文件
![](https://i-blog.csdnimg.cn/blog_migrate/c446f3c65f42cc2d9b3bd11a7ef12683.png)
5.启动SpringMVC的注解功能,完成请求和注解POJO的映射
![](https://i-blog.csdnimg.cn/blog_migrate/2d6f9a7015d9bf18ade84bc63e1ce2a4.png)
6.配置文件上传
![](https://i-blog.csdnimg.cn/blog_migrate/8c39d9f493401c1af45def303e0c8d72.png)
7.配置viewResolver
![](https://i-blog.csdnimg.cn/blog_migrate/89f8200b8997eb3e1afc365182f89395.png)
8.定义跳转的文件的前后缀 ,视图模式配置
![](https://i-blog.csdnimg.cn/blog_migrate/14da043927fd39d49ca9679bca63d644.png)
9.destroy-method="close"的作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
2.1.2 context:component-scan
在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的Java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean。
注意:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。
范例:
![](https://i-blog.csdnimg.cn/blog_migrate/fbb8bb913dc4e509b48772799d67c035.png)
<context:component-scan>提供兩個子标签:<context:include-filter>和<context:exclude-filter>各代表引入和排除的過濾。而上例把use-default-filters屬性設為false,意即在base-package所有被宣告為@Component和@Configuration等target Class不予注册为bean,由filter子标签代替。
filter標籤在Spring3有五個type,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8ee42620ba310aa146e3b5bc54d8ad20.png)
所以上例用的regex就有個語病,com.foo.config.*可以找到com.foo.config.WebLogger,但也可以找到com1fool2config3abcde,因為小數點在Regex是任意字元,是故要用\.把小數點跳脫為佳。(2010/3/15補充:但要使用\.方式,其use-default-filters不能為false,否則抓不到,感覺是Bug)
Spring3提供豐富的Filter支援,有益配置策略,不需面臨ConfigurationHell,比如Regex的com\.foo\.*\.action\.*Config,這樣就可以找到com.foo package下所有action子package的*Config的targetclass。
2.1.3 mvc:interceptors
这个标签用于注册一个自定义拦截器或者是WebRequestInterceptors。可以通过定义URL来进行路径请求拦截,可以做到较为细粒度的拦截控制。
例如在配置文件加入
![](https://i-blog.csdnimg.cn/blog_migrate/a16e7fdc18620724f1371a2e78c66af3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/020f15de6cdf7396b62494aace6078ac.png)
2.1.4 mvc:annotation-driven
<mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案。 <mvc:annotation-driven />会自动注册DefaultAnnotationHandlerMapping 与 AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
并提供数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
DefaultAnnotationHandlerMapping是HandlerMapping的实现类,它会处理@RequestMapping 注解,并将其注册到请求映射表中。(下片文章我们会详细介绍的)
AnnotationMethodHandlerAdapter是HandlerAdapter的实现类,它是处理请求的适配器,说白了,就是确定调用哪个类的哪个方法,并且构造方法参数,返回值。
![](https://i-blog.csdnimg.cn/blog_migrate/0dfa608313f66fbb3243d7e19de207bf.png)
当我们需要controller返回一个map的json对象时,可以设定<mvc:annotation-driven />,同时设定标签,设定字符集和json处理类,例如:
![](https://i-blog.csdnimg.cn/blog_migrate/01d8eef64b90af584403f7f08818f2ec.png)
3 参考链接
Spring MVC入门指南(二):@RequestMapping用法详解
https://my.oschina.net/kolbe/blog/509810
Spring MVC之@RequestMapping详解
http://blog.csdn.net/kobejayandy/article/details/12690041
SpringMVC与Struts2的对比
http://blog.csdn.net/gstormspire/article/details/8239182/
(Good)深入理解Spring MVC 思想
http://www.cnblogs.com/zhangxingBlob/p/6364728.html
http://www.cnblogs.com/superjt/p/3309255.html
Spring3中的mvc:interceptors标签配置拦截器
<mvc:annotation-driven />注解详解
http://www.cnblogs.com/shuo1208/p/5552134.html
(Good)SpringMVC解读——<mvc:annotation-driven/>
https://my.oschina.net/HeliosFly/blog/205343
Spring MVC解读——<context:component-scan/>
https://my.oschina.net/HeliosFly/blog/203149
spring组件扫描使用详解
http://blog.sina.com.cn/s/blog_57769b7b0100tt5x.html
<context:component-scan>使用说明
http://blog.csdn.net/chunqiuwei/article/details/16115135
Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
过滤器(Filter)和拦截器(Interceptor)的区别
http://www.cnblogs.com/luoyun/archive/2013/01/04/2844274.html
最新Spring 4.2.2集成Quartz Scheduler 2.2.2任务调度示例
Spring+Quartz实现定时任务的配置方法
https://www.oschina.net/question/8676_9032
Quartz学习——Spring和Quartz集成详解(三)
Spring MVC通过@Value注解读取.properties配置