SpringBoot 异常处理
异常处理最佳实践
根据我的工作经历来看,我主要遵循以下几点:
- 尽量不要在代码中写try...catch.finally把异常吃掉。
- 异常要尽量直观,防止被他人误解
- 将异常分为以下几类,业务异常,登录状态无效异常,(虽已登录,且状态有效)未授权异常,系统异常(JDK中定义Error和Exception,比如NullPointerException, ArithmeticException 和 InputMismatchException)
- 可以在某个特定的Controller中处理异常,也可以使用全局异常处理器。尽量使用全局异常处理器
使用@ControllerAdvice注释全局异常处理器
@ControllerAdvice
public class GlobalExceptionHandler implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@ExceptionHandler
public Object businessExceptionHandler(Exception exception, HttpServletRequest req) {
DtoResult response = new DtoResult();
if (exception instanceof BusinessException) {
int code = ((BusinessException) exception).getErrorCode();
response.setCode(code > 0 ? code : DtoResult.STATUS_CODE_BUSINESS_ERROR);
response.setMessage(exception.getMessage());
} else if (exception instanceof NotAuthorizedException) {
response.setCode(DtoResult.STATUS_CODE_NOT_AUTHORIZED);
response.setMessage(exception.getMessage());
} else {
response.setCode(DtoResult.STATUS_CODE_SYSTEM_ERROR);
String profile = applicationContext.getEnvironment().getProperty("spring.profiles.active");
if (profile != GlobalConst.PROFILE_PRD) {
response.setMessage(exception.toString());
} else {
response.setMessage("系统异常");
}
logger.error("「系统异常」", exception);
}
String contentTypeHeader = req.getHeader("Content-Type");
String acceptHeader = req.getHeader("Accept");
String xRequestedWith = req.getHeader("X-Requested-With");
if ((contentTypeHeader != null && contentTypeHeader.contains("application/json"))
|| (acceptHeader != null && acceptHeader.contains("application/json"))
|| "XMLHttpRequest".equalsIgnoreCase(xRequestedWith)) {
HttpStatus httpStatus = HttpStatus.OK;
if (response.getCode() == DtoResult.STATUS_CODE_SYSTEM_ERROR) {
httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
}
return new ResponseEntity<>(response, httpStatus);
} else {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("detailMessage", response.getMessage());
modelAndView.addObject("url", req.getRequestURL());
modelAndView.setViewName("error");
return modelAndView;
}
}
}
- 使用@ControllerAdvice生命该类中的@ExceptionHandler作用于全局
- 使用@ExceptionHandler注册异常处理器,可以注册多个,但是不能重复,比如注册两个方法都用于处理Exception是不行的。
- 使用HttpServletRequest中的header检测请求是否为ajax, 如果是ajax则返回json(即ResponseEnttiy<>), 如果为非ajax则返回view(即ModelAndView)
thymeleaf模板标签解析错误
themyleaf默认使用HTML5模式,此模式比较严格,比如当标签没有正常闭合,属性书写不正确时都会报错,比如以下格式
# meta标签没有闭合
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>程序出错了 - 智联</title>
</head>
<body>
<p>程序出错了...</p>
<p>请求地址:<span th:text="${url}"></span></p>
<p>详情:<span th:text="${detailMessage}"></span></p>
</body>
</html>
# 属性v-cloak不符合格式
<div v-cloak></div>
解决方法
可以在配置文件中增加 spring.thymeleaf.mode=LEGACYHTML5 配置项,默认情况下是 spring.thymeleaf.mode=HTML5,
LEGACYHTML5 需要搭配第三方库 nekohtml 才可以使用。
# 1.在 pom.xml 中增加如下内容:
<!-- https://mvnrepository.com/artifact/net.sourceforge.nekohtml/nekohtml -->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
# 2.修改 application.properties 为:
############################## thymeleaf ##############################
spring.thymeleaf.cache=false
# spring.thymeleaf.mode=HTML5
spring.thymeleaf.mode=LEGACYHTML5
############################## thymeleaf ##############################
参考文档
- SpringBoot系列学习十:统一异常处理
- @ExceptionHandler for Ajax and non-Ajax
- Spring MVC
- Spring MVC @ExceptionHandler Example
- Spring Boot中Web应用的统一异常处理
- Spring MVC View Resolver
- Exception Handling in Spring MVC
- Spring: RESTful controllers and error handling
themyleaf 参考文档
异常处理
SpringBoot 异常处理的更多相关文章
- SpringBoot异常处理统一封装我来做-使用篇
SpringBoot异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单个 ...
- Springboot异常处理和自定义错误页面
1.异常来源 要处理程序发生的异常,首先需要知道异常来自哪里? 1.前端错误的的请求路径,会使得程序发生4xx错误,最常见的就是404,Springboot默认当发生这种错误的请求路径,pc端响应的页 ...
- SpringBoot异常处理(二)
参数校验机制 JSR-303 Hibernate 参数接收方式: URL路径中的参数 {id} (@PathVariable(name="id") int-whatever) UR ...
- 【使用篇二】SpringBoot异常处理(9)
异常的处理方式有多种: 自定义错误页面 @ExceptionHandler注解 @ControllerAdvice+@ExceptionHandler注解 配置SimpleMappingExcepti ...
- springBoot异常处理
1.status=404 Whitelabel Error Page Whitelabel Error Page This application has no explicit mapping fo ...
- SpringBoot学习15:springboot异常处理方式5(通过实现HandlerExceptionResolver类)
修改异常处理方式4中的全局异常处理controller package com.bjsxt.exception; import org.springframework.context.annotati ...
- SpringBoot学习14:springboot异常处理方式4(使用SimpleMappingExceptionResolver处理异常)
修改异常处理方法3中的全局异常处理Controller即可 package bjsxt.exception; import org.springframework.context.annotation ...
- SpringBoot学习13:springboot异常处理方式3(使用@ControllerAdvice+@ExceptionHandle注解)
问题:使用@ExceptionHandle注解需要在每一个controller代码里面都添加异常处理,会咋成代码冗余 解决方法:新建一个全局异常处理类,添加@ControllerAdvice注解即可 ...
- SpringBoot学习12:springboot异常处理方式2(使用@ExceptionHandle注解)
1.编写controller package com.bjsxt.controller; import org.springframework.stereotype.Controller; impor ...
随机推荐
- 6个顶级Python NLP库的比较!
6个顶级Python NLP库的比较! http://blog.itpub.net/31509949/viewspace-2212320/ 自然语言处理(NLP)如今越来越流行,在深度学习开发的背景下 ...
- PL/SQL Developer使用小技巧
1.PL/SQL Developer记住登陆密码 在使用PL/SQL Developer时,为了工作方便希望PL/SQL Developer记住登录Oracle的用户名和密码: ...
- Android View体系(八)从源码解析View的layout和draw流程
前言 上一篇文章我们讲了View的measure的流程,接下来我们讲下View的layout和draw流程,如果你理解了View的measure的流程,那这篇文章自然就不在话下了. 1.View的la ...
- Kotlin入门(17)等式判断的情况
话说等式可是编程语言最基本的表达式之一,不管哪种高级语言,无一例外都采用双等号“==”判断两个变量是否相等:就算是复杂的对象,在Java中也可通过equals函数判断两个实例是否相等.按理说这些能够满 ...
- Azure 标准与高级托管磁盘存储的相互转换
托管磁盘提供两种存储选项:高级(基于 SSD)和标准(基于 HDD). 它允许基于性能需求在这两个选项之间轻松切换,并保障最短停机时间. 非托管磁盘不具备此功能. 但可以轻松转换为托管磁盘,以便在这两 ...
- 洗礼灵魂,修炼python(34)--面向对象编程(4)—继承
前面已经说到面向对象编程有封装,继承,多态三大特性,那么其中的继承则很重要,可以直接单独的拿出来解析 继承 1.什么是继承: 字面意是子女继承父母的家产或者特性等.而在编程里继承是指子类继承父类(基类 ...
- HCNA网络技术命令
1.display version 显示系统软件版本及硬件信息 2.system-view 切换到系统视图 3.quit 切换回用户视图 4.return 从任意非用户视图退回到用户视图 5.sysn ...
- 传智播客张孝祥java邮件开发随笔01
01_传智播客张孝祥java邮件开发_课程价值与目标介绍 02_传智播客张孝祥java邮件开发_邮件方面的基本常识 03_传智播客张孝祥java邮件开发_手工体验smtp和pop3协议 第3课时 关于 ...
- Flask应用错误处理
目录 Flask 应用错误处理 错误日志工具 错误处理 注册 处理 日志 排除应用错误 有疑问时,请手动运行 使用调试器 参考 Flask 应用错误处理 应用出错,服务器出错.或早或晚,你会遇到产品出 ...
- java死锁示例及其发现方法
在java多线程编程中很容易出现死锁,死锁就是多个线程相互之间永久性的等待对方释放锁,这和数据库多个会话之间的死锁类似.下面的代码示例了一个最简单的死锁的例子,线程1和线程2相互之间等待对方释放锁来取 ...