news 2026/9/23 7:09:21

springmvc 全局异常处理 and 拦截器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
springmvc 全局异常处理 and 拦截器

文章目录

    • 配置类 SpringMvcInit
    • 配置类 MvcConfig
      • 全局异常处理器
      • User实体类 (参数校验)
      • UserController
      • 拦截器 MyInterceptor
      • 拦截器 MyInterceptor1

配置类 SpringMvcInit

packagecom.cool.config;importorg.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;"可以被 web项目加载,会初始化ioc容器,会设置 dispatcherServlet的地址"publicclassSpringMvcInitextendsAbstractAnnotationConfigDispatcherServletInitializer{@OverrideprotectedClass<?>[]getRootConfigClasses(){returnnewClass[0];}"设置配置类"@OverrideprotectedClass<?>[]getServletConfigClasses(){returnnewClass[]{MvcConfig.class};}"配置springmvc内部自带servlet的访问地址"@OverrideprotectedString[]getServletMappings(){returnnewString[]{"/"};}}

配置类 MvcConfig

packagecom.cool.config;importcom.cool.interceptor.MyInterceptor;importcom.cool.interceptor.MyInterceptor1;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;importorg.springframework.web.servlet.config.annotation.EnableWebMvc;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;@EnableWebMvc@Configuration@ComponentScan({"com.cool.controller","com.cool.error"})publicclassMvcConfigimplementsWebMvcConfigurer{/* 通过configurer.enable()启用默认Servlet处理。 当请求无法匹配到Spring的控制器时,会回退到Servlet容器的默认Servlet(如:Tomcat的DefaultServlet), 主要用于,处理静态资源(如HTML、JS、CSS)。 典型场景: 配置后,对 /static/** 的请求会先由Spring处理,未匹配则交给容器默认Servlet */@OverridepublicvoidconfigureDefaultServletHandling(DefaultServletHandlerConfigurerconfigurer){configurer.enable();}@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){// 配置方案-1:拦截全部请求registry.addInterceptor(newMyInterceptor());// 配置方案-2:拦截指定的请求// *:任意一层字符串;**:任意多层字符串registry.addInterceptor(newMyInterceptor()).addPathPatterns("/user/**");// 拦截 user/ 下的所有请求// 配置方案-3:排除拦截// 拦截 user/ 下除了 /user/data1 之外的请求地址registry.addInterceptor(newMyInterceptor()).addPathPatterns("/user/**").excludePathPatterns("/user/data1");// 如果有多个拦截器,执行流程是怎样的呢?/* 先声明的优先级高,优先级高的在外层, MyInterceptor.preHandle MyInterceptor1.preHandle OrderController.data MyInterceptor1.postHandle MyInterceptor.postHandle MyInterceptor1.afterCompletion MyInterceptor.afterCompletion */registry.addInterceptor(newMyInterceptor());registry.addInterceptor(newMyInterceptor1());}}

全局异常处理器

全局异常处理器 GlobalException 使用了 @RestControllerAdvice,
处理 ArithmeticException 和 Exception。
当 Controller 中的方法抛出这些异常时,会被对应的 @ExceptionHandler 方法捕获并处理。

packagecom.cool.error;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.RestControllerAdvice;/** * 全局异常处理器 * * @ControllerAdvice * 作用:全局异常发生,就会走此类的方法,可以返回 逻辑视图、转发、重定向 * * @RestControllerAdvice * 相当于 @ControllerAdvice 和 @ResponseBody 的组合, * 可以直接返回 json 字符串 * */@RestControllerAdvicepublicclassGlobalException{/* 发生异常后 -> ControllerAdvice注解的类型 -> @ExceptionHandler(指定的异常) -> 执行handler 如果,没有找到指定的异常,就会找父类Exception */"精准匹配算术异常"@ExceptionHandler(ArithmeticException.class)publicObjectArithmeticExceptionHandler(ArithmeticExceptione){// 自定义异常处理即可Stringmessage=e.getMessage();System.out.println("ArithmeticExceptionHandler="+message);returnmessage;}"兜底所有异常"@ExceptionHandler(Exception.class)publicObjectExceptionHandler(Exceptione){Stringmessage=e.getMessage();System.out.println("ExceptionHandler="+message);returnmessage;}}

User实体类 (参数校验)

packagecom.cool.pojo;importjakarta.validation.constraints.Email;importjakarta.validation.constraints.Min;importjakarta.validation.constraints.NotBlank;importjakarta.validation.constraints.Past;importlombok.Data;importorg.hibernate.validator.constraints.Length;importjava.util.Date;/** * name:不为null、不为空字符串 * 字符串不为空:@NotBlank * 集合不为空:@NotEmpty * 包装类型不为空:@NotNull * * password:长度大于6 */@DatapublicclassUser{@NotBlankprivateStringname;@Length(min=6,max=20)privateStringpassword;@Min(1)privateintage;@EmailprivateStringemail;@PastprivateDatebirthday;}

UserController

packagecom.cool.controller;importcom.cool.pojo.User;importorg.springframework.validation.BindingResult;importorg.springframework.validation.annotation.Validated;importorg.springframework.web.bind.annotation.*;importjava.util.HashMap;importjava.util.Map;@RestController@RequestMapping("user")publicclassUserController{/** * 步骤1:实体类属性添加校验注解 * 步骤2:handler(@Validated 实体类对象){} * 细节: * param、json 校验注解都有效果 * 只不过,json参数的话,需要用 @RequestBody 修饰形参哦! * * 这里有个天坑:如果不符合校验规则,会直接向前端抛出异常 * 解决办法: * handler(@Validated 实体类对象, BindingResult request){} * 多加一个 BindingResult request 参数, * 此参数,必须紧挨着 @Validated 实体类对象,否则此参数不管用 */@PostMapping("register")publicObjectregister(@Validated@RequestBodyUseruser,BindingResultresult){System.out.println("user= "+user);if(result.hasErrors()){// 有错误的话,就不直接返回给前端了,可以在这里自定义内容,返回给前端Mapdata=newHashMap();data.put("code",400);data.put("msg","参数校验异常");returndata;}returnuser;}@GetMapping("data")publicStringdata(){// 这个方法,做成,空指针异常Stringname=null;name.toString();// NullPointerException,报错后,就不会执行下面的代码了,就会取异常处理那里return"data - ok";}@GetMapping("data1")publicStringdata1(){// 这个方法,做成,算数异常inti=1/0;// ArithmeticException: / by zeroreturn"data1 - ok";}}

拦截器 MyInterceptor

packagecom.cool.interceptor;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;importorg.springframework.web.servlet.HandlerInterceptor;importorg.springframework.web.servlet.ModelAndView;/** * 声明好这个类之后, * 需要在 MvcConfig 类中注册上 */publicclassMyInterceptorimplementsHandlerInterceptor{/** * handler执行之前触发 * @param request 请求对象 * @param response 响应对象 * @param handler 就是我们要调用的方法对象 * @return true:放行,false:拦截 * @throws Exception */@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{System.out.println("request= "+request+",response= "+response+",handler = "+handler);System.out.println("MyInterceptor.preHandle");returntrue;}/** * 当 handler 执行完毕后,触发此方法,没有拦截机制了 * 此方法只有在 preHandle方法 return true 的时候才会被执行 * @param request * @param response * @param handler * @param modelAndView 返回的视图和共享域的数据对象,如果没有的话,返回null * @throws Exception * * 对 响应结果 的处理 * */@OverridepublicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{System.out.println("MyInterceptor.postHandle");}/** * 整体处理完毕后,会触发这个方法 * @param request * @param response * @param handler * @param ex 如果 handler方法报错了,这个参数就是异常对象 * @throws Exception */@OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{System.out.println("MyInterceptor.afterCompletion");}}

拦截器 MyInterceptor1

packagecom.cool.interceptor;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;importorg.springframework.web.servlet.HandlerInterceptor;importorg.springframework.web.servlet.ModelAndView;/** * 声明好这个类之后, * 需要在 MvcConfig 类中注册上 */publicclassMyInterceptor1implementsHandlerInterceptor{/** * handler执行之前触发 * @param request 请求对象 * @param response 响应对象 * @param handler 就是我们要调用的方法对象 * @return true:放行,false:拦截 * @throws Exception */@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{System.out.println("MyInterceptor1.preHandle");returntrue;}/** * 当 handler 执行完毕后,触发此方法,没有拦截机制了 * 此方法只有在 preHandle方法 return true 的时候才会被执行 * @param request * @param response * @param handler * @param modelAndView 返回的视图和共享域的数据对象,如果没有的话,返回null * @throws Exception * * 对 响应结果 的处理 * */@OverridepublicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{System.out.println("MyInterceptor1.postHandle");}/** * 整体处理完毕后,会触发这个方法 * @param request * @param response * @param handler * @param ex 如果 handler方法报错了,这个参数就是异常对象 * @throws Exception */@OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{System.out.println("MyInterceptor1.afterCompletion");}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/22 5:24:57

【Linux 驱动开发】六. 中断和阻塞/非阻塞IO的实现

中断和阻塞/非阻塞IO的实现 1. 中断1.1 概念1.1.1 中断源的概念 1.2 设备树中描述中断信息1.3 中断实例---以按键为例1.3.1 在设备树中添加结点1.3.2 驱动实现 1.4 使用gpio子系统实现中断处理1.4.1 旧的gpio方式1.4.2 新的gpio方式 2. 阻塞IO和非阻塞IO的实现2.1 阻塞IO的实现…

作者头像 李华
网站建设 2026/9/20 11:36:35

如何解决 pip install 与 PyCharm 解释器版本不一致导致导入失败问题

摘要 你想解决因pip install安装包时使用的Python解释器&#xff0c;与PyCharm项目配置的解释器版本/路径不一致&#xff0c;导致在PyCharm中导入包提示ModuleNotFoundError或“Unresolved reference”的问题。这个问题是Python开发中新手高频踩坑点——核心根源是PyCharm的项…

作者头像 李华
网站建设 2026/9/21 22:59:49

赋能智慧教育:企业级智能体开发平台在个性化学习与校园管理中的应用

教育领域正寻求因材施教与规模化管理的平衡。企业级智能体开发平台为构建“AI助教”和“智能校园管理中枢”提供了技术基础&#xff0c;有望推动教学方式与教育管理的深刻变革。 一、个性化学习伙伴与智能辅导 学习智能体可以为每位学生充当“个性化学习伙伴”。它能根…

作者头像 李华
网站建设 2026/9/19 20:33:13

实现Altium许可证精细化管理的五个阶段

实现Altium许可证精细化管理的五个阶段 ——助力企业实现高效、合规的EDA资源分配在电子设计自动化&#xff08;EDA&#xff09;领域&#xff0c;Altium Designer作为一款广受欢迎的PCB设计软件&#xff0c;其许可证管理复杂度企业规模的扩大而不断提升。是在多项目、多团队协作…

作者头像 李华