异常处理最佳实践

根据我的工作经历来看,我主要遵循以下几点:

  1. 尽量不要在代码中写try...catch.finally把异常吃掉。
  2. 异常要尽量直观,防止被他人误解
  3. 将异常分为以下几类,业务异常,登录状态无效异常,(虽已登录,且状态有效)未授权异常,系统异常(JDK中定义Error和Exception,比如NullPointerException, ArithmeticException 和 InputMismatchException)
  4. 可以在某个特定的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;
}
}
}
  1. 使用@ControllerAdvice生命该类中的@ExceptionHandler作用于全局
  2. 使用@ExceptionHandler注册异常处理器,可以注册多个,但是不能重复,比如注册两个方法都用于处理Exception是不行的。
  3. 使用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 ##############################

参考文档

themyleaf 参考文档

异常处理

SpringBoot 异常处理的更多相关文章

  1. SpringBoot异常处理统一封装我来做-使用篇

    SpringBoot异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单个 ...

  2. Springboot异常处理和自定义错误页面

    1.异常来源 要处理程序发生的异常,首先需要知道异常来自哪里? 1.前端错误的的请求路径,会使得程序发生4xx错误,最常见的就是404,Springboot默认当发生这种错误的请求路径,pc端响应的页 ...

  3. SpringBoot异常处理(二)

    参数校验机制 JSR-303 Hibernate 参数接收方式: URL路径中的参数 {id} (@PathVariable(name="id") int-whatever) UR ...

  4. 【使用篇二】SpringBoot异常处理(9)

    异常的处理方式有多种: 自定义错误页面 @ExceptionHandler注解 @ControllerAdvice+@ExceptionHandler注解 配置SimpleMappingExcepti ...

  5. springBoot异常处理

    1.status=404 Whitelabel Error Page Whitelabel Error Page This application has no explicit mapping fo ...

  6. SpringBoot学习15:springboot异常处理方式5(通过实现HandlerExceptionResolver类)

    修改异常处理方式4中的全局异常处理controller package com.bjsxt.exception; import org.springframework.context.annotati ...

  7. SpringBoot学习14:springboot异常处理方式4(使用SimpleMappingExceptionResolver处理异常)

    修改异常处理方法3中的全局异常处理Controller即可 package bjsxt.exception; import org.springframework.context.annotation ...

  8. SpringBoot学习13:springboot异常处理方式3(使用@ControllerAdvice+@ExceptionHandle注解)

    问题:使用@ExceptionHandle注解需要在每一个controller代码里面都添加异常处理,会咋成代码冗余 解决方法:新建一个全局异常处理类,添加@ControllerAdvice注解即可 ...

  9. SpringBoot学习12:springboot异常处理方式2(使用@ExceptionHandle注解)

    1.编写controller package com.bjsxt.controller; import org.springframework.stereotype.Controller; impor ...

随机推荐

  1. Android学习笔记----Java中的字符串比较

    用习惯了C#.C++,在做字符串比较时想当然地使用如下语句: string str1 = "abcd", str2 = "abcd"; if(str1==str ...

  2. 【转】Maya Mel – Search String in String

    转自:http://schiho.com/?p=179 Hi, this is a little script which returns a 0 or 1 if the searched text ...

  3. tomcat 取消项目名访问路径

    在server.xml  里,<host>...</host>的标签之间添加<Context path="" docBase="projec ...

  4. C++ UTF8 UrlEncode(宽字符)

    为了支持C++ UrlEncode之后的字符串能够被C#所识别(windows phone 下C#只能支持UTF8与 Unicode). 所谓的 UTF8 UrlEncode 也只是宽字符串 UrlE ...

  5. Python:GUI之tkinter学习笔记之messagebox、filedialog

    相关内容: messagebox 介绍 使用 filedialog 介绍 使用 首发时间:2018-03-04 22:18 messagebox: 介绍:messagebox是tkinter中的消息框 ...

  6. OneAPM大讲堂 | 基于图像质量分析的摄像头监控系统的实现

    今天咱们要介绍的技术很简单,请看场景: 你在家里安装了几个摄像头想监视你家喵星人的一举一动,然而,就在喵星人准备对你的新包发动攻击的时候,图像突然模糊了.毕竟图像模糊了以后你就没法截图回家和喵当面对质 ...

  7. HTML5文件API之FileReader

    在文件上传之前,我们总想预览一下文件内容,或图片样子,html5 中FileReader正好提供了2种方法,可以在不上传文件的情况下,预览文件内容. 图片预览:readAsDataURL(file); ...

  8. python第三十五天-----作业完成--学校选课系统

    选课系统:角色:学校.学员.课程.讲师要求:1. 创建北京.上海 2 所学校2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开3. 课程包含, ...

  9. gitlab 和 github 配置 SSH Keys

    gitlab 文档上给了很好的配置的例子:https://gitlab.com/help/ssh/README#locating-an-existing-ssh-key-pair 针对mac 下的使用 ...

  10. xshell 5连接NAT模式的虚拟机

    这里简称真实的外部电脑为主机.当虚拟机NAT模式上网时(区别于桥接上网,桥接上网的话,主机和虚拟机可以互访),虚拟机是可以访问主机的,但是由于NAT机制,导致主机不能访问虚拟机,那么如何让主机上的xs ...