Spring MVC异常统一处理的三种方式
Spring 统一异常处理有 3 种方式,分别为:
- 使用 @ ExceptionHandler 注解
- 实现 HandlerExceptionResolver 接口
- 使用 @controlleradvice 注解
使用 @ ExceptionHandler 注解
使用该注解有一个不好的地方就是:进行异常处理的方法必须与出错的方法在同一个Controller里面。使用如下:
@Controller
public class GlobalController { /**
* 用于处理异常的
* @return
*/
@ExceptionHandler({MyException.class})
public String exception(MyException e) {
System.out.println(e.getMessage());
e.printStackTrace();
return "exception";
} @RequestMapping("test")
public void test() {
throw new MyException("出错了!");
}
}
可以看到,这种方式最大的缺陷就是不能全局控制异常。每个类都要写一遍。
实现 HandlerExceptionResolver 接口
这种方式可以进行全局的异常控制。例如:
@Component
public class ExceptionTest implements HandlerExceptionResolver{ /**
* TODO 简单描述该方法的实现功能(可选).
* @see org.springframework.web.servlet.HandlerExceptionResolver#resolveException(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
*/
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
System.out.println("This is exception handler method!");
return null;
}
}
使用 @ControllerAdvice+ @ ExceptionHandler 注解
上文说到 @ ExceptionHandler 需要进行异常处理的方法必须与出错的方法在同一个Controller里面。那么当代码加入了 @ControllerAdvice,则不需要必须在同一个 controller 中了。这也是 Spring 3.2 带来的新特性。从名字上可以看出大体意思是控制器增强。 也就是说,@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉。
请确保此WebExceptionHandle 类能被扫描到并装载进 Spring 容器中。
@ControllerAdvice
@ResponseBody
public class WebExceptionHandle {
private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class);
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
logger.error("参数解析失败", e);
return ServiceResponseHandle.failed("could_not_read_json");
} /**
* 405 - Method Not Allowed
*/
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
logger.error("不支持当前请求方法", e);
return ServiceResponseHandle.failed("request_method_not_supported");
} /**
* 415 - Unsupported Media Type
*/
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) {
logger.error("不支持当前媒体类型", e);
return ServiceResponseHandle.failed("content_type_not_supported");
} /**
* 500 - Internal Server Error
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public ServiceResponse handleException(Exception e) {
if (e instanceof BusinessException){
return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
} logger.error("服务运行异常", e);
e.printStackTrace();
return ServiceResponseHandle.failed("server_error");
}
}
如果 @ExceptionHandler 注解中未声明要处理的异常类型,则默认为参数列表中的异常类型。所以还可以写成这样:
@ControllerAdvice
public class GlobalExceptionHandler { @ExceptionHandler()
@ResponseBody
String handleException(Exception e){
return "Exception Deal! " + e.getMessage();
}
}
参数对象就是 Controller 层抛出的异常对象!
继承 ResponseEntityExceptionHandler 类来实现针对 Rest 接口 的全局异常捕获,并且可以返回自定义格式:
@Slf4j
@ControllerAdvice
public class ExceptionHandlerBean extends ResponseEntityExceptionHandler { /**
* 数据找不到异常
* @param ex
* @param request
* @return
* @throws IOException
*/
@ExceptionHandler({DataNotFoundException.class})
public ResponseEntity<Object> handleDataNotFoundException(RuntimeException ex, WebRequest request) throws IOException {
return getResponseEntity(ex,request,ReturnStatusCode.DataNotFoundException);
} /**
* 根据各种异常构建 ResponseEntity 实体. 服务于以上各种异常
* @param ex
* @param request
* @param specificException
* @return
*/
private ResponseEntity<Object> getResponseEntity(RuntimeException ex, WebRequest request, ReturnStatusCode specificException) { ReturnTemplate returnTemplate = new ReturnTemplate();
returnTemplate.setStatusCode(specificException);
returnTemplate.setErrorMsg(ex.getMessage()); return handleExceptionInternal(ex, returnTemplate,
new HttpHeaders(), HttpStatus.OK, request);
} }
以上就是 Spring 处理程序统一异常的三种方式。
参考资料
@ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常
Spring MVC异常统一处理的三种方式的更多相关文章
- springmvc 异常统一处理的三种方式详解
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦 ...
- spring mvc配置datasource数据源的三种方式
2.使用org.apache.commons.dbcp.BasicDataSource 说明:这是一种推荐说明的数据源配置方式,它真正使用了连接池技术 <bean id="dataSo ...
- 【Java Web开发学习】Spring MVC异常统一处理
[Java Web开发学习]Spring MVC异常统一处理 文采有限,若有错误,欢迎留言指正. 转载:https://www.cnblogs.com/yangchongxing/p/9271900. ...
- spring mvc获取路径参数的几种方式 - 浅夏的个人空间 - 开源中国社区
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
- Spring MVC中forward请求转发2种方式(带参数)
Spring MVC中forward请求转发2种方式(带参数) http://www.51gjie.com/javaweb/956.html
- spring mvc 异常统一处理方式
springMVC提供的异常处理主要有两种方式: 一种是直接实现自己的HandlerExceptionResolver: 另一种是使用注解的方式实现一个专门用于处理异常的Controller——Exc ...
- Spring学习之实例化bean的三种方式
实例化bean的三种方式 构造器实例化bean Person.java public class Person { private String name; private Integer age; ...
- 【spring Boot】spring boot获取资源文件的三种方式【两种情况下】
首先声明一点,springboot获取资源文件,需要看是 1>从spring boot默认的application.properties资源文件中获取 2>还是从自定义的资源文件中获取 带 ...
- spring中创建bean对象的三种方式以及作用范围
时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...
随机推荐
- SQLite中的SELECT子句
SQLite中的SELECT子句 目前为止,最常见的SELECT语句由三个子句组成,分别为SELECT.FROM与WHERE.本小节我们首先讲解SELECT子句.SELECT子句可以用来定义最终结果表 ...
- 安卓工作室Android Studio 快捷键
安卓工作室Android Studio 快捷键 Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O ...
- BZOJ.3928.[CERC2014]Outer space invaders(区间DP)
BZOJ3928 双倍经验BZOJ4048 Codeforces GYM100543 L \(Description\) \(Solution\) 考虑出现时间在\([l,r]\)内的敌人,设最远的敌 ...
- 1207 ACM 汉诺塔II 数学
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1207 中文题目,在原来三个柱子的情况下(汉诺塔一),增加了一个柱子,难度也增加了. 思路: 思考时尽量和汉 ...
- php中对Mysql数据库的访问操作
一: PHP-MySQL 是 PHP 操作 MySQL 资料库最原始的 Extension ,PHP-MySQLi 的 i 代表 Improvement ,提更了相对进阶的功能,就 Extensio ...
- [原创]推荐一些在线API生成工具
[原创]推荐一些在线API生成工具 最近发现Api文档维护是个大体力活,版本控制文档统一化特别麻烦,寻思着这个怎么处理,经高人指点开源有一些工具不错,具体如下: 1.Swagger http:// ...
- What is a UINavigationTransitionView
**AFAIK UINavigationTransitionView is a class used to animate UINavigationController child views aro ...
- cocos2d-x 开发用到的工具
1.VertexHelper 可用于多边形顶点的计算,可视化定点编辑器,用它创建的顶点信息可以直接导出为Box2D可使用的代码 https://github.com/jfahrenkrug/Verte ...
- 浅谈压缩感知(二十一):压缩感知重构算法之正交匹配追踪(OMP)
主要内容: OMP的算法流程 OMP的MATLAB实现 一维信号的实验与结果 测量数M与重构成功概率关系的实验与结果 稀疏度K与重构成功概率关系的实验与结果 一.OMP的算法流程 二.OMP的MATL ...
- Android apk签名的两种方法
编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! 为了保证 ...