Spring MVC学习教程(详细版)

2019-04-14 18:32发布

1      SpringMVC架构

1.1    Spring web mvc介绍

  Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出来:        

1.2    Web MVC

  mvc设计模式在b/s系统下应用:     1、  用户发起request请求至控制器(Controller) 控制接收用户请求的数据,委托给模型进行处理 2、  控制器通过模型(Model)处理数据并得到处理结果 模型通常是指业务逻辑 3、  模型处理结果返回给控制器 4、  控制器将模型数据在视图(View)中展示 web中模型无法将数据直接在视图上显示,需要通过控制器完成。如果在C/S应用中模型是可以将数据在视图中展示的。 5、  控制器将视图response响应给用户 通过视图展示给用户要的数据或处理结果。    

1.3    Spring web mvc 架构

1.3.1  架构图

   

1.3.2  架构流程

1、  用户发送请求至前端控制器DispatcherServlet 2、  DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、  处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 4、  DispatcherServlet通过HandlerAdapter处理器适配器调用处理器 5、  执行处理器(Controller,也叫后端控制器)。 6、  Controller执行完成返回ModelAndView 7、  HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet 8、  DispatcherServlet将ModelAndView传给ViewReslover视图解析器 9、  ViewReslover解析后返回具体View 10、             DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。 11、             DispatcherServlet响应用户  

1.3.3  组件说明

以下组件通常使用框架提供实现: u  DispatcherServlet:前端控制器 用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。 u  HandlerMapping:处理器映射器 HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。 u  Handler:处理器 Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。 由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。   u  HandlAdapter:处理器适配器 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。   u  View Resolver:视图解析器 View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。    

2      商品订单业务说明

  本教程在通过商品订单业务学习使用springmvc进行功能开发。    

2.1    业务流程

1、管理员维护商品信息 2、用户挑选商品,购买,创建订单  

2.2    数据库环境

       

2.3    商品订单数据模型

     

3      SpringMVC入门

3.1    需求

实现商品查询列表功能。  

3.2    开发环境准备

本教程使用Eclipse+tomcat7开发

3.3    第一步:建立一个Web项目

在eclipse下创建动态web工程springmvc_first。  

3.4    第二步:导入spring3.2.0的jar包

   

3.5    第三步:前端控制器配置

在WEB-INFweb.xml中配置前端控制器,   <servlet> <servlet-name>springmvcservlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class> <init-param> <param-namecontextConfigLocationparam-name> <param-value>classpath:springmvc.xmlparam-value> init-param> <load-on-startup>1load-on-startup> servlet> <servlet-mapping> <servlet-name>springmvcservlet-name> <url-pattern>*.actionurl-pattern> servlet-mapping>     load-on-startup:表示servlet随服务启动; url-pattern:*.action的请交给DispatcherServlet处理。 contextConfigLocation:指定springmvc配置的加载位置,如果不指定则默认加 载WEB-INF/[DispatcherServlet的Servlet 名字]-servlet.xml。  

3.5.1 Servlet拦截方式

1、拦截固定后缀的url,比如设置为 *.do、*.action, 例如:/user/add.action 此方法最简单,不会导致静态资源(jpg,js,css)被拦截。   2、拦截所有,设置为/,例如:/user/add  /user/add.action 此方法可以实现REST风格的url,很多互联网类型的应用使用这种方式。 但是此方法会导致静态文件(jpg,js,css)被拦截后不能正常显示。需要特殊处理。   3、拦截所有,设置为/*,此设置方法错误,因为请求到Action,当action转到jsp时再次被拦截,提示不能根据jsp路径mapping成功。  

3.6    第四步:springmvc配置文件

  Springmvc默认加载WEB-INF/[前端控制器的名字]-servlet.xml,也可以在前端控制器定义处指定加载的配置文件,如下:   <init-param> <param-name>contextConfigLocationparam-name> <param-value>classpath:springmvc.xmlparam-value> init-param> 如上代码,通过contextConfigLocation加载classpath下的springmvc.xml配置文件。  

3.7    第五步:配置处理器适配器

  springmvc.xml文件配置如下: <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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd       http://www.springframework.org/schema/mvc       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context-3.2.xsd       http://www.springframework.org/schema/aop       http://www.springframework.org/schema/aop/spring-aop-3.2.xsd       http://www.springframework.org/schema/tx       http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">   <bean    class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>     SimpleControllerHandlerAdapter:即简单控制器处理适配器,所有实现了org.springframework.web.servlet.mvc.Controller 接口的Bean作为 Springmvc的后端控制器。  

3.8    第六步:处理器开发

  publicclass ItemList1 implements Controller {       @Override     public ModelAndView handleRequest(HttpServletRequest request,            HttpServletResponse response) throws Exception {               //商品列表        List itemsList = new ArrayList();               Items items_1 = new Items();        items_1.setName("联想笔记本");        items_1.setPrice(6000f);        items_1.setDetail("ThinkPad T430 联想笔记本电脑!");               Items items_2 = new Items();        items_2.setName("苹果手机");        items_2.setPrice(5000f);        items_2.setDetail("iphone6苹果手机!");               itemsList.add(items_1);        itemsList.add(items_2);               //创建modelAndView准备填充数据、设置视图        ModelAndView modelAndView = new ModelAndView();               //填充数据        modelAndView.addObject("itemsList", itemsList);        //视图:对应的视图文件路径        modelAndView.setViewName("/WEB-INF/jsp/order/itemsList.jsp");               return modelAndView;     }       }   org.springframework.web.servlet.mvc.Controller:处理器必须实现Controller 接口。 ModelAndView:包含了模型数据及逻辑视图名      

3.9    第七步:配置处理器映射器

  springmvc.xml文件配置如下:   <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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd       http://www.springframework.org/schema/mvc       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context-3.2.xsd       http://www.springframework.org/schema/aop       http://www.springframework.org/schema/aop/spring-aop-3.2.xsd       http://www.springframework.org/schema/tx       http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">              <bean       class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>   BeanNameUrlHandlerMapping:表示将定义的Bean名字作为请求的url,需要将编写的controller在spring容器中进行配置,且指定bean的name为请求的url,且必须以.action结尾。  

3.10       第八步:自定义处理器配置

  springmvc.xml文件配置如下:   <bean name="/items1.action"id="itemList1" class="cn.zhong.springmvc.controller.first.ItemList1"/>   name="/items1.action":前边配置的处理器映射器为BeanNameUrlHandlerMapping,如果请求的URL 为“上下文/items1.action”将会成功映射到ItemList1控制器。    

3.11       第九步:配置视图解析器

  springmvc.xml文件配置如下:   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> bean>   InternalResourceViewResolver:支持JSP视图解析 viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,所以classpath中必须包含jstl的相关jar 包; prefix 和suffix:查找视图页面的前缀和后缀,最终视图的址为: 前缀+逻辑视图名+后缀,逻辑视图名需要在controller中返回ModelAndView指定,比如逻辑视图名为hello,则最终返回的jsp视图地址 “WEB-INF/jsp/hello.jsp”          

3.12       第十步:视图开发

  创建/WEB-INF/jsp/order/itemsList.jsp视图页面:   <%@ page language="java"contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core"prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%> DOCTYPE htmlPUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>查询商品列表title> head> <body> 商品列表: <table width="100%"border=1> <tr>     <td>商品名称td>     <td>商品价格td>     <td>商品描述td> tr> <c:forEach items="${itemsList }"var="item"> <tr>     <td>${item.name }td>     <td>${item.price }td>     <td>${item.detail }td> tr> c:forEach>   table> body> html>      

3.13       第十一步:部署在tomcat测试

  通过请求:http://localhost:8080/springmvc_first/items1.action,如果页面输出商品列表就表明我们成功了!  

3.14       DispatcherServlet

         DispathcerServlet作为springmvc的中央调度器存在,DispatcherServlet创建时会默认从DispatcherServlet.properties文件加载springmvc所用的各各组件,如果在springmvc.xml中配置了组件则以springmvc.xml中配置的为准,DispatcherServlet的存在降低了springmvc各各组件之间的耦合度。    

3.15       HandlerMapping处理器映射器

HandlerMapping 负责根据request请求找到对应的Handler处理器及Interceptor拦截器,将它们封装在HandlerExecutionChain 对象中给前端控制器返回。  

3.15.1             BeanNameUrlHandlerMapping

         BeanNameUrl处理器映射器,根据请求的url与spring容器中定义的bean的name进行匹配,从而从spring容器中找到bean实例。        

3.15.2             SimpleUrlHandlerMapping

         simpleUrlHandlerMapping是BeanNameUrlHandlerMapping的增强版本,它可以将url和处理器bean的id进行统一映射配置。     <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">        <property name="mappings">            <props>               <prop key="/items1.action">controller的bean idprop>               <prop key="/items2.action">controller的bean idprop>            props>        property>     bean>      

3.16       HandlerAdapter处理器适配器

       HandlerAdapter会根据适配器接口对后端控制器进行包装(适配),包装后即可对处理器进行执行,通过扩展处理器适配器可以执行多种类型的处理器,这里使用了适配器设计模式。  

3.16.1             SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter简单控制器处理器适配器,所有实现了org.springframework.web.servlet.mvc.Controller 接口的Bean通过此适配器进行适配、执行。   适配器配置如下:      

3.16.2             HttpRequestHandlerAdapter

HttpRequestHandlerAdapter,http请求处理器适配器,所有实现了org.springframework.web.HttpRequestHandler 接口的Bean通过此适配器进行适配、执行。   适配器配置如下: HttpRequestHandlerAdapter"/>   Controller实现如下:   publicclass ItemList2 implements HttpRequestHandler {       @Override     publicvoid handleRequest(HttpServletRequest request,            HttpServletResponse response) throws ServletException,IOException {          // 商品列表        List itemsList = newArrayList();          Items items_1 = new Items();        items_1.setName("联想笔记本");        items_1.setPrice(6000f);        items_1.setDetail("ThinkPadT430 联想笔记本电脑!");          Items items_2 = new Items();        items_2.setName("苹果手机");        items_2.setPrice(5000f);        items_2.setDetail("iphone5  苹果手机!");          itemsList.add(items_1);        itemsList.add(items_2);          // 填充数据        request.setAttribute("itemsList", itemsList);               // 视图        request.getRequestDispatcher("/WEB-INF/jsp/order/itemsList.jsp").forward(request, response);         }   }   从上边可以看出此适配器器的handleRequest方法没有返回ModelAndView,可通过response修改定义响应内容,比如返回json数据:   response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串");    

3.17       注解映射器和适配器

3.17.1             Controller的代码

  @Controller publicclass ItemList3 {       @RequestMapping("/queryItem.action")     public ModelAndView queryItem() {        // 商品列表        List itemsList = newArrayList();          Items items_1 = new Items();        items_1.setName("联想笔记本");        items_1.setPrice(6000f);        items_1.setDetail("ThinkPadT430 联想笔记本电脑!");          Items items_2 = new Items();        items_2.setName("苹果手机");        items_2.setPrice(5000f);        items_2.setDetail("iphone6苹果手机!");          itemsList.add(items_1);        itemsList.add(items_2);          // 创建modelAndView准备填充数据、设置视图        ModelAndView modelAndView = new ModelAndView();          // 填充数据        modelAndView.addObject("itemsList", itemsList);        // 视图        modelAndView.setViewName("order/itemsList");          return modelAndView;     }   }  

3.17.2             自定义处理器配置

3.17.2.1        每个bean单独配置 3.17.2.2        组件扫描器          使用组件扫描器省去在spring容器配置每个controller类的繁琐。使用标记@controller的控制器类,配置如下:       <context:component-scan base-package="cn.zhong.springmvc.controller.first"/>    

3.17.3             RequestMappingHandlerMapping注解映射器

DefaultAnnotationHandlerMapping(之前使用这个,已经过期)          注解式处理器映射器,对类中标记@ResquestMapping的方法进行映射,根据ResquestMapping定义的url匹配ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装url对应的方法Method。   从spring3.1版本开始,废除了DefaultAnnotationHandlerMapping的使用,推荐使用RequestMappingHandlerMapping完成注解式处理器映射。   配置如下:       <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>      注解描述: @RequestMapping:定义请求url到处理器功能方法的映射    

3.17.4             RequestMappingHandlerAdapter注解适配器

注解式处理器适配器,对标记@ResquestMapping的方法进行适配。   从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。   配置如下:     <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>  

3.17.5             

springmvc使用自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter,可用在springmvc.xml配置文件中使用替代注解处理器和适配器的配置。   实际开发都是使用这个的

3.18       springmvc处理流程源码分析

  1.        用户发送请求到DispatherServlet前端控制器 2.        DispatherServlet调用HandlerMapping(处理器映射器)根据url查找Handler       3.        DispatherServlet调用HandlerAdapter(处理器适配器)对HandlerMapping找到Handler进行包装、执行。HandlerAdapter执行Handler完成后,返回了一个ModleAndView(springmvc封装对象)              DispatherServlet找一个合适的适配器:                适配器执行Hanlder              4.        DispatherServlet拿着ModelAndView调用ViewResolver(视图解析器)进行视图解析,解析完成后返回一个View(很多不同视图类型的View)   视图解析: 5.        DispatcherServlet进行视图渲染,将Model中数据放到request域,在页面展示 将model数据放在request域:      

4      整合mybatis

         为了更好的学习springmvc和mybatis整合开发的方法,需要将springmvc和mybatis进行整合。   整合目标:控制层采用springmvc、持久层使用mybatis实现。  

4.1    需求

实现商品查询列表,从mysql数据库查询商品信息。  

4.2    jar包

  包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、数据库驱动、第三方连接池。   参考:“mybatis与springmvc整合全部jar包”目录      

4.3    Dao

目标: 1、spring管理SqlSessionFactory、mapper   详细参考mybatis教程与spring整合章节。  

4.3.1  db.properties

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=XXXX jdbc.password=XXXX  

4.3.2  log4j.properties

# Global logging configuration,建议开发环境中要用debug log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n  

4.3.3  sqlMapConfig.xml

  在classpath下创建mybatis/sqlMapConfig.xml   xml version="1.0" encoding="UTF-8"?> DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>   <mappers> mappers> configuration>      

4.3.4  applicationContext-dao.xml

配置数据源、事务管理,配置SqlSessionFactory、mapper扫描器。   <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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context-3.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd        http://www.springframework.org/schema/tx        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"