0
点赞
收藏
分享

微信扫一扫

springMVC学习笔记

小亦同学321 2022-02-10 阅读 65

目录

springMVC

MVC概念

什么是SpringMVC

SpringMVC的特点

基本环境配置

Maven依赖

配置web.xml

springMvc配置文件

解析器的配置

@RequestMapping注解

1 @RequestMapping注解使用

2 @RequestMapping注解的value属性

3 @RequestMapping注解的method属性

4 @RequestMapping注解的params属性

5 @RequestMapping注解的headers属性

6 SpringMVC支持ant风格的路径

7 SpringMVC支持路径中的占位符

SpringMVC获取请求参数

1、通过ServletAPI获取

2、通过控制器方法的形参获取请求参数

3、@RequestParam

4、@RequestHeader

5、@CookieValue

6、通过POJO获取请求参数

7、解决获取请求参数的乱码问题

域对象共享数据

1、使用ServletAPI向request域对象共享数据

2、使用ModelAndView向request域对象共享数据

3、使用Model向request域对象共享数据

4、使用map向request域对象共享数据

5、使用ModelMap向request域对象共享数据

6、向session域共享数据

SpringMVC的视图

1、ThymeleafView

2、转发视图

3、重定向视图

视图控制器view-controller

HttpMessageConverter 报文信息转换器

1.@RequstBody注解

2.RequestEntity对象

3.@ResponseBody注解

4.@ResponseBody返回对象

5.@ResponseBody接收ajax请求,并返回对象

6.@RestController注解

文件上传与下载

文件下载

文件上传

拦截器

1.拦截器配置

2.拦截器实现类需要实现HandlerInterceptor类并重写方法

3.拦截器的三个抽象方法

4、多个拦截器的执行顺序

spring异常处理

配置文件方式

注解方式

配置类注解开发MVC

1.创建初始化类,代替web.xml

2.springMVC配置类 代替springMVC的配置文件

SpringMVC的执行流程

SpringMVC常用组件


springMVC

学尚硅谷版springMvc做的笔记

MVC概念

MVC 是一种软件架构的思想,将软件按照模型、视图、控制器来划分

M Model ,模型层,指工程中的 JavaBean ,作用是处理数据

V View ,视图层,指工程中的 html jsp 等页面,作用是与用户进行交互,展示数据

C Controller ,控制层,指工程中的 servlet ,作用是接收请求和响应浏览器

什么是SpringMVC

SpringMVC Spring 的一个后续产品,是 Spring 的一个子项目

SpringMVC Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust

WebWork Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目

表述层开发的 首选方案

SpringMVC的特点

Spring 家族原生产品 ,与 IOC 容器等基础设施无缝对接

基于原生的 Servlet ,通过了功能强大的 前端控制器 DispatcherServlet ,对请求和响应进行统一

处理 表述层各细分领域需要解决的问题全方位覆盖 ,提供 全面解决方案

代码清新简洁 ,大幅度提升开发效率

内部组件化程度高,可插拔式组件 即插即用 ,想要什么功能配置相应组件即可

性能卓著 ,尤其适合现代大型、超大型互联网项目要求

基本环境配置

Maven依赖

<modelVersion>4.0.0</modelVersion>

<groupId>groupId</groupId>
<artifactId>Spring_MVC</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
    <maven.compiler.source>12</maven.compiler.source>
    <maven.compiler.target>12</maven.compiler.target>
</properties>
<dependencies>
    <!-- SpringMVC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.1</version>
    </dependency>

    <!-- 日志 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>

    <!-- ServletAPI -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- Spring5和Thymeleaf整合包 -->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
        <version>3.0.12.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.12.1</version> 
    </dependency>
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
</dependencies>

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>

    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:SpringMVC-config.xml</param-value>
        </init-param>
<!--        将前端控制器DispatcherServlet的初始化启动时间改为启动服务器启动-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

springMvc配置文件

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.springMVC.*"></context:component-scan>
<!--配置Thymeleaf视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="order" value="1"></property>
        <property name="characterEncoding" value="UTF-8"></property>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <property name="prefix" value="/WEB-INF/templates/"></property>
                        <property name="suffix" value=".html"></property>
                        <property name="templateMode" value="HTML5"></property>
                        <property name="characterEncoding" value="UTF-8"></property>
                    </bean>
                </property>
            </bean>
        </property>
</bean>

    <mvc:view-controller path="/" view-name="index" ></mvc:view-controller>
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
    <mvc:annotation-driven></mvc:annotation-driven>

解析器的配置

默认解析器

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jspweb/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

thymeleaf解析器

<!--配置Thymeleaf视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="order" value="1"></property> //优先级
        <property name="characterEncoding" value="UTF-8"></property> //字符编码
        <property name="templateEngine"> //DI注入模板引擎
           <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> //spring模板引擎
              <property name="templateResolver">//DI注入模板解析器
                //spring模板解析器
               <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                 <property name="prefix" value="/WEB-INF/templates/"></property> //前缀
                 <property name="suffix" value=".html"></property> //后缀
                 <property name="templateMode" value="HTML5"></property> //类型为HTML5
                 <property name="characterEncoding" value="UTF-8"></property> //字符编码为UTF-8
                 </bean>
                </property>
            </bean>
        </property>
</bean>

@RequestMapping注解

1 @RequestMapping注解使用

@Controller 
@RequestMapping("/test")
 public class RequestMappingController { 
//此时请求映射所映射的请求的请求路径为:/test/testRequestMapping 

@RequestMapping("/testRequestMapping") 
public String testRequestMapping(){
 return "success";
 }
 }

2 @RequestMapping注解的value属性

@RequestMapping( value = {"/testRequestMapping", "/test"} )
public String testRequestMapping(){ 
return "success";
 }

3 @RequestMapping注解的method属性

@RequestMapping(
 value = {"/testRequestMapping", "/test"}, method = {RequestMethod.GET, RequestMethod.POST} )
public String testRequestMapping(){
 return "success"; 
}

4 @RequestMapping注解的params属性

@RequestMapping(
 value = {"/testRequestMapping", "/test"} ,
method = {RequestMethod.GET, RequestMethod.POST} ,
params = {"username","password!=123456"} )
public String testRequestMapping(){ 
return "success";
 }

5 @RequestMapping注解的headers属性

  @RequestMapping注解的 headers属性通过请求的请求头信息匹配请求映射

@RequestMapping注解的 headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信 息和请求映射的匹配关系

"header":要求请求映射所匹配的请求必须携带 header请求头信息

"!header":要求请求映射所匹配的请求必须不能携带 header请求头信息

"header=value":要求请求映射所匹配的请求必须携带 header 请求头信息且header=value

"header!=value":要求请求映射所匹配的请求必须携带 header 请求头信息且header!=value

6 SpringMVC支持ant风格的路径

?:表示任意的单个字符

*:表示任意的0个或多个字符

**:表示任意的一层或多层目录

注意:在使用**时,只能使用/**/xxx的方式

7 SpringMVC支持路径中的占位符

@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id") String id, @PathVariable("username")
String username){
System.out.println("id:"+id+",username:"+username);
return "success";
}
//最终输出的内容为-->id:1,username:admin

SpringMVC获取请求参数

1、通过ServletAPI获取

HttpServletRequest 作为控制器方法的形参,此时 HttpServletRequest 类型的参数表示封装了当前请 求的请求报文的对象

@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:"+username+",password:"+password);
return "success";
}

2、通过控制器方法的形参获取请求参数

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在 DispatcherServlet中就会将请求参数赋值给相应的形参

@RequestMapping("/testParam")
public String testParam(String username, String password){
System.out.println("username:"+username+",password:"+password);
return "success";
}

3@RequestParam

@RequestParam是将请求参数和控制器方法的形参创建映射关系

@RequestParam注解一共有三个属性:

value :指定为形参赋值的请求参数的参数名

required 设置是否必须传输此请求参数,默认值为 true

若设置为 true 时,则当前请求必须传输 value 所指定的请求参数,若没有传输该请求参数,且没有设置 defaultValue属性,则页面报错 400 Required String parameter 'xxx' is not present ;若设置为

false ,则当前请求不是必须传输 value 所指定的请求参数,若没有传输,则注解所标识的形参的值为 null

defaultValue 不管 required 属性值为 true false ,当 value 所指定的请求参数没有传输或传输的值

"" 时,则使用默认值为形参赋值

4@RequestHeader

@RequestHeader是将请求头信息和控制器方法的形参创建映射关系

@RequestHeader注解一共有三个属性:valuerequireddefaultValue,用法同@RequestParam

5@CookieValue

@CookieValue是将cookie数据和控制器方法的形参创建映射关系

@CookieValue注解一共有三个属性:valuerequireddefaultValue,用法同@RequestParam

6、通过POJO获取请求参数

可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实 体类中的属性名一致,那么请求参数就会为此属性赋值

7、解决获取请求参数的乱码问题

解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是 必须在web.xml中进行注册

<!--配置springMVC的编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-
class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

域对象共享数据

1、使用ServletAPIrequest域对象共享数据

@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
request.setAttribute("testScope", "hello,servletAPI");
return "success";
}

2、使用ModelAndViewrequest域对象共享数据

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
/**
* ModelAndView有Model和View的功能
* Model主要用于向请求域共享数据
* View主要用于设置视图,实现页面跳转
*/
ModelAndView mav = new ModelAndView();
//向请求域共享数据
mav.addObject("testScope", "hello,ModelAndView");
//设置视图,实现页面跳转
mav.setViewName("success");
return mav;
}

3、使用Modelrequest域对象共享数据

@RequestMapping("/testModel")
public String testModel(Model model){
model.addAttribute("testScope", "hello,Model");
return "success";
}

4、使用maprequest域对象共享数据

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
map.put("testScope", "hello,Map");
return "success";
}

5、使用ModelMaprequest域对象共享数据

@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
modelMap.addAttribute("testScope", "hello,ModelMap");
return "success";
}

6、向session域共享数据

@RequestMapping("/testSession")
public String testSession(HttpSession session){
session.setAttribute("testSessionScope", "hello,session");
return "success";
}

7、向 application 域共享数据

@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
ServletContext application = session.getServletContext();
application.setAttribute("testApplicationScope", "hello,application");
return "success";
}

SpringMVC的视图

SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户

SpringMVC视图的种类很多,默认有转发视图和重定向视图

当工程引入 jstl 的依赖,转发视图会自动转换为 JstlView

若使用的视图技术为 Thymeleaf ,在 SpringMVC 的配置文件中配置了 Thymeleaf 的视图解析器,由此视 图解析器解析之后所得到的是ThymeleafView

1ThymeleafView

当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被 SpringMVC 配置文件中所配置 的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式实现跳转

2、转发视图

SpringMVC中默认的转发视图是InternalResourceView

SpringMVC中创建转发视图的情况:

当控制器方法中所设置的视图名称以 "forward:" 为前缀时,创建 InternalResourceView 视图,此时的视 图名称不会被SpringMVC 配置文件中所配置的视图解析器解析,而是会将前缀 "forward:" 去掉,剩余部 分作为最终路径通过转发的方式实现跳转

例如"forward:/","forward:/employee"

@RequestMapping("/testForward")
public String testForward(){
return "forward:/testHello";
}

3、重定向视图

SpringMVC中默认的重定向视图是RedirectView

当控制器方法中所设置的视图名称以 "redirect:" 为前缀时,创建 RedirectView 视图,此时的视图名称不 会被SpringMVC 配置文件中所配置的视图解析器解析,而是会将前缀 "redirect:" 去掉,剩余部分作为最 终路径通过重定向的方式实现跳转

例如"redirect:/","redirect:/employee"

@RequestMapping("/testRedirect")
public String testRedirect(){
return "redirect:/testHello";
}

视图控制器view-controller

<!--
path:设置处理的请求地址
view-name:设置请求地址所对应的视图名称
-->
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>

HttpMessageConverter 报文信息转换器

1.@RequstBody注解

注解加在方法参数项

@RequestMapping("/RequestBody")
public  String RequestBody(@RequestBody String RequestBody){
    System.out.println(RequestBody);
    return  "index1";
}
//输出结果例:user=root  为传过来的参数

2.RequestEntity对象

使用RequestEntity作为参数

@RequestMapping("/RequestEntity")
public  String RequestEntity(RequestEntity<String> RequestEntity){
    System.out.println(RequestEntity.getHeaders());
    System.out.println(RequestEntity.getBody());
    return  "index1";
}
//第一个会输出整个请求头信息
//第二个例:user=root 输出传过来的参数

3.@ResponseBody注解

@RequestMapping("/ResponseBody")
@ResponseBody
public  String ResponseBody(){
       //使用springMVC中的Response 在@RequestMapping注解下面加上@ResponseBody   
       // return "ResponseBody" 相当于Response.getWrite.write("ResponseBody");
       return "ResponseBody";
}

4.@ResponseBody返回对象

导入json依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.1</version>
</dependency>

返回对象

 @RequestMapping("/ResponseBodyUser")
 @ResponseBody
 public User ResponseBodyUser(){
//   @ResponseBody返回对象
     return new User(10,"roor","root");
 }

5.@ResponseBody接收ajax请求,并返回对象

返回对象

@RequestMapping("/ResponseBodyajax")
@ResponseBody
public User ResponseBodyajax(){
  System.out.println("ajax过来了");
    return new User();
}

ajax代码

<script>
    function ajaxTest(){
//创建原生ajax对象 低版本创建ActiveXObject('Mricosoft.XMLHTTP')对象
        var ajax=new XMLHttpRequest;
//设置请求方式,和url,和是否异步传输
        ajax.open("post","http://localhost:8080/Spring_MVC/ResponseBodyajax",true);
//onreadystatechange相应回调函数
        ajax.onreadystatechange = function () { 
 //判断readyState(ajax)状态码和status(http状态码)==200
            if (ajax.readyState === 4 && ajax.status === 200) {
//将接收过来的对象转换为json对象输出
                let responseText = JSON.parse(ajax.responseText); 
                console.log(responseText);
            }};
 //执行ajax
        ajax.send();
    }
</script>

6.@RestController注解

@RestController注解相当于@ResponseBody + @Controller合在一起的作用。

@RestController
public class RestControllerTest {

    @RequestMapping("/RestController")
  public   String RestControllerTest(){
        return "hallo";
    }
}

文件上传与下载

文件下载

返回类型设置为ResponseEntity对象

调用ServletContext对象的 getRealPath()方法获取到要下载文件的真实路径

利用FileInputStream对象读取复制文件

InputStream 中的available()方法来获取读取到的数据长度

将流读取到byte数组中

@RequestMapping("/testDown") 
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws 
IOException { 
//获取ServletContext对象 
ServletContext servletContext = session.getServletContext();

//获取服务器中文件的真实路径 
String realPath = servletContext.getRealPath("/static/img/1.jpg"); 
//创建输入流 
InputStream is = new FileInputStream(realPath); 
//创建字节数组 
byte[] bytes = new byte[is.available()]; 
//将流读到字节数组中 
is.read(bytes); 
//创建HttpHeaders对象设置响应头信息 
MultiValueMap<String, String> headers = new HttpHeaders(); 
//设置要下载方式以及下载文件的名字 
headers.add("Content-Disposition", "attachment;filename=1.jpg"); 
//设置响应状态码 
HttpStatus statusCode = HttpStatus.OK; 
//创建ResponseEntity对象 
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, 
statusCode); 
//关闭输入流 
is.close(); 
return responseEntity; 
}

文件上传

添加依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

创建文件解析器对象的Bean

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

form表单 必须是POST方式传输 加密类型为: enctype="multipart/form-data"

<form th:action="@{/fileUpload}" method="post" enctype="multipart/form-data">
    <input type="file" name="multipartFile">
    <input type="submit" value="提交">
</form>

实现代码

@RequestMapping("/fileUpload")
    public String  fileUpload(MultipartFile multipartFile,HttpSession session) throws IOException {
//获取到原文件名
  //例 1.jpg
    String Filename = multipartFile.getOriginalFilename(); 
  //获取文件名后缀
   //例 .jpg
    String hzName = Filename.substring(Filename.lastIndexOf(".")); 
 //通过UUID解决重复名问题再拼接上文件名后缀
//例 ea0a0fdb-eb58-4fc4-987b-2a1e7a72da6f.jpg
    Filename = UUID.randomUUID().toString() + hzName; 
    //通过Session获取ServletContext对象
    ServletContext servletContext = session.getServletContext(); 
//fileUpload文件夹的全路径
 //例C:\Users\Administrator\IdeaProjects\Spring_MVC\target\Spring_MVC-1.0-SNAPSHOT\WEB-INF\static\fileUpload\
    String path = servletContext.getRealPath("/WEB-INF/static/fileUpload/"); 
   //拼接字符串 
//例 C:\Users\Administrator\IdeaProjects\Spring_MVC\target\Spring_MVC-1.0-SNAPSHOT\WEB-INF\static\fileUpload\ea0a0fdb-eb58-4fc4-987b-2a1e7a72da6f.jpg
    String Filepath=path+Filename; 
    
//实现文件上传 将接收到的multipartFile转移到C:\Users\Administrator\IdeaProjects\Spring_MVC\target\Spring_MVC-1.0-SNAPSHOT\WEB-INF\static\fileUpload\文件下
   multipartFile.transferTo(new File(Filepath)); 
    return "index1";
}

拦截器

拦截器Interceptors

1.拦截器配置

<mvc:interceptors>
<!--    <bean class="com.springMVC.Day6.Interceptor.FirstInterceptor"></bean>-->
<!--   <ref bean="firstInterceptor"></ref>以上两种方式都是全局拦截-->
    <mvc:interceptor>
        <mvc:mapping path="/*" /> <!--例/**才是拦截所有目录 /*只是拦截项目下-->
        <mvc:exclude-mapping path="/FirstController"/>   <!--    排除目录-->
        <ref bean="firstInterceptor"></ref>
    </mvc:interceptor>
</mvc:interceptors>

2.拦截器实现类需要实现HandlerInterceptor类并重写方法

@Component
public class FirstInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandletִ执行了");
        return true;//只有为 true才放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandleeִ执行了");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletioneִ执行了");
    }
}

3.拦截器的三个抽象方法

SpringMVC中的拦截器有三个抽象方法:

preHandle():控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

postHandle():控制器方法执行之后执行postHandle()

afterComplation():处理完视图和模型数据,渲染视图完毕之后执行afterComplation()

4、多个拦截器的执行顺序

1.若每个拦截器的preHandle()都返回true

此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:

preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反序执行

2.若某个拦截器的preHandle()返回了false

preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterComplation()会执行

spring异常处理

配置文件方式

需要配置SimpleMappingExceptionResolver 这个bean

可用ctrl+shift+n查找异常类

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
<property name="exceptionMappings"> 
<props> 
<!--
properties的键表示处理器方法执行过程中出现的异常 
properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面 
--> 
<prop key="java.lang.ArithmeticException">error</prop> 
</props> 
</property> 
<!--
exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享 
--> 
<property name="exceptionAttribute" value="ex"></property> 
</bean>

注解方式

@ControllerAdvice  //异常控制类
public class ErrorControllerZhujie {
    @ExceptionHandler(value = {ArithmeticException.class}) //异常处理注解 value值的类型为Class数组
    public  String ExceptionHandler(Exception exception, Model model){ //通过Exception这个类来接收异常信息
          model.addAttribute("ex",exception);
         return "error";
    }
}

配置类注解开发MVC

使用配置类和注解代替web.xml和SpringMVC配置文件的功能

1.创建初始化类,代替web.xml

需要继承AbstractAnnotationConfigDispatcherServletInitializer

public class springConfigClass extends AbstractAnnotationConfigDispatcherServletInitializer {

     @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{springConfig.class};//指定spring的配置类 
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{springMvcConfig.class};//指定springMVC的配置类 
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};//指定DispatcherServlet的映射规则,即url-pattern 
    }


    @Override
    protected Filter[] getServletFilters() {//重写getServletFilters()方法
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
            characterEncodingFilter.setEncoding("UTF-8");//创建过滤器对象
            characterEncodingFilter.setForceRequestEncoding(true);
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
    }//返回过滤器数组
}

2.springMVC配置类 代替springMVC的配置文件

mvc配置类需要实现WebMvcConfigurer接口

//配置类注解
@Configuration
//扫描组件 和<context:component-scan base-package=""></context:component-scan>
@ComponentScan("com.Controller")
//开启MVC注解驱动 和<mvc:annotation-driven></mvc:annotation-driven>类似
@EnableWebMvc
public class springMvcConfig implements WebMvcConfigurer {

    @Override//配置默认servlet处理器处理静态资源 和 <mvc:default-servlet-handler></mvc:default-servlet-handler>注解类似
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override //配置视图控制器 和<mvc:view-controller path="/" view-name="index" ></mvc:view-controller>注解类似
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }
/*配置拦截器 类似注解如下
*<mvc:interceptors>
*    <mvc:interceptor>
*        <mvc:mapping path="/**" />
*        <mvc:exclude-mapping path="/FirstController"/>
*        <ref bean="firstInterceptor"></ref>
*    </mvc:interceptor>
*</mvc:interceptors>
* */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        OneInterceptor oneInterceptor = new OneInterceptor();
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(oneInterceptor);
        interceptorRegistration.addPathPatterns("/**");
    }

    @Override//异常处理器
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        properties.setProperty("java.lang.ArithmeticException","error");
           simpleMappingExceptionResolver.setExceptionMappings(properties);
           simpleMappingExceptionResolver.setExceptionAttribute("ex");
           resolvers.add(simpleMappingExceptionResolver);
    }

    //配置文件上传解析器
    @Bean
    public CommonsMultipartResolver multipartRequest(){
        return new CommonsMultipartResolver();
    }

    //spring模板解析器
    @Bean
    public ITemplateResolver templateResolver() {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        // ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过 WebApplicationContext 的方法获得
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver( webApplicationContext.getServletContext());
        templateResolver.setPrefix("/WEB-INF/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }
    //生成模板引擎并为模板引擎注入模板解析器
    @Bean public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }
    //生成视图解析器并未解析器注入模板引擎
    @Bean public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setCharacterEncoding("UTF-8");
        viewResolver.setTemplateEngine(templateEngine);
        return viewResolver;
}
}

SpringMVC的执行流程

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

2 DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),判断请求URI对应的映射:

3 根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器,最后以HandlerExecutionChain执行链对象的形式返回。

4 DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。

5 如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler(…)方法【正向】

6 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。

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

8 此时将开始执行拦截器的postHandle(...)方法【逆向】。

9 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver进行视图解析,根据Model和View,来渲染视图。

10 渲染视图完毕执行拦截器的afterCompletion(…)方法【逆向】。

11)将渲染结果返回给客户端。

SpringMVC常用组件

举报

相关推荐

0 条评论