SpringBoot 异常处理
异常处理最佳实践
根据我的工作经历来看,我主要遵循以下几点:
- 尽量不要在代码中写try...catch.finally把异常吃掉。
- 异常要尽量直观,防止被他人误解
- 将异常分为以下几类,业务异常,登录状态无效异常,(虽已登录,且状态有效)未授权异常,系统异常(JDK中定义Error和Exception,比如NullPointerException, ArithmeticException 和 InputMismatchException)
- 可以在某个特定的Controller中处理异常,也可以使用全局异常处理器。尽量使用全局异常处理器
使用@ControllerAdvice注释全局异常处理器
@ControllerAdvicepublic class GlobalExceptionHandler implements ApplicationContextAware {private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}@ExceptionHandlerpublic 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;}retu new ResponseEntity<>(response, httpStatus);} else {ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("detailMessage", response.getMessage());modelAndView.addObject("url", req.getRequestURL());modelAndView.setViewName("error");retu 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=HTML5spring.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 参考文档
异常处理
——致力于微软企业解决方案、项目管理及技术培训
来源链接:https://www.cnblogs.com/fuhongwei041/p/7597531.html
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。