Spring mvc

SpringMvc简单介绍

Spring MVC是一个基于MVC(Model  view Controller)模式的WEB框架,它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化、等等),使用非常简单,SpringMvc作为Spring中的一个模块,可以与Spring无缝集成。

 

SpringMvcSpring框架为核心,为应用程序中的Web层(表现层)提出的一套优秀的解决方案。

spring-webmvc-4.1.2.RELEASE.jar  SpringMVCjar文件。

spring-web-4.1.2.RELEASE.jar     SpringWeb项目运行的支持。

1.1.1. MVC框架思想-核心控制器(前端控制器)

顾名思义核心控制器用于Web层核心功能的处理以及在所有控制器执行的。所有的WebMvc框架都采用了这种方式。

Struts2中我们使用的是StrutsPrepareAndExecuteFilter作为核心控制器,在SpringMVC中使用的是DispatcherServlet为核心控制器.

DispatcherServlet核心控制器会拦截匹配的请求,把拦截下来的请求,依据相应的规则分发到目标Controller来处理。

创建项目确保Spring可用

导入jar

com.springsource.org.apache.commons.logging-1.1.1.jar(版本三)

    spring-beans-4.1.2.RELEASE.jar

    spring-context-4.1.2.RELEASE.jar

    spring-core-4.1.2.RELEASE.jar

    spring-expression-4.1.2.RELEASE.jar

    spring aopormjdbctx相关jar根据项目使用自行添加;

准备配置文件配置 applicationContext.xml

1.1.1. 加入相关Spring mvc相关jar包。

spring-web-4.1.2.RELEASE.jar           spring web项目的支持。

spring-webmvc-4.1.2.RELEASE.jar       SpringMVC核心包。

配置核心控制器

Webmvc框架的心脏就是核心控制器,负责所有请求的公共功能,然后再分发给具体的控制器(我们编写的控制器),完成业务逻辑,响应视图。

   配置:

<!-- springmvc的核心控制器,拦截所有的请求,负责分发到对应的Controller中的方法 -->

<servlet>

<servlet-name>springmvc</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>springmvc</servlet-name>

<!-- / 拦截所有的请求,拦截Controller的地址

/*拦截所有的请求,会拦截*.jsp类似请求

*.do  *.action 拦截.do   .action结尾的请求

 -->

<url-pattern>/</url-pattern>

</servlet-mapping>

1.1.1. 准备SpringMVC映射文件

 

规范要求

说明

实现Controller接口或子接口。

注意:子接口很多已经过时了。

核心方法为handleRequest(req,resp),处理用户请求

普通的类(常用的哦)

使用一个普通的类作为我们的控制器,每一个方法就是一个处理器,这种方式需要配合注解标签才能使用。

 

       SpringMVCSpring的一个模块,它的配置文件就是Spring的配置差不多,复制一份applicationContext.xml修改为applicationContext-mvc.xml

SpringMVC中的控制器有一定规范,要么实现接口,要么使用POJO对象与注解配合使用。

handleRequest方法的两个参数与我们以前的servletservice方法一样,requestresponse对象,我们可以使用这个两个对象完成一次请求的所有工作,比如你可以使用request接受参数,或者使用response重定向等等,注意方法除了返回值以外还有一个返回值ModelAndView

 1  SpringMVC的控制器Controller,和Struts2中的action一样。
 2  */
 3 public class HelloController implements Controller{
 4     /**
 5      * 处理请求方法。
 6      * request:封装了请求对象;
 7      * response:封装了这个请求的响应对象
 8      * 返回一个ModelAndView对象:
 9      *    Model:模型 ,封装我们的数据
10      *    View:视图,返回的jsp页面
11      *    ModelAndView对象是springmvc控制器中的一个对象,用于封装数据模型和返回页面视图
12      */
13     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
14         //获取请求参数
15         System.out.println("HelloController....");
16         //调用service进行业务逻辑处理
17         System.out.println("HelloController 已经进行了业务逻辑处理");
18         //返回jsp页面视图
19         ModelAndView mAndView = new ModelAndView();
20         mAndView.setViewName("/01jsp/01_hello.jsp");
21         return mAndView;
22     }
23 
24 }

1)配置

SpringMVC是基于SpringSpring中的核心就是Ioc容器,而Ioc容器中最重要的成员就是<bean>SpringMVC中的控制器也是一个一个<bean>。使用name属性:表示这个Controller的访问路径

 1 <!-- springmvc的核心控制器,拦截所有的请求,负责分发到对应的Controller中的方法 -->
 2     <servlet>
 3         <servlet-name>springmvc</servlet-name>
 4         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 5         
 6 <!--         启动springmvc的核心控制器的时候,就初始化加载springmvc的配置文件 -->
 7         <init-param>
 8           <param-name>contextConfigLocation</param-name>
 9           <param-value>classpath:applicationContext-mvc.xml</param-value>
10         </init-param>
11 <!--         DispatcherServlet启动比较耗时,在启动加载文件的时候就进行加载 -->
12         <load-on-startup>1</load-on-startup>
13     </servlet>
14     <servlet-mapping>
15         <servlet-name>springmvc</servlet-name>
16         <!-- / 拦截所有的请求
17         /*拦截所有的请求
18         *.do  *.action 拦截.do   .action结尾的请求
19          -->
20         <url-pattern>/</url-pattern>
21     </servlet-mapping>

1.1.1. 入门小结:

  ①:创建一个动态工程,配置tomcat和编译路径

  ②:Spring的环境准备:导入基本的5jar包和一个applicationContext.xml配置文件

  ③:Springmvc的环境的准备:

spring-web-4.1.2.RELEASE.jar           spring web项目的支持。

spring-webmvc-4.1.2.RELEASE.jar       SpringMVC核心包。

  Web ,webmvc的两个jar包;

     applicationContext-mvc.xml的配置文件

      Web.xml:配置核心控制器:DispatcherServlet

 ④:Controller的准备:写一个类,实现Controller接口,覆写方法,返回一个视图jsp页面

       同时应把这个Controller配置到applicationContext-mvc.xml,变成一个beanname就是访问的路径

 ⑤:准备一个jsp视图

:启动测试

1.1. 静态资源文件访问问题

由于我们配置的拦截器规则是”/”,”/”就代表默认控制器,tomcat本身自带有一个默认控制器,这个控制器用于处理静态资源请求,如果我们配置默认控制器,那么tomcat的默认控制器就不生效,导致静态资源无法访问。

解决办法:springmvc开启静态资源控制器。(适应于HTML页面视图)

<mvc:default-servlet-handler/>(release :释放)

1.1. 控制器三种实现方式

① 实现Controller接口

② 实现HttpRequestHandler接口

③ 普通类(pojo)和注解 @RequestMapping

public class ImplController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("我implements Controller进来了。。。。。");
        return null;
    }
}

配置:将这个Controller交给spring管理,并使用name属性配置映射关系(就是这个Controller的访问路径)

1 public class HandlerController implements HttpRequestHandler {
2     @Override
3     public void handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
4         System.out.println("进来了implements HttpRequestHandler。。。。");
5     }
6 }

配置:将这个Controller交给spring管理,并使用name属性配置映射关系(就是这个Controller的访问路径)

缺点:只能有一个方法,不能实现多个地址的映射

普通类(pojo)和注解

 1 @RequestMapping("/user")
 2 public class UserController {
 3     /**
 4      * 一个Index方法
 5      * @return
 6      */
 7      @RequestMapping("/index")//访问地址:/user/index 
 8      public String index(){
 9          System.out.println("我是一个index。。。。。。。。。。。。");
10          return  "";
11      }
12      /**
13       * 一个list方法
14       * @return
15       */
16      @RequestMapping("/list")//访问地址:/user/list 
17      public void  list(){
18          System.out.println("我是一个list。。。。。。。。。。。。");
19      }
20 
21 }

配置:@RequestMapping配置类上和方法上

(只需要配置让spring管理这个bean即可,无需指定路径,因为方法上面通过@RequestMapping指定)

<!-- Controller的实现:方式一:定义一个普通的java-->

<bean  class="cn.itsource.springmvc._02_controller.UserController"> </bean>

需要开启SprigMVC注解支持:

<!-- 开启Springmvc的注解驱动:扫描@RequestMapping等注解 -->

 <mvc:annotation-driven/>

总结

Springmvc中所有控制器,其实在spring中就是一个一个bean

spring管理bean的方法分为两种,第一种是xml,第二种是注解。

Springmvc中控制器建议使用注解方式,是官方推荐的,也外面公司使用方式

控制器注解实现方式

 1 /**
 2  *        
 3  * Controller的实现:
 4  *   全注解:
 5  *      @Controller的配置:相当于一起的xml中的bean配置
 6  *      @RequestMapping("/department")配置:bean的name的配置
 7  *      
 8  *      注意:需要配置spring注解的扫描路径
 9  *             <!-- 开启Spring的注解的扫描:@Controller @Service @Repository @Component等 -->
10                 <context:component-scan base-package="cn.itsource.springmvc"/>
11  *          开启springmvc注解的扫描:
12  *              <!-- 开启Springmvc的注解驱动:扫描@RequestMapping等注解 -->
13                  <mvc:annotation-driven/>
14  * @author admin
15  *
16  */
17 @Controller//将这个类,交给Spring管理,需要开启注解的扫描路径
18 @RequestMapping("/department")
19 public class DepartmentController {
20     
21     @RequestMapping("/index")
22     public void index(){
23         System.out.println("index...........");
24     }
25     @RequestMapping("/del")
26     public void del(){
27         System.out.println("del.......");
28     }
29 
30 }
 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" 
 4     xmlns:mvc="http://www.springframework.org/schema/mvc"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="
 7     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
 9     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
10     <!-- 开启springMVC的默认处理控制器 :处理静态资源 -->
11     <mvc:default-servlet-handler />
12     <!-- 开启spring对mvc注解支持功能,能识别@RequestMapping等注解 -->
13     <mvc:annotation-driven />
14     <!-- 开启spring对注解配置支持,默认这个配置是存在的,但是为了规范起见,还是写上:@Controller:controller @Service:service @Repository:dao @Component :其他 -->
15     <context:annotation-config />
16     <!-- 组件扫描路径 -->
17     <context:component-scan base-package="cn.itsource.springmvc" />
18 </beans>
  1. 控制器常用操作

struts2一样,控制器除了我们前面重点讲解处理请求并返回视图以外,还需要一些事情,比如接收页面传递参数、绑定数据到页面、返回json数据、文件上传、文件下载等

参数接收

配置请求编码过滤器

参数接收,首先要考虑乱码问题。然而springmvc框架本身没有处理请求编码,但是spring框架为我们提供了一个请求编码过滤器,我们在web.xml配置一个请求编码过滤器。

  参数接收

  配置请求编码过滤器

参数接收,首先要考虑乱码问题。然而springmvc框架本身没有处理请求编码,但是spring框架为我们提供了一个请求编码过滤器,我们在web.xml配置一个请求编码过滤器。

 1 <!-- 支持UTF-8编码 -->
 2   <filter>
 3       <filter-name>characterEncoding</filter-name>
 4       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
 5       <init-param>
 6           <param-name>encoding</param-name>
 7           <param-value>UTF-8</param-value>
 8       </init-param>
 9   </filter>
10   <filter-mapping>
11       <filter-name>characterEncoding</filter-name>
12       <url-pattern>/*</url-pattern>
13   </filter-mapping>

1.1.1. 参数接收方式

① 通过控制器的执行方法参数来接收普通参数

② 通过Domain模型对象来接收

③ 通过传统的HttpServletRequest接收

④ 通过url中的参数接收(restfull风格) @PathVariable("id")转换

1.通过控制器的执行方法参数来接收普通参数

2.通过模型对象来接收(常用)

3.接收url中参数的请求,接收用户请求参数值

4.通过传统的HttpServletRequest接收

1.1. 数据传递

就是Controller往前台(页面)传递数据

① 通过ModelAndView对象传递

② 通过Model对象传递

③ 通过request对象传递

④ 通过返回值传递

 

①通过ModelAndView对象传递

/**
	 * 通过一个ModelAndView对象来传递参数
	 * @return
	 */
	@RequestMapping("/demo1")
	public ModelAndView demo1() {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("msg", "大家好啊");
		modelAndView.setViewName("/03jsp_contrlloerParamsToView/controllerToView.jsp");
		User user=new User("zs", 13, 11L);
		modelAndView.addObject(user);
		return modelAndView;

通过Model对象进行数据传递

 1 /**
 2      * 通过形参中的一个Model对象来传递参数。
 3      * springMvc自动创建模型对象传入到方法中,我们只需要在这个模型上添加数据就以。
 4      * @param model 封装数据的模型对象
 5      * @return 返回值是一个字符串,表示是返回的视图view
 6      */
 7     @RequestMapping("/demo2")
 8     public String demo2(Model model) {
 9         model.addAttribute("msg", "一点都不好");
10         return "/03jsp_contrlloerParamsToView/controllerToView.jsp";
11     }

3.通过request对象进行数据传递

 1 /**
 2      * 使用原始的在request上添加属性
 3      * @param request
 4      * @return 返回值是一个字符串,表示返回的视图view
 5      */
 6     @RequestMapping("/demo3")
 7     public String demo3(HttpServletRequest request) {
 8         request.setAttribute("msg", "我是另一种方式了哦");
 9         return "/03jsp_contrlloerParamsToView/controllerToView.jsp";
10     }

4.通过返回值传递数据

 1 /**
 2      * 返回一个自定义对象:user。
 3      * 返回值就是模型数据。
 4      * springmvc会自动创建一个ModelAndView对象,mav,将uer添加到mav中:mav.addObject("user",user);
 5      * 并且返回视图路径就是访问路径:mav.setViewName("/demo4.jsp");
 6      * @return
 7      */
 8     @RequestMapping("/demo4")
 9     public User demo4() {
10         User user=new User("2",34,34L);
11         return user;
12     }
13 
14 yi

SpringMcv返回JSON

要把Java对象转换为Json,需要框架支持

Jacksonhttp://jackson.codehaus.org/ springMVC

JSON-libhttp://json-lib.sourceforge.net/  struts2

Gsonhttp://code.google.com/p/google-gson/

FastJson阿里开源

加入jackson json工具包

 1 出现406状态异常
 2 
 3   加入json jar包 jackson
 4 
 5 处理如果有乱码的问题:springContext-mvc.xml
 6 
 7 <!-- 为了处理返回的JSON数据的编码,设置为UTF-8 --> 
 8 
 9 <bean id="mappingJacksonHttpMessageConverter"  class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
10 
11     <property name="supportedMediaTypes">
12 
13         <list>
14 
15              <value>text/html;charset=UTF-8</value>
16 
17           </list>
18 
19      </property>
20 
21 </bean>
22 
23  

对日期格式的特殊处理(后面要用到的知识)

从后台向前台:

默认返回的日期格式为时间戳,而在前台我们希望显示出指定规则的日期字符串。如:

默认:{"name""小明哥","birthdate"121223223}

期望: {"name""小明哥","birthdate""2025-12-12 14:12:12"}

在日期get属性,字段上,添加一个格式化注解

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

从前台向后台:

在后台模型的setter方法上,添加注解

@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")

访问地址:localhost:8080/jsonV587?birthDay=2017-06-13 16:50:53

 文件上传/下载

@RequestMapping(value = "/upload", method = RequestMethod.GET)

//映射关系的匹配有很多参数可以选:value:表示请求的路径,可以默认不写

//method:表示这个方法的请求方式:get或者post。当明显指定了访问方式后:就必须对应的方式才能进入。

文件上传

由于springmvc自己没有实现文件上传,它使用是apache.commons.fileupload ,需要导入以下的包

com.springsource.org.apache.commons.fileupload-1.2.0.jar

com.springsource.org.apache.commons.io-1.4.0.jar

 1 **
 2  * 文件的上传:
 3  * springmvc没有自己的上传方法。需要使用Apache.commons.fileupload
 4  * com.springsource.org.apache.commons.fileupload-1.2.0.jar
 5    com.springsource.org.apache.commons.io-1.4.0.jar
 6 */
 7 @Controller
 8 public class UploadController {
 9     /**
10      * 显示指定这个方法是get请求
11      * 前台通过get请求访问这个路径,返回一个jsp文件上传页面
12      * @return
13      */
14     @RequestMapping(value = "/upload", method = RequestMethod.GET)
15     public String uploadFileGet() {
16         System.out.println("get....");
17         return "/WEB-INF/05_upload_jsp/upload.jsp";
18     }
19 
20     /**
21      * 文件上传实现方法:
22      * ①:获取上传文件的原始文件名
23      * ②:随机生产一个UUID作为上传后的文件名,放置文件名重复
24      * ③:获取文件名后缀,结合①②生产保存的文件名
25      * ④:获取需要保存的文件的服务器路径
26      * ⑤:使用file流写文件
27      * ⑥:完成文件保存
28      * @param name  注册名
29      * @param img 上传的文件图片对象
30      * @param request request请求
31      * @return
32      * @throws FileNotFoundException
33      * @throws IOException
34      */
35     @RequestMapping(value = "/upload", method = RequestMethod.POST)
36     public String uploadFilePost(String name,MultipartFile img,HttpServletRequest request) throws FileNotFoundException, IOException {
37         //获取上传文件的原始文件名
38         String oFileName=img.getOriginalFilename();
39         //获取文件名的后缀
40         String fNameSuffix= FilenameUtils.getExtension(oFileName);
41         //生产一个随机的文件名
42         String uuidName = UUID.randomUUID().toString();
43         String fileName=uuidName+"."+fNameSuffix;
44         //获取保存文件的路径
45         String fileDir = request.getServletContext().getRealPath("/uploads");
46         //使用file流写文件
47         File file=new File(fileDir,fileName);
48         if(!file.getParentFile().exists()){
49             file.getParentFile().mkdirs();
50         }
51         IOUtils.copy(img.getInputStream(),new FileOutputStream(file));
52         return "/WEB-INF/05_upload_jsp/upload.jsp";
53     }
54 }
1 <!—文件上传:必须写:enctype="multipart/form-data"—>
2 <form action="/upload" method="post" enctype="multipart/form-data">
3        用户名:<input type="text" name="name"/><br/>
4        头像:<input type="file" name="img"/><br/>
5        <input type="submit" value="提交"/>
6   </form>
1 <!--     配置文件上传解析器:id="multipartResolver",这个id不能乱写 
2           设置一个maxUploadSize属性,就是上传文件的大小
3 -->
4     <bean id="multipartResolver"
5     class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
6         <property name="maxUploadSize">
7             <value>2000000000</value>
8         </property>
9    </bean>
 1 6.4.2.文件下载(还是原生Servlet方式)
 2 /**
 3      * 文件下载:原生的servlet
 4      * ①:设置response的头信息
 5      * ②:获取文件输出流
 6      * ③:获取需要下载的文件输入流
 7      * ④:文件流的拷贝
 8      * @param response
 9      * @param request
10      * @throws IOException
11      */
12     @RequestMapping("/downLoad")
13     public void downLoad(HttpServletResponse response,HttpServletRequest request) throws IOException{
14         //设置响应response的头信息和文件名
15         String filename="mm.jpg";
16         response.setHeader("Content-Disposition", "attachment; filename="+filename+"");
17         //获取文件输出流
18         OutputStream out=response.getOutputStream();
19         
20         //获取下载文件的地址
21         String filePath =request.getServletContext().getRealPath("/upload");
22         String fileAllPath=filePath+"/mm.jpg";
23         //获取文件输入流
24         FileInputStream in=new FileInputStream(fileAllPath);
25         //文件流拷贝
26         IOUtils.copy(in, out);
27     }
  1. 执行流程

 流程图

控制器=处理器(Handler)

      1. 用户向服务器发送请求,请求被SpringMVC前端控制DispatcherServlet捕获;

      2. DispatcherServlet通过调用HandlerMapping(处理器映射管理对象)获得该请求对应的Handler对象(包括控制器以及Handler对象对应的拦截器)

   HandlerExecutionChain对象(包含:控制器+2个拦截器);

      3. DispatcherServlet 根据获得的Handler,选择一个合适(管理Controller的方式:有xml方式和注解方式)的HandlerAdapter(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)

       4. 提取Request中的模型数据,填充Handler入参,开始执行HandlerController)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

      HttpMessageConveter: 将请求消息(如Jsonxml等数据)转换成一个对象,将对象转换为指定的响应信息

      数据转换:对请求消息进行数据转换。如String转换成IntegerDouble

      数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等

      数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResultError

      5.Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象

      6.根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;

      7. ViewResolver 结合Model和View,来渲染视图(Model+View合成)

      8. 将渲染结果返回给客户端

1.1. 简易描述(面试用)

  1. 客户端请求提交到DispatcherServlet

  2. DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller

  3. 通过Handler匹配一个合适HandlerAdapter ,通过HandlerAdapter 调用对象Controller方法。

  4. Controller调用业务逻辑处理后,返回ModelAndView

  5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。

  6. 视图负责将结果显示到客户端。

Converter  变换器;

DataBinder 数据连接器

 

  1. 核心对象                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

1.1. HandlerMapping 处理器映射管理对象

HanderMapping 处理器映射管理对象:

    作用:根据不同的请求选择最合适的处理器(自己编写的控制器),处理器映射管理对象可以配置多个,谁最先匹配就执行谁。

 SpringMVC默认:/org/springframework/web/servlet/DispatcherServlet.properties

 

 

 

Java程序员必会springmvc框架三大组件工作流程与struts2框架区别

SpringMVC围绕着Servlet进行开发Web,代码的实现上同时也依赖Spring开发,不然也不会叫做SpringMVC,本文着重强调的重点在于SpringMVC的工作流程,并不设计具体代码开发,所以并不要求掌握Spring的知识。

SpringMVC的处理流程为,用户访问的地址被DispathcherServlet的url-pattern匹配到后,

 

 

 

DispathcherServlet会在内部从Spring容器中拿到HandlerMapping对象

 

该对象内部有一个LinkedHashMap,

 在Spring容器初始化时,我们在@requestMapping中填写的url路径被存入这个map中作为Key值,一旦用户发送请求DispathcherServlet通过RequestMappingHandlerMapping中获取请求地址然后迭代这个Map寻求匹配的Key值,也就是我们在@requestMapping中写的路径,如果匹配成功就能够获取到我们的controller处理器的全包名和方法名

 这时候DispathcherServlet创建一个HandlerAdapter接口下的子类对象执行从map中获取的方法,也就是我们在controller编写的方法

 

 ,返回一个ModelAndView对象,DispathcherServlet又从SpringWeb容器中拿到ViewResolver对象,

ViewResolver对象能够将上面方法的返回值ModelAndView中的ViewName解析出,该ViewName就是我们写的/WebINFO/下的JSP页面的这段字符串,ViewResolver通过该地址将整个jsp页面解析成View对象,将对象返回给DispathcherServlet。然后调用processDispatchResult方法对页面进行渲染,也就是将controller处理后的model数据与ViewResolver返回的view对象进行渲染,就是将他们重新组合成了一个处理后的jsp页面对象返回给浏览器。

以上就是DispathcherServlet的工作流程了,可以说整个流程都是在DispathcherServlet的方法内部进行的,SpringMVC框架的三大组件处理器映射器,处理器适配器,和视图解析器都是由DispathcherServlet从Spring的webapp容器中获取的。非常有意思的设计,下面让我们来看看这三大组件都有哪些配置。

 

这是一个property文件,位于springmvc框架的依赖jar包下。红色框框标识出都是DispathcherServlet中的对象属性。

LocaleResolver 是一个国际化的解析器,它使用i18n国际化的标准能够为不同国家的展示不同语言的页面。ThemeResolver 用于防止注入式攻击。HandlerMapping 配置默认使用的requestMapping映射器。HandlerAdapter 配置默认使用的requestMapping适配器。HandlerExceptionResolver 异常解析器RequestToViewNameTranslator 请求jsp路径时的事务管理器ViewResolver 配置默认使用的r视图解析器。

等等等等,同类型Struts2框架有22种拦截器分别对应不同的功能,因为web层与用户进行直接交互所以功能相比service和dao都要复杂些。我们也可以在xml文件中自定义每个功能所使用的类。

我们可以在xml文件中手动指定想要使用的组件类型,只需要将该类注册到spring容器中即可,不需要配置其他东西。

该标签用于启动mvc的注解驱动,有这个标签相当于我们默认使用注解来表示请求路径,就是@requestMapping注解,默认在上面property文件中是启用的,所以这个标签可以不写。

InternalResourceViewResolver则是个很有用的功能,他能够为我们controller中set的ViewName补充前后缀。见下图

图中代码本是配置jsp页面的路径的,有了上面的配置后我们可以省略所以jsp页面共同的前后缀部分,最后拼接后的路径为/WIN-INF/asas.jsp。

 核心对象

1.1. HandlerMapping 处理器映射管理对象

HanderMapping 处理器映射管理对象:

    作用:根据不同的请求选择最合适的处理器(自己编写的控制器),处理器映射管理对象可以配置多个,谁最先匹配就执行谁。

   SpringMVC默认:/org/springframework/web/servlet/DispatcherServlet.properties

BeanNameUrlHandlerMapping

处理通过<bean name="/xxx">注册的控制器。控制器需要实现Controller接口。

DefaultAnnotationHandlerMapping

处理通过注解@Controller(类标签) @RequestMapping(方法标签) 注册的控制器。该处理器映射管理对象已经在Spring 3.2 版本过时,替换为RequestMappingHandlerMapping

spring 中提供的内置处理器映射:

简单url处理器映射

org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

(了解即可,现在已经基本不用了)

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

        <property name="mappings">

      <value>

      /helloworld(url 地址)=helloworldController(bean id)

      /helloworld002=helloworldController

      </value>

       </property>

     </bean>

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping  采用注解方式请求处理器映射。

使用<mvc:annotation-driven/>开启新的映射处理器。

 HandlerAdapter 处理器适配

作用:支持多种类型的处理器,如何来执行"处理器(控制器)" 如何执行我们的控制器。

Spring默认处理器适配:

org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter 处理实现了HttpRequestHandler接口对应的控制器

 org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter 处理实现了Controlle接口对应的控制器。

使用<mvc:annotation-driven/>开启新的处理器适配  

org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter  处理通过注解方式的控制器。 3.2中已过时,替换为org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

1.1. ViewResolver 视图解析器 (struts2视图类型类似)

作用:根据不同的视图,响应不同的结果,比如普通的jspjson.

SpringMVC默认:

 

  InternalResourceViewResolver : 支持默认视图,采用forward,redirect

视图名规则

    不写前缀默认为"转发"

    视图名字符串前缀:

   forward:/xxx.jsp 采用转发。

    redirect:/xxx.jsp  采用重定向。

    new ModelAndView("forward:/userList");

    new ModelAndView("redirect:/user");

注册(替换)视图解析器

设置视图路径的前后缀,该配置可以让我们写视图路径的时候更简单。

   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

  <property name="prefix" value="/WEB-INF/jsps/" />

  <property name="suffix" value=".jsp" />

</bean>

路径简写:

注意事项:"forward:""redirect:"前缀问题

页面不在前缀路径中的情况(或者页面路径不是以.jsp为后缀)

 课程总结

重点

Controller的实现方式全注解

参数的接收 在形参中使用java内置的类型接收(常用)

 在形参中使用domain接收(常用)

视图返回返回一个String的字符串

参数的返回json的返回

  

 

 

原文地址:https://www.cnblogs.com/wzscom/p/10514152.html