异常处理最佳实践

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

  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. VUE路由转场特效,WebAPP的前进与后退

    一.效果图 二.思路 1. 定义两个 CSS 过度动画,前进与后退: slide-right-enter   和   slide-left-enter 2. 给路由配置meta信息,设置各个路由的级别 ...

  2. eclipse没有server选项解决方法

    eclipse是是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境. 它使用频率十分高,然而当使用它配置weblogic的时候,经常 ...

  3. Apktool(1)——Apktool的安装

    Apktool是google提供的apk的编译工具,有了它就可以做很多事情.比如获取apk的源码,apk汉化,对手机rom包做一些美化. 首先来看看apktool的安装(配置): 以下内容主要翻译字A ...

  4. MongoDB的基本操作:服务端启动,客户端连接,CRUD操作

    本文内容: MongoDB的介绍 MongoDB服务端的启动 MongoDB客户端连接 SQL与MongoDB相关概念解释 什么是BSON 数据库操作 集合操作 文档操作 测试环境:win10 软件版 ...

  5. WCF服务端开发和客户端引用小结

    1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...

  6. MySQL 并行复制演进及 MySQL 8.0 中基于 WriteSet 的优化

    MySQL 8.0 可以说是MySQL发展历史上里程碑式的一个版本,包括了多个重大更新,目前 Generally Available 版本已经已经发布,正式版本即将发布,在此将介绍8.0版本中引入的一 ...

  7. 【PAT】B1033 旧键盘打字(20 分)

    #include<stdio.h> #include<algorithm> #include<ctype.h> using namespace std; bool ...

  8. Windows和Mac浏览器启动本地程序

    前言 这几天有个需求,需要在IE上启动本地程序,就如下面一样. 一开始,我还以为IE有提供特殊的接口,类似上图中的“RunExe”,可以找了大半天觉得不对经(找不到该方法). 后来想想不对,这种方式是 ...

  9. Web服务器的反向代理nginx

    nginx作为web服务器一个重要的功能就是反向代理. Nginx配置详解   序言 Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭 ...

  10. 计算机基础-BIOS

    BIOS--硬件和软件的纽带(Basic Input Output System) 1.含义:基本的输入输出系统,它是一组固化到计算机内主板上的一个ROM存储芯片上的程序 2.性质:它保存着计算机最重 ...