分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

web应用中的异常处理

发布时间:2023-09-06 01:15责任编辑:傅花花关键词:web应用

楼主前几天写了一篇“Java子线程中的异常处理(通用)”文章,介绍了在多线程环境下3种通用的异常处理方法。

但是平时大家的工作一般是基于开发框架进行的(比如Spring MVC,或Spring Boot),所以会有相应特定的异常处理方法,这篇文章要介绍的就是web应用中的异常处理。 

想快速解决问题的小伙伴可以只看“解决办法”,想进一步了解细节的小伙伴还可以看“深入剖析”部分。

适用场景

使用Spring MVC或Spring Boot框架搭建的web应用

解决办法

@ControllerAdvice注解 + @ExceptionHandler注解

实现一个异常处理类,在类上应用@ControllerAdvice注解,并在异常处理方法上应用@ExceptionHandler注解。那么在web应用中,当Controller的@RequestMapping方法抛出指定的异常类型时,@ExceptionHandler修饰的异常处理方法就会执行。

示例:

 1 @ControllerAdvice 2 public class WebServerExceptionHandler { 3 ????Logger log = LoggerFactory.getLogger(this.getClass()); 4 ?5 ????public WebServerExceptionHandler() { 6 ????} 7 ?8 ????// 指定捕获的异常类型,这里是自定义的SomeException 9 ????@ExceptionHandler({SomeException.class})10 ????public ResponseEntity<WebServerExceptionResponse> handle(HttpServletResponse response, SomeException ex) {11 ????????WebServerExceptionResponse body = new WebServerExceptionResponse();12 ????????body.setStatus(ex.getStatus());13 ????????body.setMessage(ex.getMessage());14 ????????this.log.info("handle SomeException, status:{}, message:{}", ?new Object[]{body.getStatus(), body.getMessage()});15 ????????return new ResponseEntity(body, HttpStatus.valueOf(ex.getStatus()));16 ????}17 18 ????// 指定捕获的异常类型,这里是自定义的OtherException19 ????@ExceptionHandler({OtherException.class})20 ????public ResponseEntity<WebServerExceptionResponse> handle(HttpServletResponse response, OtherException ex) {21 ????????WebServerExceptionResponse body = new WebServerExceptionResponse();22 ????????body.setStatus(ex.getStatus());23 ????????body.setMessage(ex.getMessage());24 ????????this.log.info("handle OtherException, status:{}, message:{}", ?new Object[]{body.getStatus(), body.getMessage()});25 ????????return new ResponseEntity(body, HttpStatus.valueOf(ex.getStatus()));26 ????}27 }

 深入剖析

@ControllerAdvice的定义如下: 

 1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Component 5 public @interface ControllerAdvice { 6 ?7 ????String[] value() default {}; 8 ?9 ????String[] basePackages() default {};10 11 ????Class<?>[] basePackageClasses() default {};12 13 ????Class<?>[] assignableTypes() default {};14 15 ????Class<? extends Annotation>[] annotations() default {};16 17 }

可以看出它应用在TYPE类型的元素上(也即class或interface),运行时生效。

作用是Controller类的帮助注解,一般搭配@ExceptionHandler注解,用来处理Controller的@RequestMapping修饰的方法抛出的异常。

楼主根据源码的注释整理了5个参数的含义,它们都是用来限定需要处理的Controller的:

  • value():等同于basePackages,表示需要被处理的Controller包名数组,例如 @ControllerAdvice("org.my.pkg")。如果不指定,就代表处理所有的Controller类
  • basePackages():表示需要被处理的Controller包名数组,例如 @ControllerAdvice(basePackages={"org.my.pkg","org.my.other.pkg"})
  • basePackageClasses():通过标记类来指定Controller包名数组
  • assignableTypes():通过类的Class对象来指定Controller包名数组
  • annotations():被注解修饰的Controller需要被处理

性能考虑:不要指定过多的参数和异常处理策略,因为异常检查和处理都是在运行时做的。

@ExceptionHandler的定义如下:

 1 @Target(ElementType.METHOD) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 public @interface ExceptionHandler { 5 ?6 ????/** 7 ?????* Exceptions handled by the annotated method. If empty, will default to any 8 ?????* exceptions listed in the method argument list. 9 ?????*/10 ????Class<? extends Throwable>[] value() default {};11 12 }

可以看出它作用在方法上面,而且参数很好理解,就是需要处理的异常类的Class对象数组。

但是,它对修饰的异常处理方法的参数和返回值有限定,楼主根据源码的注释整理如下:

(1)异常处理方法的参数限定,可以是以下类型,顺序任意:

  •  异常类对象
  • HttpServletRequest、HttpServletResponse
  • HttpSession
  • InputStream/Reader、OutputStream/Writer

(2)异常处理方法的返回值限定,最终会写入response流:

  • ResponseEntity
  • HttpServletResponse
  • ModelAndView
  • Model
  • Map
  • View 

总结

以上就是在Spring web应用中的异常处理方法:使用@ControllerAdvice搭配@ExceptionHandler修饰自定义异常处理方法,处理来自Controller类中的@RequestMapping方法抛出的异常。

使用时需要根据实际情况,合理设置@ControllerAdvice和@ExceptionHandler的参数。

web应用中的异常处理

原文地址:http://www.cnblogs.com/yangfanexp/p/7616570.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved