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