需求源自于任何一个业务的编写总会有各种各样的条件判断,需要时时手动抛出异常,又希望让接口返回友好的错误信息。

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 统一异常处理的更多相关文章

  1. Spring Boot统一异常处理实践

    摘要: SpringBoot异常处理. 原文:Spring MVC/Boot 统一异常处理最佳实践 作者:赵俊 前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 对于很多 ...

  2. Spring Boot☞ 统一异常处理

    效果区:  代码区: package com.wls.integrateplugs.exception.dto; public class ErrorInfo<T> { public st ...

  3. Spring Boot统一异常处理方案示例

    一.异常处理的原则 1.调用方法的时候返回布尔值来代替返回null,这样可以 NullPointerException.由于空指针是java异常里最恶心的异常. 2. catch块里别不写代码.空ca ...

  4. Spring MVC 统一异常处理

    Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...

  5. 编程小白入门分享三:Spring AOP统一异常处理

    Spring AOP统一异常处理 简介 在Controller层,Service层,可能会有很多的try catch代码块.这将会严重影响代码的可读性."美观性".怎样才可以把更多 ...

  6. Spring Boot全局异常处理

    本文为大家分享了Spring Boot全局异常处理,供大家参考,具体内容如下 1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dep ...

  7. Spring Boot 统一返回结果及异常处理

    在 Spring Boot 构建电商基础秒杀项目 (三) 通用的返回对象 & 异常处理 基础上优化.调整 一.通用类 1.1 通用的返回对象 public class CommonReturn ...

  8. spring boot 统一接口异常返回值

    创建业务 Exception 一般在实际项目中,推荐创建自己的 Exception 类型,这样在后期会更容易处理,也比较方便统一,否则,可能每个人都抛出自己喜欢的异常类型,而造成代码混乱 Servic ...

  9. 使用Spring MVC统一异常处理实战

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

随机推荐

  1. <算法图解>读书笔记:第3章 递归

    第3章 递归 3.1 递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一 ...

  2. Run Keyword And Ignore Error,Run Keyword And Return Status,Run Keyword And Continue On Failure,Run Keyword And Expect Error,Wait Until Keyword Succeeds用法

    *** Test Cases ***case1 #即使错误也继续执行,也不记录失败,且可以返回执行状态和错误信息 ${Run Keyword And Ignore Error status} ${st ...

  3. Windows linux子系统 使用说明

    1.安装 linux 子系统 2.应用商店安装ubuntu 3.为了方便可以配置成默认登陆root账户 Ubuntu config –default-user root   4. 安装完毕   5.安 ...

  4. Windows本地代码仓库使用连接教程

    目录 软件安装 修改语言为中文 克隆远程仓库 文件上传教程 软件安装 安装Git(软件下载链接) 根据自己的系统选择对应版本下载安装 安装TortoiseGit(软件下载链接) 1.下载完毕解压文件夹 ...

  5. mysql数据表增删改查

    http://www.runoob.com/mysql/mysql-tutorial.html 一.MySQL 创建数据表 创建MySQL数据表需要以下信息: 表名 表字段名 定义每个表字段 语法 以 ...

  6. 常用jq代码

    1. 只允许输入数字,且禁止输入法 <html> <head> <script type='text/javascript' src='../../js/jquery.m ...

  7. flagSet 使用

    var ( flagSet = flag.NewFlagSet("main", flag.ExitOnError) // 参数定义 version = flagSet.Bool(& ...

  8. Catalan 数列的性质及其应用(转载)

    转自:http://lanqi.org/skills/10939/ 卡特兰数 — 计数的映射方法的伟大胜利 发表于2015年11月8日由意琦行 卡特兰(Catalan)数来源于卡特兰解决凸$n+2$边 ...

  9. 获取subgrid中的数据并修改,含添加刷新列表的事件

    var isAddRefresh = false; function setLawsuitQueryResultText() { var queryResultIndex = 7; var gridC ...

  10. Java线程安全相关概