第一章 MVC介绍
- MVC
Web应用程序的一种架构模式,view model controller三层相分离,降低了耦合度,提高重用性和可维护性,有利于工程化管理
其中model包括pojo、service、dao等 - 常用的MVC框架
- Struts
占有MVC框架中最大的市场份额 - Spring MVC
通过一套MVC注解,让POJO成为处理请求的控制器,无须实现任何接口,同时,Spring MVC还支持REST风格的URL请求:注解驱动和REST风格的Spring MVC 是spring3.0最出彩的功能之一;
Spring MVC在数据绑定、视图解析、本地化处理及静态资源处理上都有许多不俗的表现
Spring MVC围绕DispatcherServlet这个类展开,DispatcherServlet是总策划总导演,它负责截获请求并将其分配给相应的处理器处理
DispatcherServlet是SpringMVC的总导演,负责控制和协调各个组件,DispatcherServlet继承自HttpServlet,所以本质上是Servlet,事实上,所有MVC框架的基础和核心还是Servlet规范
Spring MVC在框架设计、灵活性、扩展性等方面全面超越了Struts、webwork等MVC框架
- Struts
第二章 Spring MVC
一 、基本概念
- DispatcherServlet
前端控制器,是Spring MVC的核心,截获请求,然后分派给相应的处理器处理,最后响应请求 - HandlerAdatper
处理器适配器
按照特定的规则(HandlerAdapter要求的规则)去执行Handler
注意:编写Handler时要按照HandlerAdapter的要求去做,这样适配器才可以正确执行Handler - HandlerInterceptor
拦截器,是一个接口,有三个方法,对Controller加一些“料”,可以在真正调用Controller之前之后做一些事情 - HandlerMapping
处理器映射器
查找Handler
表示前端控制器DispatcherServlet和Controller之间的映射关系的一个类
可以告诉DispatcherServlet,一个请求到来之后由哪个Controller来响应请求 - HandlerExecutionChain
- ModelAndView
Spring MVC底层对象,包含Model和View - ViewResolver
视图解析器
根据逻辑视图解析成真正的视图(view) - View
视图,View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf......) - 整体流程
1:一个请求到达DispatcherServlet
2:DispatcherServlet通过HandlerMapping查找处理器(Handler 或者叫Controller)【根据xml配置或注解查找】
3:处理器映射器向前端控制器返回Handler
4::前端控制器调用处理器适配器去执行Handler
5:处理器适配器执行Handelr
6:Handler执行完给适配器返回ModelAndView
7:适配器给前端控制器返回ModelAndView
8:前端控制器请求视图解析器进行视图解析(根据逻辑视图名解析成真正的视图如jsp)
9:视图解析器向前端控制器返回view
10:前端控制器进行视图渲染(将模型数据(在ModelAndView对象中)填充到request域)
11:前端控制器向用户响应结果
HandlerMapping找到Controller以及HandlerIntercepter之后,把他们形成了一个Handler/HandlerAdapter(一个执行链条),返回给DispatehreServlet
二、DispatcherServlet类源码分析
- DispatcherServlet体系结构
HttpServletBean是Spring对Servlet最底层的抽象,将这个Servlet视作一个Spring的bean,并将init-param的值作为bean的属性注入进来
FrameworkServlet是在HttpServletBean基础上进一步抽象,通过FrameworkServlet真正初始化了一个Spring容器(WebApplicationContext),并引入到Servlet对象中
在DispatcherServlet源码中初始化组件:
DispatcherServlet实现了HttpServlet,本质是一个Servlet,遵循Servlet规范
init()方法在整个系统启动时运行,且只允许一次,可以在方法中对整个应用程序进行初识化操作(webapplicationcontext初始化、组件初始化、外部资源初始化等)
service()方法在系统运行的过程中处于侦听模式,侦听并处理所有的web请求 - DispetcherServlet配置
DispatcherServlet本质还是一个Servlet,要使用Spring MVC,要在web.xml中配置DispatcherServlet
三、一个Spring MVC例子
- 命令行方式创建一个maven工程
- 导入工程到IDE中
把缺少的文件补全,配置pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.gcl</groupId> 5 <artifactId>spring-mvc-study</artifactId> 6 <packaging>war</packaging> 7 <version>1.0-SNAPSHOT</version> 8 <name>spring-mvc-study Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 11 <properties> 12 <commons-lang.version>3.0</commons-lang.version> 13 <slf4j.version>1.7.6</slf4j.version> 14 <spring.version>4.2.0.RELEASE</spring.version> 15 </properties> 16 17 <dependencyManagement> 18 <dependencies> 19 <dependency> 20 <groupId>org.springframework</groupId> 21 <artifactId>spring-framework-bom</artifactId> 22 <version>${spring.version}</version> 23 <type>pom</type> 24 <scope>import</scope> 25 </dependency> 26 </dependencies> 27 </dependencyManagement> 28 29 <dependencies> 30 <dependency> 31 <groupId>org.springframework</groupId> 32 <artifactId>spring-webmvc</artifactId> 33 </dependency> 34 35 <dependency> 36 <groupId>org.apache.commons</groupId> 37 <artifactId>commons-lang3</artifactId> 38 <version>3.0</version> 39 </dependency> 40 41 <dependency> 42 <groupId>org.slf4j</groupId> 43 <artifactId>slf4j-log4j12</artifactId> 44 <version>${slf4j.version}</version> 45 <exclusions> 46 <exclusion> 47 <groupId>org.slf4j</groupId> 48 <artifactId>slf4j-api</artifactId> 49 </exclusion> 50 </exclusions> 51 </dependency> 52 53 54 <dependency> 55 <groupId>junit</groupId> 56 <artifactId>junit</artifactId> 57 <version>3.8.1</version> 58 <scope>test</scope> 59 </dependency> 60 </dependencies> 61 <build> 62 <finalName>spring-mvc-study</finalName> 63 </build> 64 </project>
- 配置web.xml
1 <!DOCTYPE web-app PUBLIC 2 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 3 "http://java.sun.com/dtd/web-app_2_3.dtd" > 4 5 <web-app> 6 <display-name>Archetype Created Web Application</display-name> 7 8 <servlet> 9 <servlet-name>mvc-dispatcher</servlet-name> 10 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 11 <!-- DispatcherServlet对应的上下文的配置,默认为/WEB-INF/$servlet-name-$servlet.xml --> 12 <!-- 也就是说如果没有配置下面的init-param,那么spring会从加载 13 /WEB-INF/mvc-dispatcher-servlet.xml这个配置文件 --> 14 <init-param> 15 <param-name>contextConfigLocation</param-name> 16 <param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value> 17 </init-param> 18 <load-on-startup>1</load-on-startup> 19 </servlet> 20 21 <servlet-mapping> 22 <!-- mvc-dispatcher拦截所有请求 --> 23 <servlet-name>mvc-dispatcher</servlet-name> 24 <url-pattern>/</url-pattern> 25 </servlet-mapping> 26 </web-app>
- 创建DispatcherServlet的配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context-3.1.xsd 15 http://www.springframework.org/schema/mvc 16 http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 17 http://www.springframework.org/schema/task 18 http://www.springframework.org/schema/task/spring-task-3.1.xsd"> 19 <!-- 激活@Autowired、@Resource、@PostConstruct、@PreDestroy、@PersistenceContext、@Required这几个注解 --> 20 <context:annotation-config /> 21 22 <!-- DispatcherServlet上下文,只搜索@Controller标注的类,不搜索其他标注的类 --> 23 <context:component-scan base-package="com.gcl.mvcdemo"> 24 <context:include-filter type="annotation" 25 expression="org.springframework.stereotype.Controller" /> 26 </context:component-scan> 27 28 <!-- 让DispatcherServlet启用基于注解的HandlerMapping --> 29 <mvc:annotation-driven /> 30 31 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 32 <property name="prefix" value="/WEB-INF/jsps/"/> 33 <property name="suffix" value=".jsp"/> 34 </bean> 35 </beans>
创建真正的Controller类

package com.gcl.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/hello") public class HellomvcController { // 这个方法会响应 host:8080/hello/mvc @RequestMapping("/mvc") public String helloMvc() { return "home"; } }
四、Spring MVC实现一个登录验证
- 新建一个maven工程,配置maven依赖
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.gcl.spring</groupId> 5 <artifactId>spring-mvc-study2</artifactId> 6 <packaging>war</packaging> 7 <version>0.0.1-SNAPSHOT</version> 8 <name>spring-mvc-study2</name> 9 <url>http://maven.apache.org</url> 10 11 <!--properties标签用来定义全局变量,在pom中通过${property_name}的形式引用变量的值 --> 12 <properties> 13 <spring.version>4.2.0.RELEASE</spring.version> 14 </properties> 15 16 <dependencies> 17 18 <dependency> 19 <groupId>org.springframework</groupId> 20 <artifactId>spring-webmvc</artifactId> 21 <version>${spring.version}</version> 22 </dependency> 23 24 <!-- <dependency> 25 <groupId>org.springframework</groupId> 26 <artifactId>spring-tx</artifactId> 27 <version>${spring.version}</version> 28 </dependency> 29 --> 30 <dependency> 31 <groupId>junit</groupId> 32 <artifactId>junit</artifactId> 33 <version>3.8.1</version> 34 <scope>test</scope> 35 </dependency> 36 </dependencies> 37 <build> 38 <finalName>spring-mvc-study2</finalName> 39 </build> 40 </project>
- 配置web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app> 3 <display-name>Archetype Created Web Application</display-name> 4 5 6 <listener> 7 <listener-class>org.springframework.web.context.ContextLoaderListener 8 </listener-class> 9 </listener> 10 11 <context-param> 12 <param-name>contextConfigLocation</param-name> 13 <param-value>classpath*:applicationContext.xml</param-value> 14 </context-param> 15 16 17 <servlet> 18 <servlet-name>springmvc</servlet-name> 19 <servlet-class>org.springframework.web.servlet.DispatcherServlet 20 </servlet-class> 21 <init-param> 22 <param-name>contextConfigLocation</param-name> 23 <param-value>/WEB-INF/springmvc.xml</param-value> 24 </init-param> 25 </servlet> 26 27 <servlet-mapping> 28 <servlet-name>springmvc</servlet-name> 29 <url-pattern>*.html</url-pattern> 30 </servlet-mapping> 31 </web-app>
- 创建DispatcherServlet的配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context-3.1.xsd 15 http://www.springframework.org/schema/mvc 16 http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 17 http://www.springframework.org/schema/task 18 http://www.springframework.org/schema/task/spring-task-3.1.xsd"> 19 20 <!-- 自动扫描com.gcl.springmvc包下所有的组件 --> 21 <context:component-scan base-package="com.gcl.springmvc"/> 22 23 </beans>
- Controller类和Service类
1 package com.gcl.springmvc.controller; 2 3 import javax.annotation.Resource; 4 import javax.servlet.http.HttpServletRequest; 5 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.servlet.ModelAndView; 9 10 import com.gcl.springmvc.service.LoginService; 11 12 @Controller 13 public class LoginController { 14 15 @Resource 16 LoginService service; 17 18 @Resource 19 HttpServletRequest request; 20 21 @RequestMapping("/index") 22 public ModelAndView toLogin(){ 23 return new ModelAndView("WEB-INF/jsp/login.jsp"); 24 } 25 26 @RequestMapping("login") 27 public ModelAndView login(){ 28 String loginurl = "WEB-INF/jsp/login.jsp"; 29 String succseeurl = "WEB-INF/jsp/success.jsp"; 30 31 String uname = request.getParameter("uname"); 32 String upassword = request.getParameter("upassword"); 33 34 return service.doLogin(loginurl,succseeurl,uname,upassword); 35 } 36 37 }
1 package com.gcl.springmvc.service; 2 3 import org.springframework.stereotype.Service; 4 import org.springframework.web.servlet.ModelAndView; 5 6 @Service 7 public class LoginService { 8 9 public ModelAndView doLogin(String loginurl, String succseeurl, 10 String uname, String upassword) { 11 12 if(uname==null||"".equals(uname)){ 13 return new ModelAndView(loginurl,"error","用户名不能为空"); 14 } 15 if(upassword==null||"".equals(upassword)){ 16 return new ModelAndView(loginurl,"error","密码不能为空"); 17 } 18 //用户名 : gcl 密码:123 19 if(uname.equals("gcl")&&upassword.equals("123")){ 20 return new ModelAndView(succseeurl); 21 } 22 return new ModelAndView(loginurl,"error","用户名或密码错误"); 23 } 24 25 }
- 登录页面和登录成功页面
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>登录</title> 13 14 <meta http-equiv="pragma" content="no-cache"> 15 <meta http-equiv="cache-control" content="no-cache"> 16 <meta http-equiv="expires" content="0"> 17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 18 <meta http-equiv="description" content="This is my page"> 19 <!-- 20 <link rel="stylesheet" type="text/css" href="styles.css"> 21 --> 22 23 </head> 24 25 <body> 26 <form action="login.html" method="post"> 27 <p> 28 用户名:<input name="uname" type="text"> 29 </p> 30 <p> 31 密 码:<input name="upassword" type="password"> 32 </p> 33 <p> 34 <input type="submit" value="提交"> 35 <input type="reset" value="重置"> 36 </p> 37 </form> 38 39 <font color="red">${error }</font> 40 </body> 41 </html>
五、不使用注解的Spring MVC
- 配置前端控制器DispatcherServlet
DispatcherServlet负责请求的接受与响应,是一个servlet需要在web.xml中配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> 3 <display-name>myspringmvc</display-name> 4 5 <!-- 前端控制器:springmvc --> 6 <servlet> 7 <servlet-name>springmvc</servlet-name> 8 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 9 <!-- contextConfigLocation:前端控制器要加载的配置文件,(要在该配置文件中配置适配器等) 10 如果不配置这个,就会默认加载/WEN-INF/servlet_name-servlet.xml --> 11 <init-param> 12 <param-name>contextConfigLocation</param-name> 13 <param-value>/WEB-INF/config/springmvc.xml</param-value> 14 </init-param> 15 </servlet> 16 17 <servlet-mapping> 18 <servlet-name>springmvc</servlet-name> 19 <!-- 20 第一种: *.action 以.action结尾的请求由DispatcherServlet解析 21 第二种: / 所有访问的地址都由DispatcherServlet解析 22 对于静态文件的解析需要配置不让DispatcherServlet解析 23 这种方式可以实现RESTful风格的url 24 第三种: /* 是不正确的 25 --> 26 <url-pattern>*.action</url-pattern> 27 </servlet-mapping> 28 29 <welcome-file-list> 30 <welcome-file>index.html</welcome-file> 31 <welcome-file>index.htm</welcome-file> 32 <welcome-file>index.jsp</welcome-file> 33 <welcome-file>default.html</welcome-file> 34 <welcome-file>default.htm</welcome-file> 35 <welcome-file>default.jsp</welcome-file> 36 </welcome-file-list> 37 38 </web-app>
- 配置DispatcherServlet初始化要加载的配置文件
在这个配置文件中,可以配置处理器映射器、处理器适配器、视图解析器、处理器
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context-3.1.xsd 15 http://www.springframework.org/schema/mvc 16 http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 17 http://www.springframework.org/schema/task 18 http://www.springframework.org/schema/task/spring-task-3.1.xsd"> 19 20 <!-- 配置处理器适配器 --> 21 <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> 22 23 <!-- 配置处理器映射器 --> 24 <!-- 把处理器的bean-name作为URL去查找 --> 25 <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> 26 27 <!-- 配置处理器,name为请求的路径,这样映射器才能根据名字找到 --> 28 <bean name="/hello.action" class="com.gcl.controller.MyController"/> 29 30 <!-- 视图解析器 --> 31 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/> 32 33 </beans>
- 编写处理器
处理器(也就是Handler或者叫Controller),要根据适配器的规则去写才能被适配器调用,查看源码发现,适配器只能处理实现了Controller接口的Handler
所以,Handler要实现Controller接口,处理器返回的是一个ModelAndView对象
1 package com.gcl.controller; 2 3 import java.util.ArrayList; 4 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 8 import org.springframework.web.servlet.ModelAndView; 9 import org.springframework.web.servlet.mvc.Controller; 10 11 import com.gcl.po.Iterm; 12 13 public class MyController implements Controller { 14 15 @Override 16 public ModelAndView handleRequest(HttpServletRequest request, 17 HttpServletResponse response) throws Exception { 18 // ArrayList<Iterm> itermlist = new ArrayList<Iterm>(); 19 Iterm i1= new Iterm(); 20 i1.setIname("手机"); 21 i1.setPrice(8000); 22 // itermlist.add(i1); 23 24 ModelAndView mav = new ModelAndView(); 25 mav.addObject("iterm", i1.getIname()); 26 27 mav.setViewName("/WEB-INF/jsp/home.jsp"); 28 29 return mav; 30 } 31 32 }
- 编写页面
在jsp页面中可以用el表达式获取到ModelAndView中设定的值
六、总结
- DispatcherServlet的web.xml配置
<!-- 前端控制器:springmvc --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- contextConfigLocation:前端控制器要加载的配置文件,(要在该配置文件中配置适配器等) 如果不配置这个,就会默认加载/WEN-INF/servlet_name-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 第一种: *.action 以.action结尾的请求由DispatcherServlet解析 第二种: / 所有访问的地址都由DispatcherServlet解析 对于静态文件的解析需要配置不让DispatcherServlet解析 这种方式可以实现RESTful风格的url 第三种: /* 是不正确的 --> <url-pattern>*.action</url-pattern> </servlet-mapping>
- 处理器映射器
- 非注解的
多个映射器可以并存,前端控制器会判断url能让哪个映射器映射,就让正确的映射器处理
<!-- 配置处理器映射器 --> <!-- 第一种:拿URL去查找处理器的bean-name --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 第二种:简单url映射器 --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mapping"> <props> <prop key="/xxx.action">myController</prop> <prop key="/xxxxxx.action">myController</prop> </props> </property> </bean> <!-- 配置处理器,name为请求的路径,这样映射器才能根据名字找到 --> <bean id="myController" name="/hello.action" class="com.gcl.controller.MyController"/>
- 注解的映射器
前端控制器从上面的文件中加载映射器、适配器、视图解析器等组件,如果不在相应的xml中配置那就会加载这个properties文件中的
在spring3.1之前用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器
properties文件中没3.1之后的
在spring3.1之后用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器
- 非注解的
- 处理器适配器
- 非注解
<!-- 配置处理器适配器 ,所有的适配器都实现了HandlerAdapter接口--> <!-- 第一种:要求编写的Controller实现Controller接口 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 第二种:要求编写的Controller实现HttpRequestHandler接口 --> <!--使用这种方式可以通过修改response,设置响应的数据格式,比如响应json数据 response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=utf-8); response.getWrite().write("json串");--> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
- 注解的适配器
在spring3.1之前用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器
在spring3.1之后用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器
properties文件中没3.1之后的
<!-- 注解映射器,spring3.1之后用的 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!-- 注解适配器,spring3.1之后用的 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> <!-- MVC的注解驱动,可以代替上边的注解映射器和注解适配器 mvc:annotation-driven还默认加载了很多的参数绑定方法,比如json转换解析器就默认加载了 在实际开发中使用mvc:annotation-driven--> <mvc:annotation-driven></mvc:annotation-driven>
- 注解的Handler
如果不配置适配器和映射器,也会加载默认的注解映射器和注解适配器
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
注解的映射器和注解的适配器配对使用
如果要用新的,可以显示的加载
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
或者使用在实际开发中用的方法:
<mvc:annotation-driven></mvc:annotation-driven>
然后用@Controller表示该处理器,用@RequestMapping指定请求的路径
然后要加载处理器就需要在xml中配置,如果有很多个,单个配置太麻烦,实际开发中用包扫描:
<context:component-scan base-package="com.gcl.controller"/> - 视图解析器
给jsp路径加上前缀和后缀,程序中就可以省掉
<!-- 视图解析器 解析jsp classpath下面必须要有jstl的包 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置jsp路径的前缀和后缀 --> <property name="prefix" value="/WEN-INF/jsp"/> <property name="suffix" value=".jsp"/> </bean>
第三章、Spring MVC和Mybatis整合
一、整体架构
- 架构图
-
整合思路
- 整合dao层,Mybatis和Spring整合,通过Spring管理mapper接口,使用mapper接口的扫描器自动扫描mapper接口在spring容器中注册
- 整合service层,通过Spring管理service接口,使用配置方式将service接口配置在spring配置文件中;实现事务控制等
- 整合spring mvc ,由于spring mvc是spring的一个模块,不需要整合
二、Spring和Mybatis整合开发流程
- 整合Dao层
- Mybatis自己的配置文件
- 整合的配置文件
里面要配置:数据源、SeqSessionFactory、mapper扫描器 - Dao层编写
对应的xml
- Mybatis自己的配置文件
- service层
- 接口
- 实现类
- 在容器配置service
创建applicationContext-service.xml 文件中配置service接口 - 实现事务控制(applicationContext-transaction.xml)
在这个配置文件中,使用spring的声明式事务控制方法
- 接口
- 整合spring mvc
配置前端控制器(web.xml以及springmvc.xml)
springmvc.xml
编写Controller(就是Handler)
编写jsp -
加载spring容器
第四章、Spring MVC注解开发
需求:根据商品id查询商品信息、修改商品信息
一、service层
接口:
实现类:
。。。
二、Controller
- @Controller
- @RequestMapping
@RequestMapping作用一:url映射,在方法上指定url
@RequestMapping作用二:窄化请求映射,方法和类上都有url
这样queryItems()方法就会处理这个请求:http://localhost:8080/项目名/items/queryItems.action
@RequestMapping作用三:限制Http请求方式,出于对http的链接进行安全访问,如果限制请求方式为post,进行get请求会报错 - Controller方法的返回值
- 返回ModelAndView
需要方法结束时,定义ModelAdnView,将Model和View分别进行设置 - 返回String
如果Controller方法返回String,表示返回逻辑视图名
真正视图(jsp路径)=前缀+逻辑视图名+后缀
redirect重定向
商品修改提交后重定向到商品查询列表
重定向的特点:浏览器地址栏的url会发生变化,修改提交的request数据无法传到重定向的地址,因为重定向后重新进行request,也就是request无法共享
forward页面转发
浏览器地址栏url不变,request可以共享 -
返回void
- 返回ModelAndView
三、参数绑定
- 参数绑定过程
- 参数绑定默认支持的类型
直接在Controller方法形参上定义下边类型的对象,就可以使用这些对象,参数绑定过程中,下边这些类型会直接进行绑定- HttpServletRequest 通过request对象获取请求信息
- HttpServletResponse 通过response对象处理响应信息
- HttpSession 通过session对象得到session中存放的对象
- Model / ModelMap Model是一个接口,ModelMap是一个接口实现 作用:将Model数据填充到request域
- 参数绑定支持的简单类型
-
pojo绑定
-
乱码问题
-
pojo绑定
页面中input的name和controller的pojo形参中的属性名称一致,将页面中的参数绑定到pojo
页面:
controller中的形参:
-
- 自定义参数绑定实现日期类型绑定
对于Controller形参中的pojo对象,如果该对象的属性中有日期类型,就需要自定义参数绑定
将请求中的日期数据串转换成日期类型,要转换的日期类型和该属性的日期类型一致
需要向处理器适配器中自定义的参数绑定组件
自定义的参数绑定器
配置方式一:
配置方式二:
四、Spring MVC和Struts2的区别
- spring mvc是基于方法开发的;struts2是基于类开发的
spring mvc将url和controller方法映射,映射成功后spring mvc生成一个Handler对象,对象中只包括了一个方法,方法执行结束,形参数据销毁
spring mvc的controller开发类似与service开发 - spring mvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接受参数,无法使用单例,只能使用多例
因为spring mvc通过形参接受参数,多线程访问的时候,方法里面的参数它是每个线程都有不同的内存空间,而通过成员变量接受参数,多线程访问是共享的成员变量 - 经过实际测试,struts2速度慢,是因为使用了struts标签,如果使用struts,建议使用jstl