1.主流的mvc构架包括:
struts1, webwork, strut2, spring mvc, jsf
2.spring MVC特点:
@ 功能组件划分细致
@ 灵活、强大
@ 设计思想优秀
3.spring mvc的作用:
@、以Controller为中心完成对系统流程的控制管理
@、从请求中收集数据
@、对传入参数进行验证
@、根据请求调用相应业务逻辑完成数据处理
@、将处理结果返回给视图
@、国际化支持
@、针对不同视图技术提供不同解析支持方案
@、针对JSP视图技术提供标签库
@、通过拦截器链实现面向方面编程完成系统级控制
@、对文件上传、下载等常用功能的封装
4.Spring MVC框架的核心构件
Dispatcher Servlet (分发器、调度器)
Controller (控制器)
Handler Mapping (映射器)
ViewResolver & View (视图解析器及视图处理类)
Interceptors (拦截器)
LocalResolver
Validate
5.spring MVC示例1
spring-framework下载
Latest GA release: 3.0.1.RELEASE-A
133.3 MB | ||
45.3 MB | ||
21.8 MB |
加Jar包
下载spring 的jar包,包括:spring 本身之外还要下载: spring framework dependencies.zip 它所依赖的一些包。
首先新建一个个名为spring_mvc_test的web project,先导入以下几个包:
(找不到的jar包可以到jarvana去找)
springframework.beans-3.1.0.RELEASE.jar
springframework.context-3.1.0.RELEASE.jar
springframework.context.support-3.1.0.RELEASE.jar
springframework.core-3.1.0.RELEASE.jar
springframework.web.servlet-3.1.0.RELEASE.jar
<servlet-name>test</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup> <!-- 在项目启动时就加载 -->
<servlet-name>test</servlet-name>
<url-pattern>*.test</url-pattern> <!-- 获得所有以 .test的请求,即管理所有以 .test的请求 -->
1.它是一个大的对象工厂,这是整个spring最核心、最基本的功能。spring mvc的核心功能,表现在在依赖注入。
2.dispatcher servlet在被初始化的时候,就会读取配置文件中的各个bean,完成对各个类型、各个构件的初始化过程。
3.如查没有指定dispatcher(调度器)读取哪一个配置文件,dispatcher会默认读取/WEB-INF/[servlet-name]-servlet.xml配置文件。
4.建一个名为StartController的java文件,再在WEB-INF/目录下建一个test-servlet.xml的配置文件。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
* @className:StartController.java
* @createTime:2012-2-12下午09:21:58
public class StartController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("start controller is working !");
return new ModelAndView("start"); //只指定一个视图的逻辑名称叫start
//使用控制器与视图名称完全分离,只返回一个名称叫start的视图,具体返回什么视图由后续配置决定。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="startController" class="test.StartController"></bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<prop key="start.test">startController</prop><!-- key是url,text是控制器的名称 -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"/><!-- 返回的逻辑名称的前缀 -->
<property name="suffix" value=".jsp"/><!-- 返回的逻辑名称的后缀 -->
发布到tomcat启动,根据错误提示,添加缺少的对应的Jar包,有如下:
org.springframework.web-3.1.0.RELEASE.jar
org.springframework.asm-3.1.0.RELEASE.jar
org.springframework.expression-3.1.0.RELEASE.jar
This is my start jsp page. <br>
@、直接实现Controller 接口或AbstractController抽象类
ParameterizableViewController, UrlFilenameViewController
@、在同一控制器类中处理多个请求的MultiActionController.具体调用的方法通过MethodNameResolver决定
(InternalPathMethodResolver, ParameterMethodNameResolver, PropertiesMethodResolver)
@、能封装表单参数的CommondController、 FormController
如果一个控制器实现了CommandContrller 或FormController,那么它就可以直接接收一个表单对象。
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.ui.Model;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;
import org.springframework.web.servlet.mvc.AbstractController;
* @className:EmpController.java
/*public class EmpController extends AbstractController { //实现简单的Controller抽象类
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception { //
String name=request.getParameter("name");
String phone=request.getParameter("phone");
public class EmpController extends AbstractCommandController{
protected ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
System.out.println(emp.toString());
return new ModelAndView("success");
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd"), true));
import java.text.SimpleDateFormat;
public void setEmpNo(int empNo) {
public void setName(String name) {
public void setPhone(String phone) {
public void setHireDate(Date hireDate) {
public void setDept(String dept) {
return "Emp [empNo="+empNo+",name=" + name + ", phone=" + phone
+ ",hireDate="+new SimpleDateFormat("yyyy-MM-dd").format(hireDate)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<prop key="start.test">startController</prop><!-- key是url,text是控制器的名称 -->
<prop key="login.test">loginController</prop>
<prop key="add_emp.test">addEmpController</prop>
<prop key="add.test">addEmpSuccController</prop>
<bean id="startController" class="test.StartController"></bean>
<!-- 给loginController配置一个参数化的视图控制器类 --><!---
<property name="viewName" value="login"></property> --><!-- 返回一个名称叫login的视图 -->
<!-- 给loginController配置一个按url文件名决定的一个控制器,这样可以省去配置视图名的过程 -->
<bean id="loginController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
<!-- 一个url对应一个controller的情况 -->
<bean id="addEmpController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
<bean id="addEmpSuccController" class="test.EmpController">
<property name="commandClass" value="test.Emp"></property> <!-- 指定command对象的类别 -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"/><!-- 返回的逻辑名秼/span>
import java.beans.PropertyEditorSupport;
* @classDescription:自定义一个属性编辑器
public class MyEditor extends PropertyEditorSupport {
// TODO Auto-generated method stub
public void setValue(Object value) {
// TODO Auto-generated method stub
public void setAsText(String text) throws IllegalArgumentException {
// TODO Auto-generated method stub
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
* @className:EmpFormController.java
* @createTime:2012-2-13上午02:41:45
public class EmpFormController extends SimpleFormController {
protected ModelAndView onSubmit(Object command) throws Exception {
Emp emp=(Emp)command; //注意,直接将command对象转换成Emp对象即可
System.out.println(emp.toString());
return new ModelAndView(getSuccessView());
protected Map referenceData(HttpServletRequest request) throws Exception {
Map<String,Object> model=new HashMap<String,Object>(); //建立一个模型
model.put("deptList", new String[]{"sales","manage"}); //向模型中放入一个列表
return model; //返回加入了deptList的模型
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd"), true));
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<prop key="start.test">startController</prop><!-- key是url,text是控制器的名称 -->
<prop key="login.test">loginController</prop>
<prop key="add_emp.test">addEmpController</prop>
<!-- <prop key="add.test">addEmpSuccController</prop> -->
<bean id="startController" class="test.StartController"></bean>
<!-- 给loginController配置一个按url文件名决定的一个控制器,这样可以省去配置视图名的过程 -->
<bean id="loginController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
<!-- 表单控制器,使用一个controller对应多个url处理 -->
<bean id="addEmpController" class="test.EmpFormController">
<property name="commandClass" value="test.Emp"/><!-- 它也需要command对象是什么类别 -->
<property name="formView" value="add_emp"/><!-- 表单提交页面 -->
<property name="successView" value="success"/><!-- 表单成功页面 -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"/><!-- 返回的逻辑名称的前缀 -->
<property name="suffix" value=".jsp"/><!-- 返回的逻辑名称的后缀 -->
1.如果没有指定视图名称,那么spring mvc 它会按默认的方式来指定视图名称。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
* @className:EmpMultiController.java
public class EmpMultiController extends MultiActionController {
private ModelAndView toAdd() {
//ModelAndView mav=new ModelAndView("add_emp");
//ModelAndView mav=new ModelAndView();
//mav.addObject(attributeValue);
//mav.addAllObjects(modelMap);
ModelAndView mav = new ModelAndView();
mav.addObject("deptList",new String[]{"salse","manage"});
//public ModelAndView addEmp(HttpServletRequest request,
public String addEmp(HttpServletRequest request,
HttpServletResponse response,HttpSession session,Emp emp){
//return new ModelAndView("success");
return "success"; //直接返回一个字符串,就是viewName
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<prop key="start.test">startController</prop><!-- key是url,text是控制器的名称 -->
<prop key="login.test">loginController</prop>
<prop key="to_add.test">addEmpController</prop>
<prop key="add_emp.test">addEmpController</prop>
<!-- <prop key="add.test">addEmpSuccController</prop> -->
<bean id="startController" class="test.StartController"></bean>
<bean id="addEmpController" class="test.EmpMultiController">
<property name="commandClass" value="test.Emp"/>
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="func"></property> <!-- 此参数决定调用哪一个方法名 -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"/><!-- 返回的逻辑名称的前缀 -->
<property name="suffix" value=".jsp"/><!-- 返回的逻辑名称的后缀 -->
@、默认的ControllerClassNameHandlerMapping
按照控制器的类名来自动完成映射,在这需要使用拦截器的时候,它不需要配置任何属性。如下:
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
当发送一个以 abc.test 结尾的请求时,它会找一个名称为AbcController,直接根据控制器的类名匹配请求的路径来寻找控制器。
@、基于注解Controller时使用的DefaultAnnotationHandlerMapping
5. controller类可以不定义requestMapping,但一个要请求路径的方法,就必须定义requestMapping。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd" >
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd" >
<context:component-scan base-package="test.controller" ></context:component-scan>
<!-- 定义一个视图解析类,基于ResourceView的解析器 ,此解析器是在url解析器上,加入了对jstl的支持-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
* @className:TestController.java
@RequestMapping("/test") //类的映射路径
@RequestMapping("/start") //映射到start方法
public String start(HttpServletRequest request,HttpServletResponse response){
String nameString=request.getParameter("name");
System.out.println("name="+nameString);
//http://localhost:8080/@mvc/test/start.do?name=zhangsan
//http://localhost:8080/@mvc/test/start.do?name=lisi
//http://localhost:8080/@mvc/test/start/zhangsan.do
//http://localhost:8080/@mvc/test/start/lisi.do
@RequestMapping("/start2/{name}/{age}") //name为url模板中取出的路径变量
public String start2(@PathVariable String name,@PathVariable("age") String age,
/*如果采用release模式,则需要定义为 @PathVariable("name") String name
HttpServletRequest request,HttpServletResponse response){
System.out.println("name="+name+" age="+age);
//http://localhost:8080/@mvc/test/start2/zhangsan/20.do
@RequestMapping(value="/start3",method=RequestMethod.POST) //映射到start方法
public String start_post(HttpServletRequest request,HttpServletResponse response){
System.out.println("RequestMethod.POST");
@RequestMapping(value="/start3",method=RequestMethod.GET)
public String start_get(HttpServletRequest request,HttpServletResponse respose){
System.out.println("RequestMethod.GET");
<h1>This is start JSP page. </h1><br>
<form name="form2" action="test/start3.do" method="get">
<form name="form2" action="test/start3.do" method="post">
<h1>This is start_get JSP page. </h1><br>
<h1>This is start_post JSP page. </h1><br>
@、@RequestParam, @PathVariable, @CookieValue
spring MVC 常用ViewResoler & View
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.WebRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
* @className:TestController.java
@RequestMapping("/test") //类的映射路径
public class TestController<AnyType> {
@RequestMapping("/start") //映射到start方法
public String start(HttpServletRequest request,HttpServletResponse response){
String nameString=request.getParameter("name");
System.out.println("name="+nameString);
//http://localhost:8080/@mvc/test/start.do?name=zhangsan
//http://localhost:8080/@mvc/test/start.do?name=lisi
//http://localhost:8080/@mvc/test/start/zhangsan.do
//http://localhost:8080/@mvc/test/start/lisi.do
@RequestMapping("/start2/{name}/{age}") //name为url模板中取出的路径变量
public String start2(@PathVariable String name,@PathVariable("age") String age,
/*如果采用release模式,则需要定义为 @PathVariable("name") String name
HttpServletRequest request,HttpServletResponse response){
System.out.println("name="+name+" age="+age);
//http://localhost:8080/@mvc/test/start2/zhangsan/20.do
@RequestMapping(value="/start3",method=RequestMethod.POST) //映射到start方法
public String start_post(HttpServletRequest request,HttpServletResponse response){
System.out.println("RequestMethod.POST");
@RequestMapping(value="/start3",method=RequestMethod.GET)
public String start_get(HttpServletRequest request,HttpServletResponse respose){
System.out.println("RequestMethod.GET");
@RequestMapping(value="/{test}",method=RequestMethod.GET)
public void testPathVariable(@PathVariable("test") Date test){
public void initBinder(WebRequestDataBinder binder){
binder.registerCustomEditor(Date.class,new CustomDateEditor(
new SimpleDateFormat("yyyyMMdd"),false));
//session前提条件,当前请求session可用,request.getSession(),session.setAttribute();
public void testAllArguments(HttpServletRequest request,HttpServletResponse response,
HttpSession session,@PathVariable AnyType xxx,@PathVariable AnyType id,
@CookieValue("user-Agent") AnyType cookieName){
public String testAllArguments(PrintWriter out,Map model){
public String testCommand(User user,BindingResult result){
//会生成一个隐含的viewName -- 按请求路径,如果请求是xxx.do 则返回的视图为 xxx.jsp
//${appName }/test/xxx.do --> test/xxx --> /WEB-INF/page/test/xxx.jsp
public User testuser(){ //model("user",user)
//除了可以单独返回一个User对象,我们也可以返回一个List对象
public List<User> testuser2(){
//model("userList",user) request.getAttribute("userList");
* @createTime:2012-2-15下午11:04:10
public void setName(String name) {
public void setPassword(String password) {
@、 InternalResourceViewResolver、 UrlBasedViewResolver
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
* @className:UserController.java
* @createTime:2012-2-16上午12:59:17
@RequestMapping(method=RequestMethod.GET)
@RequestMapping(method=RequestMethod.POST)
public String addUser(User user){
//request.forward(); a -server -> b
//response.redirect a --> server --> client --> b
@、JstlView, ExcelView及自定义view (JsperReport, Pdf, Excel)
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
* @className:MyInteceptor.java
* @createTime:2012-2-16上午01:30:20
public class MyInteceptor implements HandlerInterceptor {
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object arg2, Exception arg3)
//控制器执行完,生成视图之前可以做的动作,向模型中添加公共成员
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
<!-- 设置拦截器链 ,当配置了多个拦截器bean时,则是顺序的往下执行-->
<bean class="test.web.MyInteceptor"></bean>
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
* @className:UserController.java
* @createTime:2012-2-16上午12:59:17
@RequestMapping(method=RequestMethod.GET)
@RequestMapping(method=RequestMethod.POST)
public String addUser(User user){
//request.forward(); a -server -> b
//response.redirect a --> server --> client --> b
//spring mvc的bean验证,对user对象加入验证,并绑定到一个结果集上
@RequestMapping(method=RequestMethod.POST)
public String addUser2(@Valid User user,BindingResult result){
if(result.hasErrors()){ //如果验证发生错误
//hibernate-validator-4.0.2.GA.jar
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html