文章目录
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
做整体请求处理调度!
除了DispatcherServlet
SpringMVC还会提供其他特殊的组件协作完成请求处理和响应呈现。
其中对于组件的理解:
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企业级开发