web应用中的异常处理
楼主前几天写了一篇“Java子线程中的异常处理(通用)”文章,介绍了在多线程环境下3种通用的异常处理方法。
但是平时大家的工作一般是基于开发框架进行的(比如Spring MVC,或Spring Boot),所以会有相应特定的异常处理方法,这篇文章要介绍的就是web应用中的异常处理。
想快速解决问题的小伙伴可以只看“解决办法”,想进一步了解细节的小伙伴还可以看“深入剖析”部分。
适用场景
使用Spring MVC或Spring Boot框架搭建的web应用
解决办法
@ControllerAdvice注解 + @ExceptionHandler注解
实现一个异常处理类,在类上应用@ControllerAdvice注解,并在异常处理方法上应用@ExceptionHandler注解。那么在web应用中,当Controller的@RequestMapping方法抛出指定的异常类型时,@ExceptionHandler修饰的异常处理方法就会执行。
示例:
@ControllerAdvice
public class WebServerExceptionHandler {
Logger log = LoggerFactory.getLogger(this.getClass());
public WebServerExceptionHandler() {
}
// 指定捕获的异常类型,这里是自定义的SomeException
@ExceptionHandler({SomeException.class})
public ResponseEntity<WebServerExceptionResponse> handle(HttpServletResponse response, SomeException ex) {
WebServerExceptionResponse body = new WebServerExceptionResponse();
body.setStatus(ex.getStatus());
body.setMessage(ex.getMessage());
this.log.info("handle SomeException, status:{}, message:{}", new Object[]{body.getStatus(), body.getMessage()});
return new ResponseEntity(body, HttpStatus.valueOf(ex.getStatus()));
}
// 指定捕获的异常类型,这里是自定义的OtherException
@ExceptionHandler({OtherException.class})
public ResponseEntity<WebServerExceptionResponse> handle(HttpServletResponse response, OtherException ex) {
WebServerExceptionResponse body = new WebServerExceptionResponse();
body.setStatus(ex.getStatus());
body.setMessage(ex.getMessage());
this.log.info("handle OtherException, status:{}, message:{}", new Object[]{body.getStatus(), body.getMessage()});
return new ResponseEntity(body, HttpStatus.valueOf(ex.getStatus()));
}
}
深入剖析
@ControllerAdvice的定义如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] assignableTypes() default {};
Class<? extends Annotation>[] annotations() default {};
}
可以看出它应用在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的定义如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
/**
* Exceptions handled by the annotated method. If empty, will default to any
* exceptions listed in the method argument list.
*/
Class<? extends Throwable>[] value() default {};
}
可以看出它作用在方法上面,而且参数很好理解,就是需要处理的异常类的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应用中的异常处理的更多相关文章
- ASP.NET Web API 中的异常处理(转载)
转载地址:ASP.NET Web API 中的异常处理
- 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理
原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...
- 2017.10.28 针对Java Web应用中错误异常处理方法的运用
针对Java Web应用中错误异常处理方法的运用 在javaweb中其异常都需要对Checked Exception之下的Exception进行继承,并且有选择地对发生的错误和异常进行处理.Java同 ...
- 【Web】Web开发中的异常处理方案
我认为最合理的做法: 1.dao层不捕获异常.不抛出异常:spring框架将底层的数据库checked异常封装成unchecked异常了 2.service层捕获异常,并抛出自定义unchecked异 ...
- (五)web服务中的异常处理
一.服务端发布服务 package com.webservice; import javax.jws.WebParam; import javax.jws.WebResult; import java ...
- Java web的几种异常处理 (转)
一.在servlet容器中处理异常 以下两种方式: 1. 在web.xml定义异常处理 如果没有在web的应用中作异常处理,那么异常就会抛给Servlet容器,应该说此时Servlet容器是处理异常 ...
- 转:Spring Boot应用中的异常处理
引自:https://www.cnblogs.com/yangfanexp/p/7616570.html 楼主前几天写了一篇“Java子线程中的异常处理(通用)”文章,介绍了在多线程环境下3种通用的异 ...
- 编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理
原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保留下! 文章宗旨:Talk is cheap show me the code. 大成若缺,其 ...
- WEB 项目中的全局异常处理
在web 项目中,遇到异常一般有两种处理方式:try.....catch....:throw 通常情况下我们用try.....catch.... 对异常进行捕捉处理,可是在实际项目中随时的进行异常捕捉 ...
随机推荐
- HTML5新增属性data-*和js/jquery之间的交互
HTML5新增属性data- data-自定义属性,这种方式的自定义属性解决属性混乱无状态管理的现状 书写实例 <div data-role="page" data-last ...
- Azure Powershell对ARM资源的基本操作
本分主要介绍Windows Azure Powershell对ARM资源的基本操作 1.登陆ARM模式,命令:Login-AzureRmAccount -EnvironmentName AzureCh ...
- CentOS 7 更改网卡名为eth0
今天用VBOX安装了CentOS7, 但是安装完之后,发现没有ifconfig命令,在网上搜了一下解决办法,在可以连网状态下,输入下面命令即可 然后就可以用ifconfig命令了. 使用ifconfi ...
- Java代理详解
一.概述 代理模式是Java常用的设计模式之一,实现代理模式要求代理类和委托类(被代理的类)具有相同的方法(提供相同的服务),代理类对象自身并不实现真正的核心逻辑,而是通过调用委托类对象的相关方法来处 ...
- 如何通过navigator.userAgent判断是哪款浏览器?
userAgent 用户代理.通过浏览器控制台alert( navigator.userAgent );可以获得当前浏览器的信息,如果逆推呢? 通过navigator.userAgent判断是哪款浏览 ...
- 201521123082 《Java程序设计》第10周学习总结
201521123082 <Java程序设计>第10周学习总结 标签(空格分隔): java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. A ...
- JAVA基础第七组(5道题)
31.题目:将一个数组逆序输出. 1.程序分析:用第一个与最后一个交换. package com.niit.homework1; /** * @author: Annie * ...
- 201521123119《Java程序设计》第7周学习总结
1. 本周学习总结 2. 书面作业 Q1.ArrayList代码分析 Q1.1 解释ArrayList的contains源代码 这段代码的主要目的是判断在对ArrayList遍历时所用的方法,在输入参 ...
- 201521123054《JAVA程序设计》第三周学习总结
本周学习总结 书面作业 代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; public st ...
- 201521123018 《Java程序设计》第1周学习总结
1. 本章学习总结 *Java程序的特点 *可以跨平台运行 *语言简单 *利用控制台运行java程序 *cmd调出控制台->用javac指令编译源代码->用java指令运行 2. 书面作业 ...