spring boot 统一异常处理
需求源自于任何一个业务的编写总会有各种各样的条件判断,需要时时手动抛出异常,又希望让接口返回友好的错误信息。
spring boot提供的帮助是自动将异常重定向到路由为/error的控制器
但是我们又希望手动抛出的异常与正常的数据返回为同一类型
所以我的解决方案由三个步骤组成:
1.一个异常枚举类 StatusCodeEnum.java
public enum StatusCodeEnum implements Serializable {
SUCCESS(0, "成功"),
ERROR(-1, "失败"),
USER_INVALID(60000, "无效用户"),
SYS_ARG_INVALID(11000, "无效参数"),
;
private static final long serialVersionUID = 1L;
private int code;
private String msg;
StatusCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
//根据code获取对应枚举
public static StatusCodeEnum getByCode(int code) {
StatusCodeEnum[] values = StatusCodeEnum.values();
for (StatusCodeEnum bizStatusCodeEnum : values) {
if (bizStatusCodeEnum.code == code) {
return bizStatusCodeEnum;
}
}
return null;
}
}
2.一个异常调用类 BaseException.java
因为抛出异常只能抛出字符串 所以这里使用了com.alibaba.fastjson.JSON包
public class BaseException {
private int code;
private String message;
public static void error(StatusCodeEnum statusCodeEnum) throws Exception
{
error(statusCodeEnum.getCode(),statusCodeEnum.getMsg());
}
public static void error(String message) throws Exception
{
error(-1,message);
}
public static void error(int code,String message) throws Exception
{
BaseException baseException = new BaseException();
baseException.setCode(code);
baseException.setMessage(message);
throw new Exception(JSON.toJSONString(baseException)) ;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "BaseException{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
}
3.异常处理控制器 ErrorController.java
@Controller
public class ErrorController extends AbstractErrorController{ @Autowired
ObjectMapper objectMapper; public ErrorController() {
super(new DefaultErrorAttributes());
} @Override
public String getErrorPath() {
return null;
} @RequestMapping("/error")
@ResponseBody
public BaseRs getErrorPath(HttpServletRequest request, HttpServletResponse response) { Map<String,Object> model = Collections.unmodifiableMap(getErrorAttributes(request,false)); //获取异常 可将异常打印到日志
Throwable cause = getCause(request);
int status = (Integer)model.get("status"); //自定义友好错误信息
String msg = (String)model.get("message"); JSONObject object = JSONObject.parseObject(msg);
int code = object.getInteger("code");
String message = object.getString("message"); return new BaseRs(code,message);
} protected Throwable getCause(HttpServletRequest request)
{
Throwable error = (Throwable)request.getAttribute("javax.servlet.error.exception");
if(null == error){
//MVC有可能会封装异常成ServletException ,需要调用getCause获取真正的异常
while (error instanceof ServletException && error.getCause() != null){
error = ((ServletException) error).getCause();
}
}
return error;
}
}
以上三个文件为异常处理的核心
其中的BaseRs类是统一数据返回
public class BaseRs<T> implements Serializable {
private int code;
private String message;
public BaseRs() {
}
/**
* 返回内容
*/
private T content;
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public T getContent() {
return content;
}
public BaseRs(int code, String message) {
this.code = code;
this.message = message;
}
public BaseRs(int code, String message, T content) {
this.code = code;
this.message = message;
this.content = content;
}
public BaseRs(StatusCodeEnum status) {
this.code = status.getCode();
this.message = status.getMsg();
}
public BaseRs(StatusCodeEnum status, T content) {
this.code = status.getCode();
this.message = status.getMsg();
this.content = content;
}
public static <V> BaseRs ok(V content) {
return new BaseRs(StatusCodeEnum.SUCCESS, content);
}
public static BaseRs ok() {
return new BaseRs(StatusCodeEnum.SUCCESS);
}
public static BaseRs error(StatusCodeEnum error) {
return new BaseRs(error);
}
public void setCode(StatusCodeEnum status) {
this.code = status.getCode();
}
public void setMessage(String message) {
this.message = message;
}
public void setContent(T content) {
this.content = content;
}
@Override
public String toString() {
return "BaseRs{" +
"code=" + code +
", message='" + message + '\'' +
", content=" + content +
'}';
}
public void setCode(int code) {
this.code = code;
}
}
最后的控制层代码以最简洁的方式调用即可:
@Controller
public class IndexController {
@RequestMapping("/a")
@ResponseBody
public BaseRs a() throws Exception{
boolean s = false;
if(!s){
BaseException.error(StatusCodeEnum.USER_INVALID);
}
return new BaseRs(StatusCodeEnum.SUCCESS);
}
}

本篇博客的码云地址: https://gitee.com/zhao-baolin/springboot_error
spring boot 统一异常处理的更多相关文章
- Spring Boot统一异常处理实践
摘要: SpringBoot异常处理. 原文:Spring MVC/Boot 统一异常处理最佳实践 作者:赵俊 前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 对于很多 ...
- Spring Boot☞ 统一异常处理
效果区: 代码区: package com.wls.integrateplugs.exception.dto; public class ErrorInfo<T> { public st ...
- Spring Boot统一异常处理方案示例
一.异常处理的原则 1.调用方法的时候返回布尔值来代替返回null,这样可以 NullPointerException.由于空指针是java异常里最恶心的异常. 2. catch块里别不写代码.空ca ...
- Spring MVC 统一异常处理
Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...
- 编程小白入门分享三:Spring AOP统一异常处理
Spring AOP统一异常处理 简介 在Controller层,Service层,可能会有很多的try catch代码块.这将会严重影响代码的可读性."美观性".怎样才可以把更多 ...
- Spring Boot全局异常处理
本文为大家分享了Spring Boot全局异常处理,供大家参考,具体内容如下 1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dep ...
- Spring Boot 统一返回结果及异常处理
在 Spring Boot 构建电商基础秒杀项目 (三) 通用的返回对象 & 异常处理 基础上优化.调整 一.通用类 1.1 通用的返回对象 public class CommonReturn ...
- spring boot 统一接口异常返回值
创建业务 Exception 一般在实际项目中,推荐创建自己的 Exception 类型,这样在后期会更容易处理,也比较方便统一,否则,可能每个人都抛出自己喜欢的异常类型,而造成代码混乱 Servic ...
- 使用Spring MVC统一异常处理实战
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
随机推荐
- CI 框架 隐藏index.php 入口文件 和 设置访问application下子目录
1.隐藏根目录下 index.php, 在根目录下创建 .htaccess文件 内容如下: <IfModule mod_rewrite.c> RewriteEngine on Rewrit ...
- 用JDBC把Excel中的数据导入到Mysql数据库中
步骤:0.在Mysql数据库中先建好table 1.从Excel表格读数据 2.用JDBC连接Mysql数据库 3.把读出的数据导入到Mysql数据库的相应表中 其中,步骤0的table我是先在Mys ...
- java用jsoup解析HTML
步骤 1获取document对象 //方法一 Document doc = Jsoup.connect(网址).get() //方法二 Document doc = Jsoup.parse(html字 ...
- 用OleDb导入Excel时提示驱动错误问题解决办法
导入格式为xls的excel文件,发生了错误 未处理System.Data.OleDb.OleDbException HResult=-2147467259 Message=外部数据库驱动程序 (1) ...
- Golang的模块管理Module
Golang 1.11版本终于支持了官方的模块依赖管理功能,1.11以前想要实现依赖管理只能够通过借助第三方库来实现,1.11以前的版本Golang项目必须依赖以GOPATH,从当前版本开始Golan ...
- CSS背景图片
1.背景图片插入 代码格式:background-image:url(): 括号内填写图片路径 2.背景图片设置大小 代码格式:background-size:宽.高 3.背景图片设置不平铺 代码格式 ...
- C语言复习4_while循环
1.while循环 循环三要素: 1).循环变量的初值 2).循环变量的判断 3).循环变量的更新 #include <stdio.h> #include <stdlib.h> ...
- unittest各个组件之间的关系
各个组件的含义: TestCase:测试用例,测试用例里面会有很多测试方法,是单元测试中最小维度的测试行为. TestSuite:测试套件,是测试用例的集合. TestFixure:测试固件,测试准备 ...
- ubuntu 16.04卸载不必要默认安装软件
两个办法,一个在ubuntu软件里一个一个删,明显的windows下做法. 还有一个通过终端来删除.ctrl+alt+t打开终端. 1.卸载libreoffices(要删一起删了,然后去装office ...
- C语言面试题分类->排序算法
1.选择排序. 每次将最小的数,与剩余数做比较.找到更小的,做交换. 时间复杂度:O(n²) 空间复杂度:O(1) 优缺点:耗时但内存空间使用小. void selectSort(int *p,int ...