学习springmvc的总结

springmvc的学习总结

一.SpringMVC的简介

1.1 介绍

Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc ),但它通常被称为“Spring MVC”。

为什么会选择了SpringMVC作为Java EE项目表述层开发的首选方案 ,因为它有以下显著的优势:

Spring 家族原生产品,与IOC容器等基础设施无缝对接
表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
代码清新简洁,大幅度提升开发效率
内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
性能卓著,尤其适合现代大型、超大型互联网项目要求
在代码优化方面,springmvc与原生servlet api的区别:

Servlet API代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userName = request.getParameter(“userName”);

System.out.println("userName="+userName);

}

**对于代码便于理解:**HttpServletRequest和HttpServletResponse是Java Servlet中的两个重要接口,用于处理HTTP请求和生成HTTP响应。

HttpServletRequest接口代表客户端的请求,它包含了客户端发送给服务器的请求信息,比如参数、头部信息、HTTP方法等。开发人员可以使用HttpServletRequest来获取客户端提交的数据,比如表单参数、URL参数等,并据此进行相应的处理。

HttpServletResponse接口代表服务器对客户端的响应,开发人员可以使用HttpServletResponse来设置响应的内容、状态码、头部信息等,最终将响应发送给客户端。

Spring MVC代码:

@RequestMapping(“/user/login”)
public String login(@RequestParam(“userName”) String userName,Sting password){

log.debug("userName="+userName);
//调用业务即可

return "result";

}

对于代码便于理解:@RequestMapping对外访问的地址 到handlerMapping注册的注解

​ @RequestParam是Spring MVC框架中的注解,用于将HTTP请求中的 参数绑定到方法的参数上。

1.2 主要的作用

在后期我们学习的ssm框架中,springmvc是其中的”三巨头之一“,它主要负责表述层也就是控制层,而控制层主要有以下功能:

请求映射、数据输入、视图界面、请求分发、表单回显、过滤拦截、文件的上传下载、数据的校验、类型的转换·······

1.3 springmvc的核心组件和其作用与理解

Spring MVC与许多其他Web框架一样,是围绕前端控制器模式设计的,其中中央 Servlet DispatcherServlet 做整体请求处理调度!

除了DispatcherServletSpringMVC还会提供其他特殊的组件协作完成请求处理和响应呈现。

其中对于组件的理解:

DispatcherServlet : SpringMVC提供,我们需要使用web.xml配置使其生效,它是整个流程处理的核心,所有请求都经过它的处理和分发
HandlerMapping : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,它内部缓存handler(controller方法)和handler访问路径数据,被DispatcherServlet调用,用于查找路径对应的handler
HandlerAdapter : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,它可以处理请求参数和处理响应数据数据,每次DispatcherServlet都是通过handlerAdapter间接调用handler,他是handler和DispatcherServlet之间的适配器
Handler : handler又称处理器,他是Controller类内部的方法简称,是由我们自己定义,用来接收参数,向后调用业务,最终返回响应结果
ViewResovler : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效!视图解析器主要作用简化模版视图页面查找的,但是需要注意,前后端分离项目,后端只返回JSON数据,不返回页面,那就不需要视图解析器!所以,视图解析器,相对其他的组件不是必须的
解释五大组件的运行过程:

(1)用户发送请求至前端控制器DispatcherServlet

(2)DispatcherServlet收到请求调用HandlerMapping处理器映射器。

(3)处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

(4)DispatcherServlet调用HandlerAdapter处理器适配器。

(5)HandlerAdapter经过适配调用具体的Handler处理器(Controller,也叫后端控制器)。Controller执行完成返回ModelAndView。

(6)HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。

(7)DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

(8)ViewReslover解析后返回具体View视图。

(9)DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

(10)DispatcherServlet响应用户。

二.Spring MVC接收数据

导入依赖(包括后面实现的所有所需依赖)

  <!-- springioc相关依赖  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- web相关依赖  -->
        <!-- 在 pom.xml 中引入 Jakarta EE Web API 的依赖 -->
        <!--
            在 Spring Web MVC 6 中,Servlet API 迁移到了 Jakarta EE API,因此在配置 DispatcherServlet 时需要使用
             Jakarta EE 提供的相应类库和命名空间。错误信息 “‘org.springframework.web.servlet.DispatcherServlet’
             is not assignable to ‘javax.servlet.Servlet,jakarta.servlet.Servlet’” 表明你使用了旧版本的
             Servlet API,没有更新到 Jakarta EE 规范。
        -->
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-web-api</artifactId>
            <version>${servlet.api}</version>
            <scope>provided</scope>
        </dependency>

        <!-- springwebmvc相关依赖  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.28</version>
                <scope>compile</scope>
            </dependency>
		<!--jackson 依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.0</version>
        </dependency>

        <!-- jsp需要依赖! jstl-->
        <dependency>
            <groupId>jakarta.servlet.jsp.jstl</groupId>
            <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
            <version>3.0.0</version>
        </dependency>

        <!-- 校验注解实现-->
        <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>8.0.0.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
            <version>8.0.0.Final</version>
        </dependency>
2.1 访问路径设置

在spring mvc中我们使用 @RequestMapping 注解来指定url地址,也就是用来接受请求的(注:在Servlet中请求地址需要在地址前加上”/“,而在springmvc中不用必须加)

创建控制器

1.精准路径:就是不使用任何的通配符,直接指定

@Controller指加入ioc容器

@Controller
public class UserController {
    @RequestMapping("/user/login")
    public String login(){
        return "ok";
    }

2.模糊路径:使用通配符,用于匹配多个相似的地址(注:/*:代表一层模糊;/**:代表多层模糊)

@Controller
public class UserController {
    @RequestMapping("/user/*")
    public String login(){
        return "ok";
    }
 
@RequestMapping("/user/**")
public String login(){
    return "ok";
}
3.@RequestMapping 注解也可以用于类上,表示在此类中的所有方法都是以此地址为根地 
@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("login")
    public String login(){
        return "ok";
    }

4.springmvc的请求方式,在默认情况下是所有的请求方式都可以的,都是我们也可以指定某种方式

@Controller
public class UserController {
    @RequestMapping("/user/login",method = {RequestMethod.POST,RequestMethod.GET})
    public String login(){
        return "ok";
    }

5.在选择特定的请求方式的时候,我们也可以使用特殊的注解

  • @GetMapping:用于处理HTTP GET请求。等价于@RequestMapping(method = RequestMethod.GET)
  • @PostMapping:用于处理HTTP POST请求。等价于@RequestMapping(method = RequestMethod.POST)
  • @PutMapping:用于处理HTTP PUT请求。等价于@RequestMapping(method = RequestMethod.PUT)
  • @DeleteMapping:用于处理HTTP DELETE请求。等价于@RequestMapping(method = RequestMethod.DELETE)
  • @PatchMapping:用于处理HTTP PATCH请求。等价于@RequestMapping(method = RequestMethod.PATCH)
2.2 接受参数
2.2.1 param参数的接受
1.直接接受:

条件就是从客户端发送过来的参数和形参相匹配,就可以直接接受

// 形参列表,填写对应的名称的参数即可   请求参数名=形参参数名即可!
    //1.名称相同  2.可以不传递   不报错
    @RequestMapping("data")
    @ResponseBody
    public String data(String name,int age){

        System.out.println("name = " + name + ", age = " + age);
        return "name = " + name + ", age = " + age;
    }

2.使用 @RequestParam注解 来绑定参数

(注:使用 @RequestParam注解默认是必须有参数传递,如没有就会报错,但是可以使用 @RequestParam(value = “stuAge”,required = false,defaultValue = “18”) required = false 用于设置传参是非必须,,defaultValue = "默认值”用于设置默认值)

//注解指定
    //指定任意的请求参数名   要求必须传递   要求不必须传递  给与一个默认值
    // /data1?account=root&page=1
    //account 必须传递  page可以不必须传递,如果不传递默认值就是1

   /*
    * @RequestParam  -> 形参列表  指定请求参数名  或者  是否必须传递  或者  非必须传递设置默认值
    *                       用法 @RequestParam(value="指定请求参数名",如果参数名和请求参数名一致,可以省略
    *                           required = false  前端是否必须传递次参数,默认是必须 ,不穿400异常,
    *                               defaultValue = "1" 当非必须传递false,可以设置默认值  )
    * */
    @GetMapping("data1")
    @ResponseBody
    public String data1(@RequestParam("account") String username,
                        @RequestParam(required = false,defaultValue = "1") int page){
        System.out.println("username = " + username + ",  page = " + page);
        return "username = " + username + ", page = " + page;
    }
3.可以接受集合类型
//特殊值
    //一名多值   key=1&key=2 直接使用集合接值即可
    // /data2?hbs=吃&hbs=玩&hbs=学习
    //不加注解@RequestParam 将hbs对应的一个字符串直接赋值给集合!  类型异常!
    //加了注解 **HandlerAdapter**就会将集合add加入对应的字符串
    @GetMapping(value = "data2",produces = "text/plain;charset=UTF-8")
    @ResponseBody
    public String data2(@RequestParam List<String> hbs) {
        //设置默认字符集System.out   默认值随windows系统环境改变不可修改
        PrintStream ps = new PrintStream(System.out, true, StandardCharsets.UTF_8);//如果乱码可设置
        System.setOut(ps);
        System.out.println("hbs = " + hbs);
        return "ok";
    }
4.可以接受实体类
 //使用实体对象接值  用户注册(用户的信息)          对应的实体类  ->  插入到数据库  表
    //  /data3?name=二狗子&age=18 准备一个对应属性和get|set方法的实体类即可! ->形参列表声明对象参数即可
   @RequestMapping(value = "data3",produces = "text/html;charset=UTF-8")
   @ResponseBody
    public String data3(User user){
       //设置默认字符集System.out   默认值随windows系统环境改变不可修改
        PrintStream ps = new PrintStream(System.out, true, StandardCharsets.UTF_8);
        System.setOut(ps);
        System.out.println("user = " + user);
        return "user = " + user;
    }
5.动态路径传参,使用 @PathVariable 注解
//动态路径设计   {key} =* {key}  在形参列表获取传入的参数
    //接受路径参数    String account.String password ->接受param格式参数
    //必须使用@PathVariable

    @RequestMapping("{account}/{password}")
    public String login(@PathVariable(value = "account") String username,@PathVariable String password){
        System.out.println("username = " + username + ", password = " + password);
        return "username = " + username + ", password = " + password;
    }
2.2.2 json数据的接收

对于json数据的接收,我们在springmvc框架中,我们使用 @RequestBody 注解 来将json数据转换为java对象

要想接收json数据,我们第一步就是需要定义一个接收json数据的实体类,

@Datapublic class Person {  private String name;  private int age;  private String gender;  // getter 和 setter 略}

然后 @RequestBody 注解 来接收json数据

@RequestMapping("json")
@Controller
@ResponseBody
public class JsonController {
    @RequestMapping("data")
    public String data(@RequestBody Person person){
        System.out.println("person = " + person);
        return person.toString();
    }
}

而在springmvc中想要接收json数据,我们还需要配置json转换器

1.在配置类中用 @EnableWebMvc

注解声明json转换器的配置 (注: @EnableWebMvc 注解是用于简化 导入handlerMapping和handlerAdapter 的步骤)

@EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
@Configuration
@ComponentScan(basePackages = "org.example.controller") //你的控制器位置
public class SpringMvcConfig implements WebMvcConfigurer {
     /*@Bean
    public RequestMappingHandlerMapping handlerMapping(){
        return new RequestMappingHandlerMapping();
    }
    @Bean
    public RequestMappingHandlerAdapter handlerAdapter(){
        return  new RequestMappingHandlerAdapter();
    }*/
}
2.3 接收cookie数据

我们在springmvc中需要接收cookie数据可以用 @CookieValue 注解来绑定参数

@Controller
@RequestMapping("cookie")
@ResponseBody
public class CookieController {
    @RequestMapping("data")
    public String data(@CookieValue(value = "cookieName") String value){
        System.out.println("value = " + value);
        return value;
    }
}
2.4 接收请求头数据

我们在springmvc中需要接收请求头的数据时,可以用 @RequestHeader 注解

@Controller
@RequestMapping("header")
@ResponseBody
public class HeaderController {
    @RequestMapping("data")
    public String data(@RequestHeader("Host") String host){
        System.out.println("host = " + host);
        return "host = " + host;
    }

}

2.5 原生的api对象和共享域对象的操作

我们在springmvc中,需要对原生的api对象和共享域对象的操作时,一句话就是,我们在想要对哪个对象进行操作,就把这个对象放入我们的传参里声明,除了 ModelAndView 对象 和 ModelAndView 对象

@RequestMapping("/mav")
public ModelAndView testAttrByModelAndView() {
    // 1.创建ModelAndView对象
    ModelAndView modelAndView = new ModelAndView();
    // 2.存入模型数据
    modelAndView.addObject("requestScopeMessageMAV", "666");
    // 3.设置视图名称
    modelAndView.setViewName("mav");
    return modelAndView;
}
@Autowired
private ServletContext servletContext;
@RequestMapping("/application")
public String attrApplication() {    
    servletContext.setAttribute("appScog", "666999");
    return "target";
}


总结:




接受参数
    1.路径设置
        @RequestMapping(value="地址",method="请求方式")|方法
        @GetMapping   /  @PostMapping      方法
    2.接受参数【重点】
        param
            直接接受 handler(类型 形参名)  形参名 = 请求参数名
            注解指定  handler(@RequestParam(name="请求参数名",required=true,defaultValue="默认值"))
            一名多值  handler(@RequestParam List key)
            实体接受 handler(实体   对象) 对象的属性名=请求参数名   如果接收json类型 需要@RequestBody来接值
        路径参数
            设置动态路径和标识  /{key}/info/{key}
            接受路径 handler(@PathVariable(动态路径key) 类型 形参名)
        json
            数据接受 handler(@RequestBody 实体类  对象)
            准备工作
                1.导入jackson依赖
                2.@EnableWebMvc [加入了handlerMapping 加入handlerAdapter 给handlerAdapter配置json处理器]

    3.cookie接受
        handler(@CookieValue("cookie的名字")
    4。请求头接受
        handler(@RequestHeader("cookie的名字")
    5.原生api接收
        handler(httpServletRequest,response,session)
        ServletContext -> ioc  -> 全局变量  @Autowired

    6.共享域获取
        原生api方式即可

三. Spring MVC的响应数据

3.1 跳转页面

3.1.1简单跳转

1.准备依赖
2.需要一个jsp页面路径:

/WEB-INF/jsp/index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
        <h1>666</h1>
  </body>
</html>
3.配置视图解析器

@EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器
@Configuration
@ComponentScan(basePackages = “org.example.controller”) //TODO: 进行controller扫描(你的controller地址)

//WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
public class SpringMvcConfig implements WebMvcConfigurer {

//配置jsp对应的视图解析器
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
    //快速配置jsp模板语言对应的
    registry.jsp("/WEB-INF/jsp/",".jsp");
}

}

4.控制器的返回
@Controller
public class UserController {
    @RequestMapping("/user/login")
    public String login(String name){
        return "index";
    }
3.1.2 转发和重定向

在springmvc中有两种方式来实现快速跳转, redirect 或者 forward 关键字 ,如果跳转页面,那就将关键字后写上页面的相对路径,即可实现页面的跳转

@RequestMapping("/redirect")
public String redirect() {
    // 重定向到 /login 路径 
    return "redirect:/login";
}

@RequestMapping("/forward")
public String forward() {
    // 转发到 /login 路径
    return "forward:/login";
}
 /*
    * 重定向
    *   1.方法返回值写成字符串类型
    *   2.不能添加responseBody注解
    *   3.返回字符串前  redirect :/重定向的地址
    * 路径细节:【不使用  springmvc request response】
    *       转发是项目下的资源跳转  路径:项目下的地址  /jsp/index 忽略 applicationContext
    *       重定向项目下的资源可以是项目外的资源  重定向属于二次请求  路径: 项目下的地址  全地址 /springmvc/jsp/index   不忽略applicationContext
    *   使用springmvc路径语法
    *       “forward :路径 |redirect:路径 ” 重定向 :资源的地址也不需要写项目的根路径!  /jsp/index
    *       转发和重定向的地址都一样了  /springmvc/jsp/index ->  /springmvc/springmvc/jsp/index
    * */

3.2 返回json数据

1.在配置类中添加json数据转换器
@EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
@Configuration
@ComponentScan(basePackages = "com.atguigu.controller") 
//WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
public class SpringMvcConfig implements WebMvcConfigurer {
}
2.使用 @ResponseBody 注解,

用于将方法返回的数据转化为json和xml数据返回回客户端,且不经过视图解析器(注:可以使用在类上,也可以使用在方法上)

@RequestMapping("/user", method = RequestMethod.POST)
@ResponseBody
public User getUser(@RequestBody User userParam) {
    User user = new User();
    user.setAge(20);
    user.setName("小明");
    //返回的对象,会使用jackson的序列化工具,转成json返回给前端
    return user;
}
@ResponseBody 注解是 @ResponseBody 注解可以和 @Controller 注解 的合并,所以我们可以简化 (注:可以使用在类上,也可以使用在方法上)
@ResponseBody
@Controller
@RequestMapping("/user")
public class ParamController {
    //TODO
}

3.3 返回静态资源

1.在web应用中加入静态资源

2.在配置类中配置静态资源处理

@EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
@Configuration
@ComponentScan(basePackages = "com.atguigu.controller") 
public class SpringMvcConfig implements WebMvcConfigurer {
//配置jsp对应的视图解析器
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
    //快速配置jsp模板语言对应的
    registry.jsp("/WEB-INF/jsp/",".jsp");
}

//开启静态资源处理 <mvc:default-servlet-handler/>
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

}

四.Spring MVC 的全局处理异常

4.1 两种处理异常的方式

编程式异常处理:是指在代码中显式地编写处理异常的逻辑。它通常涉及到对异常类型的检测及其处理,例如使用 try-catch 块来捕获异常,然后在 catch 块中编写特定的处理代码,或者在 finally 块中执行一些清理操作。在编程式异常处理中,开发人员需要显式地进行异常处理,异常处理代码混杂在业务代码中,导致代码可读性较差。
声明式异常处理:则是将异常处理的逻辑从具体的业务逻辑中分离出来,通过配置等方式进行统一的管理和处理。在声明式异常处理中,开发人员只需要为方法或类标注相应的注解(如 @Throws 或 @ExceptionHandler),就可以处理特定类型的异常。相较于编程式异常处理,声明式异常处理可以使代码更加简洁、易于维护和扩展。 (通常使用声明式异常处理)

4.2 声明式异常处理实现

1.声明一个异常处理控制器类

‘,用于统一处理。@RestControllerAdvice == @ControllerAdvice + @ResponseBody ,代表 当前类的异常处理控制器

@RestControllerAdvice
public class Error {  
}
2.在异常处理类中声明异常处理方法。

@ExceptionHandler(异常类.class)代表处理的异常类

@RestControllerAdvice
public class Error {  
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public Object handlerJsonDateException(HttpMessageNotReadableException e){  
    	return null;
	}
@ExceptionHandler(Exception.class)
public Object handlerException(Exception e){
	return null;
}
}


3.在配置类中,让异常处理控制器被扫描到

@ComponentScan(basePackages = {“org.example.controller”,“org.example.Error”})
1

五.拦截器

5.1 拦截器的概念

在程序中,使用拦截器在请求到达具体 handler 方法前,统一执行检测,检测成功就通过,进行后面的操作,检测不成功的就不通过

拦截器 Springmvc VS 过滤器 javaWeb:

相似点
拦截:必须先把请求拦住,才能执行后续操作
过滤:拦截器或过滤器存在的意义就是对请求进行统一处理
放行:对请求执行了必要操作后,放请求过去,让它访问原本想要访问的资源
不同点
工作平台不同
过滤器工作在 Servlet 容器中
拦截器工作在 SpringMVC 的基础上
拦截的范围
过滤器:能够拦截到的最大范围是整个 Web 应用
拦截器:能够拦截到的最大范围是整个 SpringMVC 负责的请求
IOC 容器支持
过滤器:想得到 IOC 容器需要调用专门的工具方法,是间接的
拦截器:它自己就在 IOC 容器中,所以可以直接从 IOC 容器中装配组件,也就是可以直接得到 IOC 容器的支持
选择:

功能需要如果用 SpringMVC 的拦截器能够实现,就不使用过滤器。

5.2 拦截器的实现

1.创建一个拦截器类
public class MyInterceptor implements HandlerInterceptor {
    //执行handler之前 调用的拦截方法
    //编码格式设置,登录保护 ,权限处理等等
    /**
     *  filter -doFilter
     * @param request 请求对象
     * @param response 响应对象
     * @param handler 就是我们调用的方法对象
     * @return true  放行 false 拦截
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("request = " + request + ", response = " + response + ", handler = " + handler);
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
    /**
     * 放handler执行完毕后  触发的方法!  没有拦截机制
     * 此方法只有 preHandler return true时
     *
     *  对结果处理  敏感词汇检测
     *
     * @param request   请求对象
     * @param response  响应
     * @param handler handler 方法
     * @param modelAndView 返回的视图和共享域数据对象
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor.postHandle");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
    /**
     * 整体处理完毕
     * @param request
     * @param response
     * @param handler
     * @param ex  handler报错了  异常对象
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor.afterCompletion");
    }
}

2.在配置类中添加拦截器
@Configuration
@ComponentScan("com.cqie")
@EnableWebMvc
public class MvcCofig implements WebMvcConfigurer {
    //handlerMapping handlerAdapter json 转化器
    //视图解析器来指定前后缀


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        //registry可以快速添加前后缀
        registry.jsp("/WEB-INF/views/",".jsp");

        //handler ->index
    }
    //开启静态资源查找
    //  dispatcherServlet -> handlerMapping 找有没有对应的handler -》没有 -》 找有没有静态资源
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //配置方案1.拦截全部请求
        //registry.addInterceptor(new MyInterceptor());

        //配置方案二: 指定地址拦截
        // * 任意一层字符串  **任意多层字符串
        /*registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/user/**");*/
        //配置方案3排除拦截   排除的地址应该再拦截地址内部
        /*registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/data1");*/
        registry.addInterceptor(new MyInterceptor());
        registry.addInterceptor(new MyInterceptor1());

    }
}
3.有多个拦截器时的执行顺序:先声明的优先级高 优先级高的在外层,就像一个洋葱横切

六.参数校验

6.1 jsr 303校验

注解 规则
@Null 标注值必须为 null
@NotNull 标注值不可为 null
@AssertTrue 标注值必须为 true
@AssertFalse 标注值必须为 false
@Min(value) 标注值必须大于或等于 value
@Max(value) 标注值必须小于或等于 value
@DecimalMin(value) 标注值必须大于或等于 value
@DecimalMax(value) 标注值必须小于或等于 value
@Size(max,min) 标注值大小必须在 max 和 min 限定的范围内
@Digits(integer,fratction) 标注值值必须是一个数字,且必须在可接受的范围内
@Past 标注值只能用于日期型,且必须是过去的日期
@Future 标注值只能用于日期型,且必须是将来的日期
@Pattern(value) 标注值必须符合指定的正则表达式
@Email 标注值必须是格式正确的 Email 地址
@Length 标注值字符串大小必须在指定的范围内
@NotEmpty 标注值字符串不能是空字符串
@Range 标注值必须在指定的范围内

应用校验注解
/*
* 1.name 不为null和空字符串
*   字符串不为空 @NotBlank 集合 @NotEmpty 包装 @NotNull
* 2.password 长度大于6
*
* 3.age 必须>=1
* 4.email 邮箱格式的字符串
* 5.birthday 过去时间
*
* */
@lombok.Data
public class User {
    @NotBlank
    private String name;
    @Length(min = 6)
    private String password;
    @Min(1)
    private int age;
    @Email
    private String email;
    @Past
    private Date birthday;

}

对应controller
@RestController
@RequestMapping("user")
public class UserController {
    //接受用户数据,用户有校验注解
    /*
    *
    * 步骤1.实体类水性添加校验注解
    * 步骤2.handler(@Validated 实体类 对象)
    *   细节: param | json 校验注解都有效果
    *           json参数  @RequestBody
    *
    *如果:不符合校验规则,直接向前端抛出异常!
    * 接受错误绑定信息 自定义返回结果  约定: 参数错误 -》 {code:400} -》 前端
    * 捕捉错误绑定错误信息
    *   1.handler(校验对象,BindResult result) 要求: bindingResult必须紧挨着 校验对象
    *   2.bindingresult获取绑定错误
    * */
    @PostMapping("register")
    public Object register(@Validated@RequestBody User user, BindingResult result){
        if (result.hasErrors()){
            //有绑定错误,就不直接返回了,由我们自己决定!
            Map data=new HashMap();
            data.put("code",400);
            data.put("msg","参数校验异常了");
            return data;
        }

        System.out.println("user = " + user);
        return user;
    }
    @GetMapping("data")
    public String data(){
        //空指针异常  NullPointerException
        String name=null;
//        name.toString();
        System.out.println("UserController.data");
        return "ok";
    }
    @GetMapping("data1")
    public String data1(){
            //算数异常   ArithmeticException: / by zero
//        int i=1/0;
        return "ok";
    }
}

参考于尚硅谷新版SSM框架全套视频教程,Spring6+SpringBoot3最新SSM企业级开发

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值