Spring MVC

Spring MVC

 

1.    Spring MVC 概述... 1-2

1.1.    企业级应用基本架构... 1-2

1.2.    Web MVC架构及分析... 1-2

1.3.    SpringMVC 架构及分析... 1-3

2.    Spring MVC编程基础... 2-4

2.1.    编程基本步骤... 2-4

2.2.    基于xml编程实现... 2-5

2.2.1.   创建MavenWEB 项目... 2-5

2.2.2.   添加SpringMVC 项目依赖及配置文件... 2-5

2.2.3.   配置前端控制器... 2-6

2.2.4.   创建后端控制器... 2-6

2.2.5.   创建JSP页面... 2-7

2.2.6.   配置后端控制及视图解析... 2-7

2.2.7.   部署到tomcat运行... 2-8

2.2.8.   运行原理分析... 2-8

2.3.    基于注解编程实现... 2-8

2.3.1.   创建MavenWEB 项目... 2-8

2.3.2.   添加SpringMVC 项目依赖及配置文件... 2-9

2.3.3.   配置前端控制器... 2-10

2.3.4.   创建后端控制器... 2-10

2.3.5.   配置组件扫描与视图解析... 2-11

2.3.6.   部署与运行... 2-11

3.    Spring MVC编程请求处理进阶... 3-11

3.1.    请求路径映射... 3-11

3.1.1.   普通url映射... 3-12

3.1.2.   Rest风格url映射... 3-12

3.2.    请求方式映射... 3-12

3.2.1.   请求方式限定... 3-12

3.2.2.   请求方式组合... 3-13

3.3.    请求参数映射... 3-13

3.3.1.   标准ServletAPI. 3-13

3.3.2.   直接量存储... 3-14

3.3.3.   Java bean对象... 3-14

3.3.4.   Rest url数据... 3-14

3.3.5.   请求头数据... 3-15

4.    Spring MVC响应处理进阶... 4-15

4.1.    响应数据封装... 4-16

4.1.1.   ModelAndView对象... 4-16

4.1.2.   Model对象... 4-16

4.1.3.   Map对象... 4-16

4.2.    响应数据转换... 4-17

4.2.1.   转换为json格式... 4-17

5.    Spring 拦截器应用... 5-18

5.1.    拦截器概述... 5-18

5.2.    拦截器编写及配置... 5-19

6.    Spring MVC异常处理... 6-21

6.1.    SpringMVC 异常概述... 6-21

6.2.    SpringMVC 异常处理... 6-22

7.    总结... 7-23

7.1.    重点和难点分析... 7-23

7.2.    常见FAQ.. 7-23

7.3.    作业... 7-23

 

1.     Spring MVC 概述

1.1.  企业级应用基本架构

企业级应用基本架构(C/S)以及SPRING在架构中的作用。

 

此架构图中spring要解决什么问题?

1)对象的构建,对象的依赖管理。(重点是从资源使用角度进行分析)

2)扩展业务的动态切入。(基于OCP更好实现功能扩展,同时进行解耦)

3)简化传统web mvc架构中的一些细节处理问题(参数获取,校验,值的注入,响应方式及数据格式的转换)。

 

问题:

1)我们一般说的解耦是没有耦合吗?不是,所有软件系统中的对象之间

都会存在耦合,只是要把耦合降低。

2)降低耦合的最主要目的是什么?就是要提高系统的可维护性,便于系统进行更好的升级扩展。

3)降低耦合的主要实现方式?

3.1)对象之间的耦合尽量耦合与接口与工厂

3.2)代码的重用尽量使用组合而非继承。(has a 取代 is a)

 

1.2.  Web MVC架构及分析

基于servlet,jsp,javabean技术实现的MVC架构

 

问题:

1)假如我们没有使用spring mvc,你如何对系统采用mvc思想进行分层?(参考jsp+servlet+javabean奇数)

 

2)传统的web mvc 编程架构中有什么优势,劣势?

优势:结构层次更加清晰,可读性,可维护性相对较好

劣势:参数获取,类型转换,流程调用相对都比较复杂

 

3)市场上相对比较成熟的mvc框架:spring mvc,struts2,….

1.3.  Spring MVC 架构及分析

 

Spring MVC是MVC架构模式的一种完美实现,它简化了Java WEB 中基于MVC架构的编程过程,是Spring中的WEB应用模块。其官方MVC概要架构图如下:

 

 

Spring MVC 底层核心架构图及工作流程(先了解,写完项目案例再重点强化)

 

Spring MVC 中的核心组件:

 

1)  DispatcherServlet (前端控制器, 处理请求的入口)

2)  HandlerMapping (映射器对象, 用于管理url与对应controller的映射关系)

3)  Controller (后端控制器, 负责处理请求的控制逻辑)

4)  ModelAndView (模型, 封装业务处理结果和视图)

5)  ViewResolver(视图解析器,解析对应的视图关系:前缀+view+后缀)

 

备注:假如希望了解Spring MVC的详细处理流程可以基于断点调试法进行跟踪。

2.     Spring MVC 编程基础

2.1.  编程基本步骤

 

Step01:创建maven web 项目并解决项目中的错误问题

Step02:添加项目依赖(spring-webmvc)及spring核心配置文件

Step03:配置前端控制器DispatcherServlet(web.xml)

Step04:创建后端控制器(Controller)及页面

Step05:spring配置文件中配置核心应用组件

Step06:部署及测试springmvc 应用。

 

2.2.  基于xml编程实现

2.2.1. 创建Maven WEB 项目

Web项目打包方式为war方式

Web项目的target runtimes为tomcat

Web 项目的编译版本为JDK1.8

 

可能会遇到的问题:

1)war项目默认不会创建web.xml(需要自己生成)

2)项目创建好需要设置运行时环境tomcat(多个tomcat时选哪个)

3)统一编译版本(版本不统一很有可能会出现项目不编译)

4)统一编码(UTF-8)

5)假如创建的项目还有问题,可对项目进行clean操作

 

2.2.2. 添加Spring MVC 项目依赖及配置文件

打开项目的pom.xml文件,然后添加依赖(选择组groupId为org.springframework)

 

<dependencies>

<dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-webmvc</artifactId>

        <version>4.3.9.RELEASE</version>

</dependency>

<dependencies>

 

 

假如添加好了依赖,都没有找到对应的jar依赖,先检测网络是否是通的.假如网络是通的,还没有下载到具体的依赖,此时要右键项目,选择maven/upate maven project/foreupdate…进行maven强制更新操作.

 

在项目的resource的目录中添加核心配置文件applicationContext.xml,例如:

 

<?xmlversion="1.0"encoding="UTF-8"?>

<beansdefault-lazy-init="true"

    xmlns="http://www.springframework.org/schema/beans"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xmlns:util="http://www.springframework.org/schema/util"

    xmlns:jpa="http://www.springframework.org/schema/data/jpa"

    xsi:schemaLocation=

      http://www.springframework.org/schema/beans  

      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 

      http://www.springframework.org/schema/mvc  

      http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd  

      http://www.springframework.org/schema/tx  

      http://www.springframework.org/schema/tx/spring-tx-4.3.xsd  

      http://www.springframework.org/schema/aop

      http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

      http://www.springframework.org/schema/util

      http://www.springframework.org/schema/util/spring-util-4.3.xsd

      http://www.springframework.org/schema/data/jpa

      http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd

      http://www.springframework.org/schema/context

      http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      

</beans>

 

 

说明:配置文件的名字需要自己定义,当这个空的配置文件中的某行有相关错误

时,先去检测网络是不是通的。

 

2.2.3. 配置前端控制器

打开web.xml,配置DispatcherServlet对象

 

  <servlet>

     <servlet-name>dispatcherServlet</servlet-name>

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

     <init-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>classpath:applicationContext.xml</param-value>

     </init-param>

     <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

     <servlet-name>dispatcherServlet</servlet-name>

     <url-pattern>*.do</url-pattern>

  </servlet-mapping>

前端控制器是springmvc处理请求的入口,是springmvc的核心,这个控制器一般需要在服务器启动时即初始化。

其中

1)     load-on-startup 表示启动时则加载此servlet

2)     init-param 中的参数名不能变(此名字在DispatcherServlet父类中定义)

 

 

 

2.2.4. 创建后端控制器

后端控制器编写时可以实现Controller接口,然后重写handleRequest方法处理请求

public class HelloController implements Controller{

    publicModelAndView handleRequest(HttpServletRequestrequest){

       ModelAndView mv=new ModelAndView("hello");

       mv.addObject("message","helloworld");

       returnmv;

    }

}

 

其中:

ModelAndView对象为一个模型与视图对象,内置一个map对象,主要用于封装业务数据和视图名。

ModelAndView构造方法中传递的为视图名,addObject方法可以以key/value形式存储数据。

ModelAndView 对象返回时会被spring mvc自动存储到请求作用域,在对应的视图页面可以直接从此作用域获取对应的值。

 

2.2.5. 创建JSP页面

 

在项目的WEB-INF/pages文件夹下创建hello.jsp文件,然后设置其内容,例如

 

<body>

   <h1>${message}</h1>

</body>

 

2.2.6. 配置后端控制及视图解析

在spring mvc 核心配置文件中添如下配置。

 

<!-- 将Controller这个Bean对象交给Spring管理 -->

<bean id="helloController"class="spring.controller.XmlHelloController">

</bean>

<!-- 配置HandlerMapping 映射处理器配置url到具体的Controller之间的映射-->

 <beanclass="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

             <propertyname="mappings">

                  <props>

                     <propkey="/hello.do">helloController</prop>

                  </props>

             </property>

  </bean>

  <!-- 配置视图解析器 -->

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

            <propertyname="prefix"value="/WEB-INF/pages/"/>

            <propertyname="suffix"value=".jsp"/>

</bean>

 

2.2.7. 部署到tomcat运行

将项目部署到tomcat,然后启动运行,在地址栏输入具体url访问对应controller。

 

问题:

1)tomcat启动时出现ClassNotFoundException,而这个class又不是我们自己的类,此时要重新maven update,重新发布(右键tomcat 重新publish),多次尝试还是不可以,此时重启eclipse。

2)404异常,一般表示服务端资源没找到,首先检测访问路径是否正确,然后还可以在项目的部署目录中去查找对应的资源,必须确保资源是存在的,假如资源不存在,说明代码没有正常编译。(很常见)

 

3)如何解决这种项目不编译的问题?

 

step01) 将tomcat下的项目移除,clean你的tomcat服务器

step02) 将项目的jre从buildpath移除,然后重新添加

step03) 对项目先进行maven clean操作(清除原先编译结构,然后重新编译)

step04) 再次对项目进行clean操作

step05) 重新部署项目,启动tomcat运行

 

4)运行项目时尽量不要右键运行选在run as /run on server

 

2.2.8. 运行原理分析

本应用的简易处理流程如下:

 

 

2.3.  基于注解编程实现

 

2.3.1. 创建Maven WEB 项目

Web项目打包方式为war方式

Web项目的target runtimes为tomcat

Web 项目的编译版本为JDK1.8

2.3.2. 添加Spring MVC 项目依赖及配置文件

打开项目的pom.xml文件,然后添加依赖

 

 

<dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-webmvc</artifactId>

        <version>4.3.9.RELEASE</version>

</dependency>

 

 

假如添加好了依赖,都没有找到对应的jar依赖,先检测网络是否是通的.假如网络是通的,还没有下载到具体的依赖,此时要右键项目,选择maven/upate maven project/foreupdate…进行maven强制更新操作.

 

在项目的resource的目录中添加核心配置文件applicationContext.xml,例如:

 

<?xmlversion="1.0"encoding="UTF-8"?>

<beansdefault-lazy-init="true"

    xmlns="http://www.springframework.org/schema/beans"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xmlns:util="http://www.springframework.org/schema/util"

    xmlns:jpa="http://www.springframework.org/schema/data/jpa"

    xsi:schemaLocation=

      http://www.springframework.org/schema/beans  

      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 

      http://www.springframework.org/schema/mvc  

      http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd  

      http://www.springframework.org/schema/tx  

      http://www.springframework.org/schema/tx/spring-tx-4.3.xsd  

      http://www.springframework.org/schema/aop

      http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

      http://www.springframework.org/schema/util

      http://www.springframework.org/schema/util/spring-util-4.3.xsd

      http://www.springframework.org/schema/data/jpa

      http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd

      http://www.springframework.org/schema/context

      http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      

</beans>

 

 

2.3.3. 配置前端控制器

打开web.xml,配置DispatcherServlet对象

<servlet>

     <servlet-name>dispatcherServlet</servlet-name>

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

     <init-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>classpath:applicationContext.xml</param-value>

     </init-param>

     <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

     <servlet-name>dispatcherServlet</servlet-name>

     <url-pattern>*.do</url-pattern>

  </servlet-mapping>

前端控制器是springmvc处理请求的入口,是springmvc的核心。

 

2.3.4. 创建后端控制器

 

@Controller

@RequestMapping("/")

publicclass AnnotationHelloController {

    @RequestMapping("doSayHello")

    public String doSayHello() {

        ModelAndViewmv=new ModelAndView("hello");

        mv.addObject("message","helloworld");

        return"hello";

    }

}

 

其中

通过@RequestMapping注解定义url到controller具体方法的映射。

 

2.3.5. 配置组件扫描与视图解析

 

在spring mvc 核心配置文件中添加

 

 

<!-- 配置组件扫描 -->

<context:component-scanbase-package="com.company"/>

<!—启用MVC注解扫描 -->

<mvc:annotation-driven/>

<!-- 配置视图解析器 -->

<bean id="viewResolver"

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

     <propertyname="prefix"value="/WEB-INF/pages/"/>

     <propertyname="suffix"value=".jsp"/>

</bean>

 

      

2.3.6. 部署与运行

将项目部署到tomcat,然后启动运行,在地址栏输入具体url访问对应controller。

 

3.     Spring MVC 编程请求处理进阶

3.1.  请求路径映射

实际项目中我们要借助@RequestMapping注解定义映射路径。其注解应用位置

 

ü  类定义处: 提供初步的请求映射信息。

ü  方法定义处: 提供进一步的细分映射信息

 

3.1.1. 普通url映射

 

@RequestMapping(value={"/doSayHello","/user/doSayWelcome"}):

 

多个URL路径可以映射到同一个处理器的功能处理方法。

 

3.1.2. Rest风格url映射

 

REST即表述性状态传递(英文:RepresentationalState Transfer,简称REST),是一种软件架构编码风格,是基于网络应用进行设计和开发的编码方式。可以降低开发的复杂度,提高程序的可伸缩性。例如:

 

@RequestMapping("/msg/{xxx}")

请求的URL可以是“/msg/hello”或“/msg/welcome”

 

@RequestMapping("/msg/{id}/create"):

请求的URL可以是“/users/1/create”。

 

@RequestMapping("/msg/{mId}/topics/{tId}")

这样也是可以的,请求的URL可以是“/users/10/topics/12”。

 

说明:通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。

 

http://localhost:8080/项目名/doUpdate/1.do

 

 

3.2.  请求方式映射

 

3.2.1. 请求方式限定

 

项目中Controller层对象的每个方法默认可以处理任意方式的请求,假如要指定控制层方法只能处理GET或只能处理POST请求,那该如何实现呢?

 

借助@RequestMapping注解中的method属性指定具体的请求处理方式,例如

 

@RequestMapping(value=”doSaveObj”,

method=RequestMethod.POST)

public StringdoSaveObject(Object obj){….}

 

3.2.2. 请求方式组合

 

项目中还可在控制层方法上借助@RequestMapping注解中的method属性指定使用哪几种方式处理请求。

@RequestMapping(value=”doSaveObj”,

method={RequestMethod.POST,

RequestMethod.GET})

public StringdoSaveObject(Object obj){….}

 

 提示:一般浏览器只支持GET或POST方式。

 

 

 

3.3.  请求参数映射(重点)

 

3.3.1. 标准Servlet API

 

请求映射方法中可以直接使用ServletAPI中的对象获取参数数据,例如

HttpServletRequest,HttpSession对象等,例如:

 

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

@ResponseBody

public StringwithRequest(HttpServletRequestrequest){

       System.out.println(request.getRequestURI());

       return"Obtainer 'foo' query parameter value

'"+request.getParameter("gid")+"'";

    }

 

提示:@ResponseBody注解作用:该注解作用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,而是其他数据格式的数据时,(如Json、xml,普通文本等)使用;

 

3.3.2. 直接量存储

SpringMVC 请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型要为对象类型。

 

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

@ResponseBody

public String withParam(@RequestParam Stringfoo){

    return"Obtained 'foo' query parameter value '"+foo + "'";

}

 

提示:@RequestParam注解用于接收请求参数中名字为foo的参数值,假如请求参数名与方法中的参数名一致,@RequestParam注解可以省略。假如不一致则可以使用@RequestParam注解定义新的参数名直接接收页面数据,然后传递给方法名,例如

 

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

@ResponseBody

public String withParam(

@RequestParam(value="param1",required=false) Stringfoo){

       return"Obtained 'foo' query parameter value '"+foo + "'";

}

 

提示:required=false表示,参数可以不存在,假如为true,参数不存在时会抛出异常。

 

3.3.3. Java bean对象

当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数数据以简化多个参数变量的定义。

 

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

@ResponseBody

public StringwithParamGroup(Messagebean) {

       return"Obtained parameter group " +bean;

}

 

提示:当使用javabean接收请求参数数据时,bean中需要有与参数名对应的set方法。

 

3.3.4. Rest url数据

 

SpringMVC请求资源路径的URL可以通过{XXX}形式指定动态的URL,动态URL中的这个可变参数的值可以直接注入到方法对应的参数中。

 

@RequestMapping(value="path/{var}",method=RequestMethod.GET)

@ResponseBody

public StringwithPathVariable(@PathVariable Stringvar) {

    return"Obtained 'var' path variable value '"+var + "'";

}

 

通过@PathVariable注解指定参数变量var获取请求url中{var}数据

 

3.3.5. 请求头数据

 

当服务端要获取客户端请求头中数据信息时,可通过@RequestHeader即可将请求头中

的属性值绑定到处理方法的入参中,例如获取请求中Accept属性的值,然后传入到对应方法的参数中。

 

 

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

@ResponseBody

public String withHeader(@RequestHeader StringAccept){

       return"Obtained 'Accept' header '" +Accept + "'";

}

 

假如希望在此方法中直接从cooke取值,可以定义参数时使用@CookieValue对参数进行修饰,参数名一般要与cookie对象中的key相同

 

提示:方法中的参数名需要与请求头参数中某个某个参数名相同,具体请求头相关信息可以在浏览器控制台查看。

 

当应用中要获取请求中所有数据时可以在请求方法中定义一个HttpEntity<String>参数,通过此参数获取请求头及请求体中数据,例如

 

@RequestMapping(value="entity", method=RequestMethod.POST)

public @ResponseBody StringwithEntity(HttpEntity<String> entity) {

       return"Posted request body '" +entity.getBody() + "';

 headers = " + entity.getHeaders();

}

 

 

4.     Spring MVC 响应处理进阶

 

4.1.  响应数据封装

4.1.1. ModelAndView 对象

 

在对服务端响应数据进行封装时,可以直接在方法参数中定义一个ModelAndView类型的参数,借助ModelAndView对象封装响应数据.

 

@RequestMapping("doModelAndView")

public ModelAndViewdoModelAndView(ModelAndViewmv) {

       //ModelAndView mv=new ModelAndView();

       mv.addObject("data","model andview");

       mv.setViewName("back");

       returnmv;

}

 

提示:ModelAndView对象由Spring创建,并可以将数据存储到ModelAndView对象的ModalMap类型的属性中(可参考源代码).

 

 

4.1.2. Model对象

将响应数据直接封装为model中。

 

@RequestMapping("doModel")

publicString doModel(Modelmodel) {

      

       model.addAttribute("data","modal");

       return"back";

}

 

4.1.3. Map对象

将响应数据封装到Map中。

 

@RequestMapping("doMap")

publicString doMap(Map<String,Object>map) {

    map.put("data","map..");

    return"back";

}

 

说明:  通过map接收页面参数时,需要使用@RequestParam注解声明

 

@RequestMapping("doMap")

publicString doMap(@RequestParam Map<String,Object>map) {

    map.put("data","map..");

    return"back";

}

 

 

4.2.  响应数据转换

4.2.1. 转换为json格式

 

JSON(JavaScript Object Notation):一种轻量级数据交换格式,通常用于实现客户端与服务端之间的数据传输.

例如

JSON格式的JavaScript对象:

 

varo1={id:10,name:’a’,age:20}

varo2=[{id:10,name:’a’,age:20},{id:20,name:’B’,age:30}]

 

访问json格式的javascript对象中的数据

var id1=o1.id;

var id2=o2[0].id

 

在实际的项目中,通常会将服务端返回的数据直接转换JSON格式字符串,在客户端将这个字符串再转换为javascript对象,然后从这个对象直接取数据.

 

在将Java对象转换为JSON串时一般首先要添加第三方法的JSONAPI 库,通过这样的库可以很方便的实现实现Java对象到JSON串的转换。

 

例如:我们以JACKSON 为例进行分析

 

将Map对象内容转换为字符串

 

@RequestMapping("doJSON")

@ResponseBody

publicMap<String,Object> doJSON() {

    Map<String,Object>map=new HashMap<String, Object>();

    map.put("id", 10);

    map.put("msg","helloworld");

    returnmap;

}

 

 

将JavaBean对象转换为JSON串

@RequestMapping("doBeanToJson")

    @ResponseBody

    public Message doBeanToJson(){

       Message msg=new Message();

       msg.setId(100);

       msg.setContent("msg-content-1");

       return msg;

    }

 

将Java List集合转换为JSON串。

@RequestMapping("doListToJson")

    @ResponseBody

    public List<Map<String,Object>> doListToJson(){

       List<Map<String,Object>>list=

       new ArrayList<>();

       Map<String,Object>map=new HashMap<>();

       map.put("id", 10);

       map.put("content","content-A");

       list.add(map);

      

       map=new HashMap<>();

       map.put("id", 20);

       map.put("content","content-B");

       list.add(map);

       returnlist;

    }

 

备注:将来controller中数据来自服务端数据。

 

5.     Spring 拦截器应用

 

5.1.  拦截器概述

拦截器是SpringMVC中的一个核心应用组件,主要用于处理多个

Controller的共性问题.当我们的请求由DispatcherServlet派发

到具体Controller之前首先要执行拦截器中一些相关方法,在这些

方法中可以对请求进行相应预处理(例如权限检测,参数验证),这些方法可以决定对这个请求进行拦截还是放行.

通过spring mvc 架构图分析,拦截器在Spring MVC中处理流程中的一个位置

 

回顾Spring MVC详细架构图

 

 

思考:假如对请求数据进行编码,是应在过滤器还是拦截器?

 

5.2.  拦截器编写及配置

 

 

拦截器如何编写?

 

我们自己编写SpringMVC拦截器需要实现HandlerInterceptor接口或者继承此接口的实现类HandlerInterceptorAdapter(继承这个类时可根据需求重写必要的方法)

 

publicclass SysUserInterceptorimplementsHandlerInterceptor {

    @Override

    publicboolean preHandle(

            HttpServletRequestrequest,

            HttpServletResponseresponse, Object handler)

            throws Exception {

            System.out.println("preHandle");

        returntrue;//表示放行

    }

    @Override

    publicvoid postHandle(

            HttpServletRequestrequest,

            HttpServletResponseresponse,

            Objecthandler,

            ModelAndViewmodelAndView)

            throws Exception {

            System.out.println("postHandler"

                +".modelAndView="+modelAndView);

    }

    @Override

    publicvoid afterCompletion(

            HttpServletRequestrequest,

            HttpServletResponseresponse,

            Objecthandler,

            Exceptionex)

            throws Exception {

            System.out.println("afterCompletion.handler="+

            handler.getClass());

    }

}

 

这些方法的简易执行流程点如下图所示:

 

这些方法的详细的执行时间点如下:

 

 

我们自己的拦截器编写完成以后需要在spring配置文件中进行配置,,

例如:

 

<mvc:interceptors>

          <mvc:interceptor>

            <!--指定拦截哪些请求路径 -->

            <mvc:mappingpath="/**"/>

            <!--排除要拦截的路径 -->

            <mvc:exclude-mappingpath="/sys/doLogin.do"/>

            <!--拦截器 -->

            <beanclass="cn.spring.mvc.interceptor.SysUserInterceptor"/>

          </mvc:interceptor>

</mvc:interceptors>

 

 

当我们系统中有多个拦截器时,这些拦截器可以构成一个拦截器链.其原理类似过滤器中的过滤链。在多个拦截器应用中仅当所有匹配的拦截器的preHandle()都执行之后,才会调用Controller中处理请求的方法,然后再执行所有匹配的拦截器的postHandler(),再执行所有匹配的拦截器的afterCompletion()。

 

在拦截器链中,各拦截器的执行先后顺序取决于配置文件中配置的节点的先后顺序!

 

6.     Spring MVC异常处理

 

6.1.  Spring MVC 异常概述

实际项目中我们经常会采用分层架构设计程序,每一层都可能会有异常,假如异常信息没有处理,可能会选择抛出,假如这些被抛出的异常与具体业务相关,那到控制层以后我们一般都进行相应的处理(处理方式应该相对友好)

 

在Spring mvc 项目中,边界出现异常以后我们通常会在Controller中进行处理,常用分层架构中的异常分析:

 

 

在分层架构中,异常可能会从DAO层逐步抛出到控制层,可以在控制层对异常进行相关处理。

 

6.2.  Spring MVC 异常处理

 

在spring中处理异常时,通常会在Controller中定义具体的异常处理方法,这个方法上使用@HandlerException注解进行描述.例如在指定Controller中定义异常处理方法:

 

@ExceptionHandler(value=Exception.class)

@ResponseBody

public StringhandleException(Exception e){

    System.out.println("局部异常处理");

    returne.getMessage();

}

 

 

当Spring的controller中没有定义具体的异常方法,我们外部定义一个全局的异常处理类,这个类使用@ControllerAdvice注解进行修饰.然后在这个类中定义具体的异常处理方法,这些方法再使用@HandlerExcpeiton进行修饰,例如

 

@ControllerAdvice

publicclass AdviceExceptionHandler {

    @ExceptionHandler(Throwable.class)

    @ResponseBody

    publicStringhandlerException(Throwable e){

       System.out.println("全局的异常处理");

       returne.getMessage();

    }

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值