springMVC
2025-04-06 17:35:14 0 举报
AI智能生成
springMVC技术框架
作者其他创作
大纲/内容
request相关
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">
<!--
配置 前端控制器 DispatcherServlet,也可以叫做:核心调度器 或者 分发器
接收所有 除了.jsp 的请求,都交给springmvc去处理
-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
关联springmvc的配置文件
初始化参数
contextConfigLocation 配置springmvc的xml配置文件, 指定路径
也可以不配置:
会自动去WEB-INF去找一个名字叫做 [servlet-name]-servlet.xml
这里即是: springmvc-servlet.xml 的文件
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--启动时加载servlet :
当web服务器 启动时 就会创建 servlet (会自动调用servlet的构造函数及init()方法)
-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--
匹配servlet的请求,/表示匹配 除了.jsp的所有请求
我们的web容器是 有能力处理 .jsp文件 请求的,
我们 工程里的 web.xml 都是 继承与 tomcat里conf目录下的 web.xml;
在我们的tomcat里的web.xml里,有配置 对应的默认的servlet处理器,如下:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
The mappings for the JSP servlet
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The mapping for the default servlet
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置DispatcherServlet映射:
通常为springmvc映射的路径url-pattern:
0、配置:“*” 是不行的,映射路径 无法解析,启动时 会直接报错。
1、配置:“/” 的意思是:除了.jsp的请求,都会被匹配;
2、配置:“/*” 的意思是:所有的请求 都会匹配:/user、/user/getUser.jsp ?
3、配置:“*.do” 、“*.action”的意思是:url结尾以 .do 或者 .action 的请求 会匹配
4、配置:“/request/*” 的意思是: 要进行约定, 将jsp放在/views/,所有的servlet请求都用 /request/
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
/*和/都是拦截所有请求,
/会拦截的请求,但是不包含 *.jsp,
/* 的范围更大,还会拦截 *.jsp
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
来解决 POST乱码问题:
配置 编码过滤器 CharacterEncodingFilter,用来解决 中文 POST请求 乱码问题.
!!!!!!!!一定要 写在 所有 过滤器——前面!!!!!!!!!!!!!
-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--encoding 编码格式-->
<!--解决 post请求 乱码-->
<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请求 进行匹配 *
<servlet-name> 指定 具体要过滤 哪个 servlet
-->
<!--配置:“/*”的意思是:所有的请求 都会匹配,包括 .jsp 和 任何静态文件
<url-pattern>/*</url-pattern>
-->
<servlet-name>springmvc</servlet-name>
</filter-mapping>
<!--处理 “HTML中form表单提交功能 不支持 rest中 PUT 和 DELETE 请求方式” 的问题 -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
<!--
解决 HTTP Status 405 - JSPs only permit GET POST or HEAD 问题的一个方案:
自定义 一个 过滤器,将 request.method 改回 POST
<filter>
<filter-name>xxxfilter</filter-name>
<filter-class>自定义过滤器</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethod</filter-name>
<servlet-name>springmvc</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>-->
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
</web-app>
<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">
<!--
配置 前端控制器 DispatcherServlet,也可以叫做:核心调度器 或者 分发器
接收所有 除了.jsp 的请求,都交给springmvc去处理
-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
关联springmvc的配置文件
初始化参数
contextConfigLocation 配置springmvc的xml配置文件, 指定路径
也可以不配置:
会自动去WEB-INF去找一个名字叫做 [servlet-name]-servlet.xml
这里即是: springmvc-servlet.xml 的文件
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--启动时加载servlet :
当web服务器 启动时 就会创建 servlet (会自动调用servlet的构造函数及init()方法)
-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--
匹配servlet的请求,/表示匹配 除了.jsp的所有请求
我们的web容器是 有能力处理 .jsp文件 请求的,
我们 工程里的 web.xml 都是 继承与 tomcat里conf目录下的 web.xml;
在我们的tomcat里的web.xml里,有配置 对应的默认的servlet处理器,如下:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
The mappings for the JSP servlet
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The mapping for the default servlet
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置DispatcherServlet映射:
通常为springmvc映射的路径url-pattern:
0、配置:“*” 是不行的,映射路径 无法解析,启动时 会直接报错。
1、配置:“/” 的意思是:除了.jsp的请求,都会被匹配;
2、配置:“/*” 的意思是:所有的请求 都会匹配:/user、/user/getUser.jsp ?
3、配置:“*.do” 、“*.action”的意思是:url结尾以 .do 或者 .action 的请求 会匹配
4、配置:“/request/*” 的意思是: 要进行约定, 将jsp放在/views/,所有的servlet请求都用 /request/
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
/*和/都是拦截所有请求,
/会拦截的请求,但是不包含 *.jsp,
/* 的范围更大,还会拦截 *.jsp
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
来解决 POST乱码问题:
配置 编码过滤器 CharacterEncodingFilter,用来解决 中文 POST请求 乱码问题.
!!!!!!!!一定要 写在 所有 过滤器——前面!!!!!!!!!!!!!
-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--encoding 编码格式-->
<!--解决 post请求 乱码-->
<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请求 进行匹配 *
<servlet-name> 指定 具体要过滤 哪个 servlet
-->
<!--配置:“/*”的意思是:所有的请求 都会匹配,包括 .jsp 和 任何静态文件
<url-pattern>/*</url-pattern>
-->
<servlet-name>springmvc</servlet-name>
</filter-mapping>
<!--处理 “HTML中form表单提交功能 不支持 rest中 PUT 和 DELETE 请求方式” 的问题 -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
<!--
解决 HTTP Status 405 - JSPs only permit GET POST or HEAD 问题的一个方案:
自定义 一个 过滤器,将 request.method 改回 POST
<filter>
<filter-name>xxxfilter</filter-name>
<filter-class>自定义过滤器</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethod</filter-name>
<servlet-name>springmvc</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>-->
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
</web-app>
Mapping映射
@RequestMapping
@RequestMapping(value = "/hello3",params = {"username!=123","age"})
public String hello3(@ModelAttribute("username")String username){
public String hello3(@ModelAttribute("username")String username){
@RequestMapping(value = "/hello4",
headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0"})
@RequestMapping(value = "/hello5",consumes = {"application/x-www-form-urlencoded"})
// @RequestMapping(value = "/hello5",consumes = {"multipart/form-data"})
// @RequestMapping(value = "/hello5",consumes = {"application/json"})
// @GetMapping(value = "/hello5",consumes = {"multipart/form-data"})
// @PostMapping(value = "/hello5",consumes = {"application/json"})
@RequestMapping(value = "/hello6",produces = {"application/json"})
@RequestMapping(value = "/ant?")
@RequestMapping(value = "/ant*")
@RequestMapping(value = "/**/ant")
@RequestMapping(value = "/**/h*llo?")
headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0"})
@RequestMapping(value = "/hello5",consumes = {"application/x-www-form-urlencoded"})
// @RequestMapping(value = "/hello5",consumes = {"multipart/form-data"})
// @RequestMapping(value = "/hello5",consumes = {"application/json"})
// @GetMapping(value = "/hello5",consumes = {"multipart/form-data"})
// @PostMapping(value = "/hello5",consumes = {"application/json"})
@RequestMapping(value = "/hello6",produces = {"application/json"})
@RequestMapping(value = "/ant?")
@RequestMapping(value = "/ant*")
@RequestMapping(value = "/**/ant")
@RequestMapping(value = "/**/h*llo?")
// @RequestMapping(value = "/hello6",produces = "text/html;charset=utf-8")
@RequestMapping(value = "/hello6",produces = {"application/json"})
@RequestMapping(value = "/hello6",produces = {"application/json"})
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@ModelAttribute
Params参数
@RequestParam
@RequestParam(value = "username", required = false, defaultValue = "金鳞")
@RequestHeader
public String header(@RequestHeader("User-Agent") String agent,
@RequestHeader(value = "Host",required = true,defaultValue = "127.0.0.1") String host) {
@RequestHeader(value = "Host",required = true,defaultValue = "127.0.0.1") String host) {
@CookieValue
public String cookie(
// @CookieValue("JSESSIONID")
@CookieValue(value = "JSESSIONID", required = false, defaultValue = "xxxx")
String jsessionId) {
// @CookieValue("JSESSIONID")
@CookieValue(value = "JSESSIONID", required = false, defaultValue = "xxxx")
String jsessionId) {
@PathVariable:获URL目录级别里的参数
@RequestMapping("/user/{id}/{username}")
public String path01(@PathVariable("id") Integer id, @PathVariable("username") String name)
public String path01(@PathVariable("id") Integer id, @PathVariable("username") String name)
Rest风格
在web.xml里,添加 HiddenHttpMethodFilter 过滤器
在表单中 添加一个 有隐藏域 <input type="hidden" value="put" name="_method"> value就是 对应的 请求方式
将 form的 method 设置 POST
过滤器 就会 自动将 POST请求 修改成 隐藏域中 对应值的 请求
tomcat 7 以上的 版本 对 request.method 更加 严格:只支持 GET / POST / HEAD:HTTP Status 405 - JSPs only permit GET POST or HEAD
解决方式有四个:
1. 用tomcat7
2. 不用 转发,用 重定向
3. 将jsp的 page模块的 isErrorPage属性 改成 true(不建议)
jsp页面顶端的page属性:<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
4. 自定义 一个 过滤器,将 request.method 改回 POST
1. 用tomcat7
2. 不用 转发,用 重定向
3. 将jsp的 page模块的 isErrorPage属性 改成 true(不建议)
jsp页面顶端的page属性:<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
4. 自定义 一个 过滤器,将 request.method 改回 POST
Restful
@RestController
* 基于 服务api 的方式 使用 restful api:
* 使用 注解 @RestController 标识后的类,
* 那么,所有的方法 返回的是 json格式 的 数据; 而不是 某个jsp 的名字了;
* 使用 注解 @RestController 标识后的类,
* 那么,所有的方法 返回的是 json格式 的 数据; 而不是 某个jsp 的名字了;
response相关
forward:进行转发
默认是 进行转发;
return "/login.jsp";
return "forward:/login.jsp";
redirect:重定向
重定向:必须加上redirect:
return "redirect:/login.jsp";
@SessionAttributes
负责往 session里 写入数据 的
底层 会从 model中 去找一个 叫做 type的 属性
找到了 会将 type 设置一份 到 session 中;
这种方式 是 依赖 model的
@SessionAttributes写在类上,功能 在 当前控制器下,所有的 处理方法 都会 将 model 指定的属性, 写入session
底层 会从 model中 去找一个 叫做 type的 属性
找到了 会将 type 设置一份 到 session 中;
这种方式 是 依赖 model的
@SessionAttributes写在类上,功能 在 当前控制器下,所有的 处理方法 都会 将 model 指定的属性, 写入session
@SessionAttributes("type")
public class TransferringDataToViewController
public class TransferringDataToViewController
@RequestMapping("/model")
public String model(Model model) {
System.out.println(model.getClass());
model.addAttribute("type", "model");
return "main";
}
public String model(Model model) {
System.out.println(model.getClass());
model.addAttribute("type", "model");
return "main";
}
/**
* @SessionAttribute,功能是 负责 获取 session 里的 数据的
* required: 用来设置 session中 某个属性 必须存在 , 不存在 则会报错:
* HTTP Status 400 - Missing session attribute 'type' of type String
*
* 当使用注解的时:
* model 和 session 是互通的:
* session 会 从 model中 获取 指定的属性的值 并 自动写入 到 session中的 相同属性名称的 值中,
* model 也会 从 session中 获取 指定的属性的值 并 自动写入 到 model 中的 相同属性名称的 值中;
* 或者这么描述:
* session 从 session会话中 读取到 指定的属性的值后,也会往 model 中 设置一份 相同属性名称的 值
* model 从 request会话中 读取到 指定的属性的值后,也会往 session 中 设置一份 相同属性名称的 值
* @param type
* @return
*/
@RequestMapping("/annotation/session")
public String session03(@SessionAttribute(value="type",required = false) String type,
Model model ){
* @SessionAttribute,功能是 负责 获取 session 里的 数据的
* required: 用来设置 session中 某个属性 必须存在 , 不存在 则会报错:
* HTTP Status 400 - Missing session attribute 'type' of type String
*
* 当使用注解的时:
* model 和 session 是互通的:
* session 会 从 model中 获取 指定的属性的值 并 自动写入 到 session中的 相同属性名称的 值中,
* model 也会 从 session中 获取 指定的属性的值 并 自动写入 到 model 中的 相同属性名称的 值中;
* 或者这么描述:
* session 从 session会话中 读取到 指定的属性的值后,也会往 model 中 设置一份 相同属性名称的 值
* model 从 request会话中 读取到 指定的属性的值后,也会往 session 中 设置一份 相同属性名称的 值
* @param type
* @return
*/
@RequestMapping("/annotation/session")
public String session03(@SessionAttribute(value="type",required = false) String type,
Model model ){
@ModelAttribute
@ModelAttribute 的作用
@ModelAttribute 是 Spring MVC 中一个重要的注解,主要有两种使用方式:
1.方法级别使用
当用在 方法上 时,@ModelAttribute 表示该方法 会在 控制器中 所有处理方法 之前 执行,用于准备模型数据:
特点:
会在 每个 请求处理方法 调用前 执行
用于添加 多个控制器 共享的 模型属性
方法返回值 会 自动添加 到 模型中
2.参数级别使用
当用在方法参数上时,@ModelAttribute 表示 从模型中 获取或创建对象:
特点:
- 可以从 表单 绑定数据 到 对象
- 如果模型中 不存在 指定名称 的 对象,会 自动 实例化
- 常用于 表单处理
@ModelAttribute 的作用
@ModelAttribute 是 Spring MVC 中一个重要的注解,主要有两种使用方式:
1.方法级别使用
当用在 方法上 时,@ModelAttribute 表示该方法 会在 控制器中 所有处理方法 之前 执行,用于准备模型数据:
特点:
会在 每个 请求处理方法 调用前 执行
用于添加 多个控制器 共享的 模型属性
方法返回值 会 自动添加 到 模型中
2.参数级别使用
当用在方法参数上时,@ModelAttribute 表示 从模型中 获取或创建对象:
特点:
- 可以从 表单 绑定数据 到 对象
- 如果模型中 不存在 指定名称 的 对象,会 自动 实例化
- 常用于 表单处理
主要作用
数据绑定:将 请求参数 绑定到 模型对象
数据预加载:在处理方法 执行 前 准备模型数据
数据共享:在多个 请求间 共享数据
表单处理:简化 表单对象的 创建 和 绑定
工作流程
Spring 检查是否有对应的 @ModelAttribute 方法
执行这些方法 并 将结果 添加到 模型
对于 参数级别 的 注解,从 模型 或 请求中 获取/创建 对象
执行请求处理方法
@ModelAttribute 是 Spring MVC 实现数据绑定和模型管理的重要机制。
数据绑定:将 请求参数 绑定到 模型对象
数据预加载:在处理方法 执行 前 准备模型数据
数据共享:在多个 请求间 共享数据
表单处理:简化 表单对象的 创建 和 绑定
工作流程
Spring 检查是否有对应的 @ModelAttribute 方法
执行这些方法 并 将结果 添加到 模型
对于 参数级别 的 注解,从 模型 或 请求中 获取/创建 对象
执行请求处理方法
@ModelAttribute 是 Spring MVC 实现数据绑定和模型管理的重要机制。
* 被@ModelAttribute 注解过的方法,
* 会在 当前处理器 类 中,所有的 请求处理方法(被@RequestMapping注解过的方法) 执行之前 ,都会 先调用 此方法;
* 会在 当前处理器 类 中,所有的 请求处理方法(被@RequestMapping注解过的方法) 执行之前 ,都会 先调用 此方法;
类型转换器
数据校验
* 实现 数据验证的 步骤:
* 1.加入hibernate-validator依赖
* 2.一定要注意!! 将 新加入的 jar包 加入到 WEB-INF/lib 中
* 3.在 需要验证的 javaBean的 属性上面,加入对应的 验证注解,可以设置 message属性,定制 更友好的 错误提示 信息
* 4.在 需要验证的 处理方法的 对应 javaBean 参数上,加上 @Valid
* 5.在 需要验证的 处理方法的 参数中,加入 BindingResult,代表 自己处理错误,这样就不会 显示 错误页面了。
*
* 基于 原生 html form表单 实现方式:
* 1.在 将 错误信息 循环通过 map 存入到 request域 中
* 2.在jsp 通过${errors.id} 获取 对应的 错误信息
*
* 基于 spring form标签库的 实现方式:
* 1.添加一个 显示jsp的 处理方法, 一定要 传入一个 空的 User 到 model 中
* 2.在jsp中, 导入 spring-form 标签库:<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
* 3.在form标签上,一定要 加上 ModelAtrribute="user"
* 4.加上对应的 form标签, 必须都要 以<form:开头
* 实现 数据验证的 步骤:
* 1.加入hibernate-validator依赖
* 2.一定要注意!! 将 新加入的 jar包 加入到 WEB-INF/lib 中
* 3.在 需要验证的 javaBean的 属性上面,加入对应的 验证注解,可以设置 message属性,定制 更友好的 错误提示 信息
* 4.在 需要验证的 处理方法的 对应 javaBean 参数上,加上 @Valid
* 5.在 需要验证的 处理方法的 参数中,加入 BindingResult,代表 自己处理错误,这样就不会 显示 错误页面了。
*
* 基于 原生 html form表单 实现方式:
* 1.在 将 错误信息 循环通过 map 存入到 request域 中
* 2.在jsp 通过${errors.id} 获取 对应的 错误信息
*
* 基于 spring form标签库的 实现方式:
* 1.添加一个 显示jsp的 处理方法, 一定要 传入一个 空的 User 到 model 中
* 2.在jsp中, 导入 spring-form 标签库:<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
* 3.在form标签上,一定要 加上 ModelAtrribute="user"
* 4.加上对应的 form标签, 必须都要 以<form:开头
@PostMapping("/user")
public String add(@Valid User user, BindingResult result, Model model){
public String add(@Valid User user, BindingResult result, Model model){
自定义 类型转换器
***************************** 自定义 类型转换器 **************************
* 不常用,因为有 “数据格式化” 标签:@NumberFormat 和 @DateTimeFormat;
*
* 可以 直接使用 标签 直接在 类属性上 标注即可;
* 例如:在User类的birthday属性上标注 注解 @DateTimeFormat(pattern = "yyyy-MM-dd")就可以实现此类的功能
*
* 1.定义 类型转换器: 需要明确 源类型 和目标类型
* 2.在convert方法里,自定义 类型转换的 实现
* 3.在springmvc中,配置 自定义 类型转换器
* <bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="conversionService">
* <property name="converters">
* <set>
* <bean class="cn.tulingxueyuan.converters.MyStringToDateConverter"></bean>
* </set>
* </property>
* </bean>
* 4.<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
配置 自定义的 类型转换器
当 配置了 自定义的 类型转换器,需要 将 实现类 改为:FormattingConversionServiceFactoryBean,
才可以 同时支持 自定义 类型转换器 和 数据格式化的注解:@NumberFormat 和 @DateTimeFormat
但是,同一个 数据类型的 类型转换器 会 先执行 自定义的 类型转换器,
再在 自定义的 类型转换器 执行后的 结果的 基础上 再执行 相同数据类型的 注解的 类型转换器功能
当 配置了 自定义的 类型转换器,需要 将 实现类 改为:FormattingConversionServiceFactoryBean,
才可以 同时支持 自定义 类型转换器 和 数据格式化的注解:@NumberFormat 和 @DateTimeFormat
但是,同一个 数据类型的 类型转换器 会 先执行 自定义的 类型转换器,
再在 自定义的 类型转换器 执行后的 结果的 基础上 再执行 相同数据类型的 注解的 类型转换器功能
***************************** 自定义 类型转换器 **************************
* 不常用,因为有 “数据格式化” 标签:@NumberFormat 和 @DateTimeFormat;
*
* 可以 直接使用 标签 直接在 类属性上 标注即可;
* 例如:在User类的birthday属性上标注 注解 @DateTimeFormat(pattern = "yyyy-MM-dd")就可以实现此类的功能
*
* 1.定义 类型转换器: 需要明确 源类型 和目标类型
* 2.在convert方法里,自定义 类型转换的 实现
* 3.在springmvc中,配置 自定义 类型转换器
* <bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="conversionService">
* <property name="converters">
* <set>
* <bean class="cn.tulingxueyuan.converters.MyStringToDateConverter"></bean>
* </set>
* </property>
* </bean>
* 4.<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
json格式数据
@RestController
相当于 控制器类中 所有的 处理方法 都加上了 @ResponseBody, 适用于web api
@RequestBody
响应json
1.pom.xml中 加入 jackson依赖
2.将 jackson的 jar包 加入 WEB-INF的lib 文件夹
·请求Json接收
使用 @RequestBody,前提是 要保证 请求过来的参数数据 一定是 json数据,并且 内容类型 也必须是 "application/json",只有指定的数据格式,才能接收,否则拒绝请求
1.pom.xml中 加入 jackson依赖
2.将 jackson的 jar包 加入 WEB-INF的lib 文件夹
·请求Json接收
使用 @RequestBody,前提是 要保证 请求过来的参数数据 一定是 json数据,并且 内容类型 也必须是 "application/json",只有指定的数据格式,才能接收,否则拒绝请求
上传下载
upload
会将文件上传到三个地方:
1.项目路径(适用 项目小,上传 使用率 低)
2.磁盘路径 ,这种方式 需要通过 虚拟目录的 映射
3.静态资源 服务器(CDN)
1.项目路径(适用 项目小,上传 使用率 低)
2.磁盘路径 ,这种方式 需要通过 虚拟目录的 映射
3.静态资源 服务器(CDN)
基于springmvc MultiPartResolver 单文件上传
基于springmvc MultiPartResolver多文件文件上传
基于springmvc MultiPartResolver多文件文件上传--多线程
基于springmvc MultiPartResolver多文件文件上传
基于springmvc MultiPartResolver多文件文件上传--多线程
download
基于servlet api的文件下载
基于 spring ResponseEntity的 文件下载
1、不支持 缓冲区,容易造成内存溢出;(不建议使用,还是建议直接使用servlet-api的下载方式即可)
2、ResponseEntity 可以 同时定制 文件的 响应内容,响应头, 响应状态码
2、ResponseEntity 可以 同时定制 文件的 响应内容,响应头, 响应状态码
Interceptor拦截器
<mvc:view-controller>
<mvc:view-controller>是Spring MVC框架中的一个配置元素,
主要用于 简化 视图控制器的 定义,特别适用于 那些 不需要 业务逻辑处理 的 简单页面跳转 场景。
主要用途
直接映射URL到视图: 无需编写控制器方法,直接将请求路径映射到视图名称
简化配置: 减少简单页面跳转所需的控制器类和方法
处理静态页面请求: 适用于首页、欢迎页、关于页等不需要业务逻辑的页面
基本语法 在Spring MVC的XML配置文件中使用:
<mvc:view-controller path="/welcome" view-name="welcomePage"/>
主要用于 简化 视图控制器的 定义,特别适用于 那些 不需要 业务逻辑处理 的 简单页面跳转 场景。
主要用途
直接映射URL到视图: 无需编写控制器方法,直接将请求路径映射到视图名称
简化配置: 减少简单页面跳转所需的控制器类和方法
处理静态页面请求: 适用于首页、欢迎页、关于页等不需要业务逻辑的页面
基本语法 在Spring MVC的XML配置文件中使用:
<mvc:view-controller path="/welcome" view-name="welcomePage"/>
常见使用场景
1. 配置首页
<mvc:view-controller path="/about" view-name="aboutPage"/>
2. 多个 简单页面 路由
<mvc:view-controller path="/about" view-name="aboutPage"/>
<mvc:view-controller path="/contact" view-name="contactPage"/>
<mvc:view-controller path="/faq" view-name="faqPage"/>
<mvc:view-controller path="/contact" view-name="contactPage"/>
<mvc:view-controller path="/faq" view-name="faqPage"/>
3. 重定向场景
<mvc:view-controller path="/old" view-name="redirect:/new"/>
高级配置
可以与<mvc:annotation-driven>一起使用,两者不会冲突:<mvc:annotation-driven/>
<mvc:view-controller path="/home" view-name="home"/>
<mvc:view-controller path="/home" view-name="home"/>
注意事项
1. 视图解析器:需要 正确配置 视图解析器(如InternalResourceViewResolver)
2. HTTP方法:默认处理所有HTTP方法,可通过method属性限制
3. 状态码:可通过status-code属性设置响应状态码
4. 优先级:当与@RequestMapping冲突时,<mvc:view-controller> 优先级较低
1. 视图解析器:需要 正确配置 视图解析器(如InternalResourceViewResolver)
2. HTTP方法:默认处理所有HTTP方法,可通过method属性限制
3. 状态码:可通过status-code属性设置响应状态码
4. 优先级:当与@RequestMapping冲突时,<mvc:view-controller> 优先级较低
Java配置方式
如果使用Java配置而非XML,可以通过实现WebMvcConfigurer接口达到同样效果:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/welcome").setViewName("welcomePage");
registry.addViewController("/").setViewName("index");
}
}
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/welcome").setViewName("welcomePage");
registry.addViewController("/").setViewName("index");
}
}
<mvc:view-controller>是Spring MVC中 提高 开发效率 的 有用特性,特别适合项目中 大量 简单页面跳转 的 场景。
@WebFilter
@WebFilter 是 Java Servlet 3.0 规范引入的注解,用于简化过滤器的配置,无需在 web.xml 中声明过滤器。
基本用法
@WebFilter(urlPatterns = "/*") // 拦截所有请求
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化代码
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 预处理逻辑
System.out.println("Before servlet execution");
// 放行请求
chain.doFilter(request, response);
// 后处理逻辑
System.out.println("After servlet execution");
}
@Override
public void destroy() {
// 销毁代码
}
}
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化代码
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 预处理逻辑
System.out.println("Before servlet execution");
// 放行请求
chain.doFilter(request, response);
// 后处理逻辑
System.out.println("After servlet execution");
}
@Override
public void destroy() {
// 销毁代码
}
}
执行顺序控制
默认顺序 不确定,可以通过以下方式控制:
1.实现 javax.servlet.annotation.WebFilter 的 filterName 并按字母顺序
2.使用 @Order 注解(Spring环境下)
3.编程式注册(在Spring Boot中)
1.实现 javax.servlet.annotation.WebFilter 的 filterName 并按字母顺序
2.使用 @Order 注解(Spring环境下)
3.编程式注册(在Spring Boot中)
常见应用场景
1.认证/授权检查
@WebFilter("/admin/*")
public class AuthFilter implements Filter {
// 检查用户是否登录
}
2.请求/响应日志
@WebFilter("/*")
public class LoggingFilter implements Filter {
// 记录请求信息
}
3.编码设置
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void doFilter(...) {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
}
4.跨域处理
@WebFilter("/*")
public class CorsFilter implements Filter {
// 设置CORS头
}
1.认证/授权检查
@WebFilter("/admin/*")
public class AuthFilter implements Filter {
// 检查用户是否登录
}
2.请求/响应日志
@WebFilter("/*")
public class LoggingFilter implements Filter {
// 记录请求信息
}
3.编码设置
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void doFilter(...) {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
}
4.跨域处理
@WebFilter("/*")
public class CorsFilter implements Filter {
// 设置CORS头
}
注意事项
1.Servlet容器支持: 需要Servlet 3.0+容器(Tomcat 7+、Jetty 8+等)
2.Spring Boot集成:Spring Boot会自动扫描@WebFilter
3.扫描范围: 确保 过滤器类 在 组件 扫描路径 下
4.与web.xml冲突:避免同时在web.xml中配置相同过滤器
1.Servlet容器支持: 需要Servlet 3.0+容器(Tomcat 7+、Jetty 8+等)
2.Spring Boot集成:Spring Boot会自动扫描@WebFilter
3.扫描范围: 确保 过滤器类 在 组件 扫描路径 下
4.与web.xml冲突:避免同时在web.xml中配置相同过滤器
完整示例
@WebFilter(
filterName = "myAdvancedFilter",
urlPatterns = {"/api/*", "/secure/*"},
initParams = {
@WebInitParam(name = "exclusions", value = "/api/public/*"),
@WebInitParam(name = "timeout", value = "5000")
},
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.ASYNC},
asyncSupported = true
)
public class AdvancedFilter implements Filter {
private String exclusions;
private int timeout;
@Override
public void init(FilterConfig filterConfig) {
this.exclusions = filterConfig.getInitParameter("exclusions");
this.timeout = Integer.parseInt(filterConfig.getInitParameter("timeout"));
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 检查排除路径
if (isExcluded(httpRequest.getRequestURI())) {
chain.doFilter(request, response);
return;
}
// 执行过滤逻辑
long start = System.currentTimeMillis();
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - start;
if (duration > timeout) {
System.out.println("Slow request: " + httpRequest.getRequestURI());
}
}
private boolean isExcluded(String uri) {
// 实现排除逻辑
return uri.startsWith(exclusions);
}
}
filterName = "myAdvancedFilter",
urlPatterns = {"/api/*", "/secure/*"},
initParams = {
@WebInitParam(name = "exclusions", value = "/api/public/*"),
@WebInitParam(name = "timeout", value = "5000")
},
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.ASYNC},
asyncSupported = true
)
public class AdvancedFilter implements Filter {
private String exclusions;
private int timeout;
@Override
public void init(FilterConfig filterConfig) {
this.exclusions = filterConfig.getInitParameter("exclusions");
this.timeout = Integer.parseInt(filterConfig.getInitParameter("timeout"));
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 检查排除路径
if (isExcluded(httpRequest.getRequestURI())) {
chain.doFilter(request, response);
return;
}
// 执行过滤逻辑
long start = System.currentTimeMillis();
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - start;
if (duration > timeout) {
System.out.println("Slow request: " + httpRequest.getRequestURI());
}
}
private boolean isExcluded(String uri) {
// 实现排除逻辑
return uri.startsWith(exclusions);
}
}
拦截器
1、定义拦截器,必须要 实现 HandlerInterceptor
2、在springmvc配置文件中 增加 拦截器配置
2、在springmvc配置文件中 增加 拦截器配置
<mvc:interceptors>
<bean class="cn.outstanding.interceptors.MyInterceptor"></bean>
<!--直接 配置一个Bean,会拦截 SpringMVC的 所有请求 -->
<bean class="com.outstanding.interceptors.MyFirstInterceptor"/>
<bean class="com.outstanding.interceptors.MySecondInterceptor"/>
<bean class="com.outstanding.interceptors.InvokeTimeIntercptor"/>
<!--如果不是 所有的 请求 都要拦截,可以 加一个 <mvc:interceptor>-->
<mvc:interceptor>
<!--需要 拦截的 请求 -->
<mvc:mapping path="/**"/>
<!--不需要 拦截的 请求(只会拦截get请求)-->
<mvc:exclude-mapping path="/login"/>
<!--拦截器-->
<bean class="com.outstanding.interceptors.CheckLoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<bean class="cn.outstanding.interceptors.MyInterceptor"></bean>
<!--直接 配置一个Bean,会拦截 SpringMVC的 所有请求 -->
<bean class="com.outstanding.interceptors.MyFirstInterceptor"/>
<bean class="com.outstanding.interceptors.MySecondInterceptor"/>
<bean class="com.outstanding.interceptors.InvokeTimeIntercptor"/>
<!--如果不是 所有的 请求 都要拦截,可以 加一个 <mvc:interceptor>-->
<mvc:interceptor>
<!--需要 拦截的 请求 -->
<mvc:mapping path="/**"/>
<!--不需要 拦截的 请求(只会拦截get请求)-->
<mvc:exclude-mapping path="/login"/>
<!--拦截器-->
<bean class="com.outstanding.interceptors.CheckLoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
i18n-国际化
解决 java的 硬编码的 国际化步骤
1、在属性资源文件中,假如 需要 国际化的 硬编码内容
2、在spring-mvc.xml里,注册 国际化资源文件 到 messageSource对象里。
3、根据 messageSource.getMessage 获取 国际内容
string code: 资源文件中的key
Object[] args: 文本中的参数,可以用占位符的方式在资源文件文本中设置参数占位符:{0},{2}
Locale locale: 当前本地化语言对象
jsp页面上的<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
jsp页面上的<spring:message,会自动获取对应的国际化信息
2、在spring-mvc.xml里,注册 国际化资源文件 到 messageSource对象里。
3、根据 messageSource.getMessage 获取 国际内容
string code: 资源文件中的key
Object[] args: 文本中的参数,可以用占位符的方式在资源文件文本中设置参数占位符:{0},{2}
Locale locale: 当前本地化语言对象
jsp页面上的<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
jsp页面上的<spring:message,会自动获取对应的国际化信息
<!--注册国际化资源文件-->
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basenames">
<array>
<value>i18n.login</value>
<!--如果还有别的国际化,还可以继续在这里增加value配置-->
</array>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basenames">
<array>
<value>i18n.login</value>
<!--如果还有别的国际化,还可以继续在这里增加value配置-->
</array>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
Exception-处理异常
@ControllerAdvice
被 @ControllerAdvice 标记的类是 处理全局异常的类:
1、全局异常
2、处理器异常
3、全局异常中的 具体异常
被拦截到的 优先级:
a、处理器异常 优先级 最高; 就近原则 匹配处理;
如果 处理器异常 中,没有 匹配到 异常,那么则会去 全局异常 里 找匹配;谁 最精准 就交给 谁 处理。
b、全局异常中的 具体异常 优先级 其次;
如果 处理器异常 中,没有定义 异常,那么就会 按照 精准原则 去 匹配处理;谁 最精准 就交给 谁 处理。
c、全局异常 优先级 最后; 当异常 没有满足 上面两种情况,就会交给 全局异常 处理
在实际项目开发中,往往 只需要 一个 全局异常 就够了
统一异常处理: 同时处理 普通请求 和 ajax请求
普通请求:返回视图,错误信息
ajax: 返回json
{
code
message
}
1、全局异常
2、处理器异常
3、全局异常中的 具体异常
被拦截到的 优先级:
a、处理器异常 优先级 最高; 就近原则 匹配处理;
如果 处理器异常 中,没有 匹配到 异常,那么则会去 全局异常 里 找匹配;谁 最精准 就交给 谁 处理。
b、全局异常中的 具体异常 优先级 其次;
如果 处理器异常 中,没有定义 异常,那么就会 按照 精准原则 去 匹配处理;谁 最精准 就交给 谁 处理。
c、全局异常 优先级 最后; 当异常 没有满足 上面两种情况,就会交给 全局异常 处理
在实际项目开发中,往往 只需要 一个 全局异常 就够了
统一异常处理: 同时处理 普通请求 和 ajax请求
普通请求:返回视图,错误信息
ajax: 返回json
{
code
message
}
@ExceptionHandler处理异常
通过 @ExceptionHandler,可以在 方法中 记录日志
转发一个 友好的界面 进行提示:
经验:1.记录日志中
2.可以将 异常 转发到 错误页面, 将 错误信息 在一个 隐藏的div 中显示
如果 @ExceptionHandler标注的方法 写在 @Controller类中,只能处理 当前控制器类 的 处理方法
转发一个 友好的界面 进行提示:
经验:1.记录日志中
2.可以将 异常 转发到 错误页面, 将 错误信息 在一个 隐藏的div 中显示
如果 @ExceptionHandler标注的方法 写在 @Controller类中,只能处理 当前控制器类 的 处理方法
@ExceptionHandler(RuntimeException.class)
// @ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex){
System.out.println("@Controller异常处理");
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
System.out.println(ex.getMessage());
//打印异常的详细信息
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
System.out.println(sw.toString()); // 日志记录
return modelAndView;
}
// @ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex){
System.out.println("@Controller异常处理");
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
System.out.println(ex.getMessage());
//打印异常的详细信息
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
System.out.println(sw.toString()); // 日志记录
return modelAndView;
}
@ResponseStatus
@ResponseStatus 是 Spring Framework 中的一个注解,主要用于控制 HTTP 响应的状态码和原因描述。它可以用在类级别或方法级别
通常用于以下场景
--------------------------------------------------------------------------------
1. 标记异常类(用于全局异常处理)
当某个异常被抛出时,Spring 会自动返回指定的 HTTP 状态码和错误信息。
示例:
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "User not found")
public class UserNotFoundException extends RuntimeException {
// 当抛出此异常时,Spring 会自动返回 404 状态码和 "User not found"
}
当 UserNotFoundException 抛出时,客户端会收到:
HTTP/1.1 404 Not Found
{"error": "User not found"}
2. 直接标记控制器方法(指定返回状态码)
即使方法正常执行,也可以通过 @ResponseStatus 强制返回特定的 HTTP 状态码。
示例:
@PostMapping("/create")
@ResponseStatus(HttpStatus.CREATED) // 无论是否显式返回,状态码始终是 201
public void createUser(@RequestBody User user) {
// 业务逻辑
}
调用此接口后,响应状态码会是 201 Created,而不是默认的 200 OK。
--------------------------------------------------------------------------------
3. 自定义错误消息
结合 reason 或通过 MessageSource 国际化支持,可以返回更友好的错误提示。
示例:
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Invalid input data")
public class InvalidInputException extends RuntimeException {
}
客户端会收到:
HTTP/1.1 400 Bad Request
{"error": "Invalid input data"}
--------------------------------------------------------------------------------
1. 标记异常类(用于全局异常处理)
当某个异常被抛出时,Spring 会自动返回指定的 HTTP 状态码和错误信息。
示例:
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "User not found")
public class UserNotFoundException extends RuntimeException {
// 当抛出此异常时,Spring 会自动返回 404 状态码和 "User not found"
}
当 UserNotFoundException 抛出时,客户端会收到:
HTTP/1.1 404 Not Found
{"error": "User not found"}
2. 直接标记控制器方法(指定返回状态码)
即使方法正常执行,也可以通过 @ResponseStatus 强制返回特定的 HTTP 状态码。
示例:
@PostMapping("/create")
@ResponseStatus(HttpStatus.CREATED) // 无论是否显式返回,状态码始终是 201
public void createUser(@RequestBody User user) {
// 业务逻辑
}
调用此接口后,响应状态码会是 201 Created,而不是默认的 200 OK。
--------------------------------------------------------------------------------
3. 自定义错误消息
结合 reason 或通过 MessageSource 国际化支持,可以返回更友好的错误提示。
示例:
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Invalid input data")
public class InvalidInputException extends RuntimeException {
}
客户端会收到:
HTTP/1.1 400 Bad Request
{"error": "Invalid input data"}
常见用途
- 替代
ResponseEntity:如果不需要复杂响应体,直接用 @ResponseStatus 更简洁。
- 统一异常处理
:结合 @ControllerAdvice 或自定义异常,规范全局错误码。
- RESTful 设计
:比如 201 Created 用于资源创建,204 No Content 用于删除操作。
- 替代
ResponseEntity:如果不需要复杂响应体,直接用 @ResponseStatus 更简洁。
- 统一异常处理
:结合 @ControllerAdvice 或自定义异常,规范全局错误码。
- RESTful 设计
:比如 201 Created 用于资源创建,204 No Content 用于删除操作。
注意事项
- 如果同时使用
@ResponseStatus 和 ResponseEntity,后者会覆盖前者的状态码。
- Spring 5 以后,
reason 支持通过占位符动态解析(如 reason = "{error.user.notfound}")。
--------------------------------------------------------------------------------
总结:@ResponseStatus 是一种声明式定义 HTTP 响应状态码的方式,让代码更简洁,尤其适合 REST API 开发。
- 如果同时使用
@ResponseStatus 和 ResponseEntity,后者会覆盖前者的状态码。
- Spring 5 以后,
reason 支持通过占位符动态解析(如 reason = "{error.user.notfound}")。
--------------------------------------------------------------------------------
总结:@ResponseStatus 是一种声明式定义 HTTP 响应状态码的方式,让代码更简洁,尤其适合 REST API 开发。
0 条评论
下一页