Spring MVC

介绍

一、是一个表述层框架
二、SpringMVC 底层封装了一个Servlet API
三、是Spring Framework 的一个子框架 模块的名称是:spring-webmvc 作为web层的首先方案
四、核心功能:简化接收前端参数,简化响应前端数据,调用业务逻辑

核心组件讲解 和具体的调用流程

一、核心的主键:
DispatcherServlet:就是底层封装的ServletAPI是整个流程处理的核心,所有的请求都经过它来处理和分发【CEO】

HandlerMapping:需要将他加载到ioc容器方可使用;它内部缓存了handler(就是controller里的方法)和handler访问的路径数据 被DispatcherServlet调用来查找路径对应的handle(方法和路径)【秘书】

HandlerAdapter需要将他加载到ioc容器方可使用;它可以处理请求参数和处理响应参数数据
每次DispatcherServlet 调用handler中间都是他来帮我们简化请求和响应的数据的 ;是他们之间的适配器 【经理】

Handler: 称为处理器,他是Conterller类内部的方法的简称是由我们自己定义用来接收参数,向后调用业务,最终返回响应结果的 【打工人】

ViewResovler:需要将他加载到ioc容器方可使用; 视图解析器主要作用简化模版视图页面查找的 前后端分离项目 后端只返回JSON数据 不返回页面 ,那就不需要视图解析器!这个不是必须的==【财务】==

二、调用的流程
在这里插入图片描述

快速入门 quick

场景:定义一个handler()方法,当外部访问这个方法地址 ,就给浏览器响应一个 hello handler字符串

一、创建一个web项目 web项目
二、导入所需要的依赖

<properties>
    <spring.version>6.0.6</spring.version>
    <servlet.api>9.1.0</servlet.api>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <!-- 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>

</dependencies>

三、在表述层创建一个handler()方法;就是我们自己定义的方法

package com.zh.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/14 19:54
 */
@Controller
public class helloController {

//    对外方位的地址 也是在handlerMapping上注册的注解
    @RequestMapping("zhou/hello")
    @ResponseBody //表示不去找视图 直接返回字符串给前端
    public String hello(){
        System.out.println("helloController.hello");
//        返回给前端的字符串
        return "周浩好帅 hello handler";
    }
}

四、创建一个mvcConfig配置类
一、将controller配置到ioc容器中
二、将HandlerMapping 、HandlerAdepter 配置到ioc容器中

package com.zh.Config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/16 12:55
 */
@Configuration
@ComponentScan("com.zh")
public class MVC_Config {


    /* 一、将controller配置到ioc容器中
       二、将HandlerMapping 、HandlerAdepter 配置到ioc容器中
    * */
    @Bean
    public RequestMappingHandlerMapping handlerMapping(){
        RequestMappingHandlerMapping requestMappingHandlerMapping = new RequestMappingHandlerMapping();
        return  requestMappingHandlerMapping;
    }
    @Bean
    public RequestMappingHandlerAdapter handlerAdapter(){
        RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter();
        return requestMappingHandlerAdapter;
    }
}

五、初始化 SpringMVC 初始化 init
可以被web项目加载 会初始化ioc容器 会设置dispatcherServlet地址

package com.zh.Config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/16 13:11
 */
public class SpringInit extends AbstractAnnotationConfigDispatcherServletInitializer  {

    /*  继承这个类: 可以被web项目加载 会初始化ioc容器 会设置dispatcherServlet地址

    * */

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

//    这个实现是来设置项目的配置类的 MVC_Config的
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{MVC_Config.class};
    }
//   servlet 的访问地址
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"}; //处理所有的请求
    }
}

六、启动的时候在编辑栏 中加入tomcat

接收参数

访问路径的设置

一、地址设置
二、模糊设置
三、类上注解的作用(提取方法共同部分)
四、请求方式指定
五、注解代替

package com.zh.UserController;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/19 14:38
 */

@Controller
@RequestMapping("/zh")  // 提取方法上公共的部分
public class userController {
    /* 一、@RequestMapping
            1、可以不需要 / 开头

            2、支持模糊查询  /zh/*    表示一层模糊查询  eg: /zh/a    /zh/aaaaa
                                          /zh/**   表示任意层模糊查询 eg: /zh/a   /zh/aaa/aaa/aaa
            3、可以在类上加注解;就是加在类上的注解(@RequestMapping) 在类里面方法的地址是通用的  eg: 类注解地址 + 方法注解地址

            4、请求方式指定:默认情况下 所有的方式都能访问
                          指定get/post访问:@RequestMapping(value = "/login",method = {RequestMethod.GET,RequestMethod.POST})  也可以指定多个
            5、注解代替 :GetMapping

     */

    @RequestMapping(value = "/login",method = {RequestMethod.GET,RequestMethod.POST})
    public String login(){

        return null;
    }

    @GetMapping("register") //只能用在方法上 等价于 @RequestMapping(value="/register",method =RequestMethod.GET)
    public String register(){
        return null;
    }

    @RequestMapping       //这个是类上注解的地址  /zh
    public String index(){
        return null;
    }
}

Param 4种场景 接收参数

一、直接接收值
二、使用注解接收@RequestParam
三、使用集合接收
四、使用实体类接受

package com.zh.Param;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/20 10:02
 */

@Controller
@RequestMapping("/Param")
public class ParamController {
//    一、直接接收  使用方法中的形参列表来接收值 请求参数名=形参列表名 不传参数也不会报错
    @RequestMapping("/data1")
    @ResponseBody
    public String data(String name,int age){
        System.out.println("name = " + name + ", age = " + age);
        return "name = " + name + ", age = " + age;
    }


    /*  二、使用注解的方式
    *   场景一 account必须传值 page不必须传值 不传的话默认值是 1
    *
    *   @RequestParam :指定任意的参数请求名 可以要求必须传值 要求不必须传 给一个默认值
    *   value : 指定请求参数名的 默认是必须要传值 请求参数和方法参数名一致的话可以不写
    *   required: 值为false 表示不是必须传值
    *   defaultValue:表示给一个默认值 和上面required使用
    *
    * */
    @RequestMapping("/data2")
    @ResponseBody
    public String data2
    (@RequestParam(value="account") String username ,@RequestParam(required=false,defaultValue = "1") int page){
        System.out.println("username = " + username + ", page = " + page);
        return "username = " + username + ", page = " + page;
    }

    /* 三、使用集合来接受值
       场景是 一名多值的情况  eg key=吃&key=喝

       使用集合接受值的话必须加 @RequestParam来注解 才会经过代理类
    * */

    @RequestMapping("data3")
    @ResponseBody
    public String data3(@RequestParam List<String> zh){
        System.out.println("zh = " + zh);
        return "ok";
    }
    /* 四、实体类接收值
          声明一个实体类 来接受 实体类的属性名== 请求参数名
    *
    * */
    @RequestMapping("/data4")
    @ResponseBody
    public String data4(User user){
        return user.toString();
    }

}

动态路径接收参数

package com.zh.Path;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/23 18:36
 */
@Controller
@RequestMapping("/Path")
public class PathController {
    /* 演示动态接收参数

    {key} 表示动态的接收 这个参数
    @PathVariable 加了这个才可以在参数中获取动态传入进来的值
    * */

    @RequestMapping("/{account}/{password}")
    @ResponseBody
    public String Path_(@PathVariable("account") String username,@PathVariable(name = "password") String password){
        System.out.println("username = " + username + ", password = " + password);
        return "username = " + username + ", password = " + password;
    }
}

json 格式数据接收

没听明白 先放着吧

接收Cookie数据 和请求头接收

package com.zh.Cookie;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/23 19:52
 */
@Controller
@ResponseBody
@RequestMapping("Cookie")
public class CookieController {
    /*演示如何获取 CookieController
    * */
    /*取cookie*/
    @RequestMapping("/data")
    public String cookie_(@CookieValue(value = "zh") String username){
        System.out.println(username);
        return username;
    }
    /*存cookie*/

    @RequestMapping("/cookie_")
    public String cookie_01(HttpServletResponse response){
        Cookie cookie = new Cookie("zh", "root");
        response.addCookie(cookie);
        return "ok";
    }
}

请求头接收
在这里插入图片描述

package com.zh.Header;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author ZhouHao
 * @version 1.0
 * 只要干不死,就往死里干
 * 成为想成为的人,越努力越幸运
 * 我自光芒万丈,何须他人半点光
 * 有要做的事,请从知晓的那一刻百分之百去执行
 * 2023/10/23 20:11
 */

@Controller
@ResponseBody
@RequestMapping("header")
public class HeaderController {
    /*  获取请求头   name 和 value 属性的效果是一样的
    
    @RequestHeader 写对应的请求头就好了
    * */
    @RequestMapping("data")
    public String header(@RequestHeader(name = "Host") String host,@RequestHeader(value = "Accept") String Accept){
        System.out.println("host = " + host + ", Accept = " + Accept);
        return "host = " + host + ", Accept = " + Accept;
    }

}

获取原生态的api

共享域对象的操作

响应数据

转发和重定向

需要添加一个jsp的依赖

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

演示快速定义和转发、重定向

package com.zh.Jsp;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/25 18:06
 */
@RequestMapping("zhou")
@Controller
public class JspController {


    @RequestMapping("hao")
    public String  test(Model model){
        model.addAttribute("data","hello word"); //放在共享域中的数据
        System.out.println("JspController.test");
        return "index";
    }

//    转发 在return 中添加 forward  转发只能是项目下的资源
    @RequestMapping("forward")
    public  String forward(){
        System.out.println("JspController.forward");
        return "forward:/zhou/hao";
    }

//    重定向  可以是项目外的资源   因为重定向是二次请求 所以地址要写根路径地址 就是全部的地址
    @RequestMapping("redirect")
    public String redirect(){
        System.out.println("JspController.redirect");
        return "redirect:/zhou/forward";
    }
//    重定向到百度
    @RequestMapping("redirectBAIDU")
    public String redirectBAIDU(){
        System.out.println("JspController.redirectBAIDU");
        return "redirect:http://www.baidu.com";
    }

}

package com.zh.Config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/25 17:21
 */
@Configuration
@ComponentScan("com.zh")
@EnableWebMvc
public class Config implements WebMvcConfigurer {
//    @Bean
//    public RequestMappingHandlerMapping handlerMapping(){
//        return new RequestMappingHandlerMapping();
//    }
//    @Bean
//    public RequestMappingHandlerAdapter handlerAdapter(){
//        return new RequestMappingHandlerAdapter();
//    }


    /*  继承接口 重写这个方法  来实现视图解析式 然后通过jsp来配置他的前后缀 handler方法就可以访问到了
    * */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
//        handler 方法直接写 index 他会自动加入前后缀
        registry.jsp("/WEB-INF/Views/",".jsp");
    }
}

package com.zh.SpringMvcInit;

import com.zh.Config.Config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/25 17:25
 */
public class MvcInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{Config.class};
    }

//    配置拦截地址的
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

返回json格式的数据

package com.zh.Json;

import com.zh.Pojo.user;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/25 20:29
 */
@RequestMapping("zzz")
//@ResponseBody   //表示直接写入http的响应体中 ,不会走视图解析式了  快速查找视图和转发重定向都不生效了
//@Controller

@RestController     /* 相对于上面 这个两个注解 //@ResponseBody //@Controller*/
public class ReturnJson {
    @RequestMapping("aaa")
    public user test_01(){
        user user = new user();
        user.setName("zhouhao");
        user.setAge(18);
        System.out.println("ReturnJson.test_01");
        return user;
    }

//    返回一个集合
    @RequestMapping("bbb")
    public Map<Integer,user> test_02(){
        user user = new user();
        user.setName("zhouhao");
        user.setAge(18);

        Map<Integer, com.zh.Pojo.user> map = new HashMap<>();
        map.put(1,user);
        System.out.println("ReturnJson.test_02");

        return map;
    }
}

返回静态资源处理

内部用的还是转发


    /*  开启查找静态支援 */

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

Restful风格

http 协议的标准使用方案和风格设计
1、教你如何设计路径
2、教你如何设计参数传递
3、教你如何选择请求方式

具体怎么设置

1、路径尽量设置成名词,
2、请求方式尽量跟业务相关

|查询操作|GET|
|保存操作、插入|POST|
|删除操作|DELETE|
|更新操作|PUT|

3、单个资源用地址Path传 多个用Param传 很多的话用json

代码演示

package com.zh.Pojo.Controller;

import com.zh.Pojo.User;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/27 18:08
 */
@RestController    // @Controller + @ResponseBody
@RequestMapping("user")
public class UserController {
        @RequestMapping(method = RequestMethod.GET)
        public List<User> page(@RequestParam(required = false,defaultValue = "1") Integer page,
                               @RequestParam(required = false,defaultValue = "10") Integer size){
                return null;
        }

        @RequestMapping(method=RequestMethod.POST)
        public User insert(@RequestBody  User user){
                return user;
        }

        @RequestMapping(method=RequestMethod.GET,value = "{userid}")
        public User query(@PathVariable(value = "userid") Integer id){
                return null;
        }
        @RequestMapping(method = RequestMethod.PUT)
        public  User  update(@RequestBody User user){
                return user;
        }
        @RequestMapping(method = RequestMethod.DELETE,value = "{id}")
        public User delete( Integer id){
                return null;
        }
        @RequestMapping(method = RequestMethod.GET,value = "search")
        public List<User> search(@RequestParam(required = false,defaultValue = "1") Integer id
                ,@RequestParam(required = false,defaultValue = "10") Integer size,String keywork){

        }

}

MV扩展

全局异常处理机制

一、controller类

package com.zh.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/29 21:50
 */
@Controller
@RequestMapping("user")
public class UserController {

    @RequestMapping("data1")
    public String data_01(){
        String str=null;
        str.toString();  //报一个空指针异常 然后就会走对应的全局异常的类
        return "ok";
    }

    @RequestMapping("data2")
    public String data_02(){
        int num=1/0; //会报一个算术异常
        return "ok";
    }
}

二、声明式事务异常

package com.zh.error;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/29 22:23
 */
/*
*  全局异常处理机制演示
* */
@RestControllerAdvice  //返回json字符串
//@ControllerAdvice(可以返回逻辑视图可以转发、重定向)   + @ResponseBody  等于上面那个
public class globalException {
    @ExceptionHandler({ArithmeticException.class})  //表示专门处理 算术异常的和空指针异常的
    public Object ArithmeticException_handler(ArithmeticException arithmeticException){  //参数表示 可以接受异常信息
        System.out.println("算术异常");
        return "suanshuyichang";
    }
    @ExceptionHandler({NullPointerException.class})  //表示专门处理 空指针异常的
    public Object ArithmeticException_handler(){
        System.out.println("空指针异常");
        return "kongzhizheng";
    }
}

拦截器的使用

一、创建一个拦截器方法

package com.zh.Interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/30 15:53
 */
public class MyInterceptor implements HandlerInterceptor {

    /* 执行handler之前调用的拦截器的方法*/

    /**
     *
     * @param request  请求对象
     * @param response 响应对象
     * @param handler  handler 就是我们要调用的方法对象
     * @return  ture 表示放行 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 true;
    }
    /* handler执行完毕后触发的方法 没有拦截机制*/

    /**
     *
     * @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");
    }
    /* 整体处理完毕了 触发这个方法*/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor.afterCompletion");
    }
}

二、在配置类中加入这个方法

package com.zh.MvcConfig;

import com.zh.Interceptor.MyInterceptor;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/10/29 21:54
 */
@EnableWebMvc
@Configuration
@ComponentScan("com.zh")
public class UserConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /* 方案一 默认拦截前部的请求*/
//        registry.addInterceptor(new MyInterceptor());

        /* 方案二 指定地址拦截  支持模糊查询   *(支持任意一层) **(支持任意层)*/
//        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/user/data","/user/data1");

        /* 方案三  排除指定的地址   也支持 *  ** 拦截   */
        registry.addInterceptor(new MyInterceptor()).excludePathPatterns("/user/data1");
    }
}

参数校验功能

导入相关的依赖

<!-- 校验注解 -->
<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-web-api</artifactId>
    <version>9.1.0</version>
    <scope>provided</scope>
</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>

二、实体类

package com.zh.Pojo;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Past;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import java.util.Date;

/**
 * @author ZhouHao
 * @version 1.0
 * 我自光芒万丈,何须他人半点光
 * 2023/11/2 22:52
 */
@Data
public class person {
    /*
    *  参数注解校验演示
    * */
//  name 不为null 且不能是空字符串
    @NotBlank
    private String name;

    @Length(min = 6)
//    password 长度大于6
    private String password;

//    @Min(1)
    age  必须>=1
//    private int age;
//
//    @Email
    email 必须为邮箱格式
//    private String email;
//
//    @Past
    birthday 为过去的时间
//    private Date birthday;
}

三、Controller handler方法

    /*接受用户数据 且经过校验的 需要加上 Validated注解
    *
    *  经过校验的出错了的话 可以自定义返回异常(@Validated person per,BindingResult result)  注意这2个参数得挨着写
    *   BindingResult 会自动捕捉出错的异常 
    * */
    @RequestMapping("register")
    public Object  register(@Validated person per,BindingResult result){
//        自定义抛出异常
        if (result.hasErrors()){
            return "400错误";
        }
        System.out.println("person = " + per);
        return per;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有心肝,只有干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值