当前位置: 首页 > news >正文

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");}}
http://www.jsqmd.com/news/304206/

相关文章:

  • 【Linux 驱动开发】六. 中断和阻塞/非阻塞IO的实现
  • 基于spring+vue的校园勤工俭学平台[spring]-计算机毕业设计源码+LW文档
  • 基于SpringBoot的社区医疗服务管理小程序的设计与开发(源码+lw+部署文档+讲解等)
  • 计算机毕业设计springboot飞机票预定系统 基于SpringBoot的航班在线预订平台 SpringBoot驱动的民航电子客票销售系统
  • 基于SpringBoot的扶贫助农系统及其小程序的实现(源码+lw+部署文档+讲解等)
  • 计算机毕业设计springboot飞羽羽毛球俱乐部管理系统 基于SpringBoot的羽球馆综合运营平台 SpringBoot驱动的羽毛球会所活动与场地预约系统
  • 基于SpringBoot的健康管理微信小程序的设计与实现(源码+lw+部署文档+讲解等)
  • 基于SpringBoot的旅游线路定制微信小程序(源码+lw+部署文档+讲解等)
  • 计算机毕业设计springboot飞机票订票管理系统 基于SpringBoot的航空客运票务管理平台 SpringBoot驱动的在线航班预订与订单管理系统
  • 2026最新益气健脾滋补品/益气健脾保健品/益气健脾口服液企业推荐复方红衣补血口服液:传承创新,这家老字号实力引领
  • AsyPPO_ 轻量级mini-critics如何提升大语言模型推理能力 - 实践
  • 电脑加密软件应该怎么选择?六款电脑加密软件推荐(建议收藏)
  • 链家二手房数据爬取、聚类分析与可视化展示实践
  • MySQL UDF 一例
  • IK-M20的体验
  • VRRP:智算中心网络高可用的关键技术
  • Python包管理|如何解决 pip install requests[socks] 报错:zsh:1: no matches found: requests[socks] 问题
  • 如何解决 pip install 与 PyCharm 解释器版本不一致导致导入失败问题
  • 如何解决 pip install 导入失败 因 PYTHONPATH 污染(本地同名包遮蔽)问题
  • Python系列环境兼容|如何解决 pip install 平台报错 GLIBC_2.64 not found(manylinux 与系统不兼容)问题
  • Python系列环境兼容|如何解决 pip install 平台报错 macOS arm64 无预编译轮子(需 Rosetta/源码)问题
  • OpenEuler编译兼容|如何解决checking for liblz4... no configure: error: Package requirements (liblz4)问题
  • AI框架兼容|如何解决RuntimeError: Only Hopper supports different V headdim 问题
  • 如何解决 pip install 未激活虚拟环境导致安装到系统 Python 问题
  • 多相机无重叠区域的坐标系统一(大标定板歪斜情况下的精确物理坐标获取)
  • 安科瑞ASLP-LMB 智能防雷环境预警监测箱
  • Cron表达式
  • 客户端负载均衡与服务端负载均衡解释与对比
  • 分布式事务概念解析
  • 知识管理的智能进化:企业级智能体开发平台如何打造企业“第二大脑”?