查看原文
其他

玩转springboot2.x之统一异常处理篇

桌前明月 Java学习之道 2022-08-24

点击上方"Java学习之道",选择"关注"公众号

优秀文章,第一时间收到!

文章已获得原作者授权,原文地址:

https://zhuoqianmingyue.blog.csdn.net/article/details/83243900


0、序言

0.0、demo版本说明

软件版本
开发工具Spring Tool Suite (STS)
jdk版本1.8.0_144
springboot版本2.0.5.RELEASE


0.1、场景介绍

我们在开发中必须要做的一个操作,那就是异常处理,今天主要就是讲解一下为项目设置统一异常处理如何操作。


1、@ControllerAdvice 和 @ExceptionHandler 注解介绍

我们可以通过@ControllerAdvice (控制增强)+ @ExceptionHandler 进行统一异常处理,ExceptionHandler注解可以设置全局处理控制里的异常类型来拦截要处理的异常。 例如:@ExceptionHandler(value = Exception.class)


2、成功和异常数据消息处理

2.1 消息类定义
定义restfull 返回json 数据的消息类,其中包含

  • code:错误码,0表示没有异常信息。

  • message:异常提示信息

  • date:无异常返回具体内容。

/**
 * restfull 请求返回json 信息实体类
 * @author lijunkui
 * @param <T>
 */

public class ReturnMessage<T> {

    private Integer code;//错误码
    private String message;//提示信息
    private T date;//返回具体内容
    public ReturnMessage(Integer code, String message, T date) {
        super();
        this.code = code;
        this.message = message;
        this.date = date;
    }
    //省略get and set方法

}

2.2 消息类处理工具类
主要是用来处理成功 失败消息处理

该工具类主要包含是3个方法 :

  • 1、成功处理含实体数据

  • 2、成功处理,但没有实体数据

  • 3、失败处理

package cn.lijunkui.unifiedException.message;
/**
 * json 消息处理工具类
 * @author Administrator
 *
 */

public class ReturnMessageUtil {
    /**
     * 无异常 请求成功并有具体内容返回
     * @param object
     * @return
     */

    public static ReturnMessage<Object> sucess(Object object) {
        ReturnMessage<Object> message = new ReturnMessage<Object>(0,"sucess",object);
        return message;
    }
    /**
     * 无异常 请求成功并无具体内容返回
     * @return
     */

    public static ReturnMessage<Object> sucess() {
        ReturnMessage<Object> message = new ReturnMessage<Object>(0,"sucess",null);
        return message;
    }
    /**
     * 有自定义错误异常信息
     * @param code
     * @param msg
     * @return
     */

    public static ReturnMessage<Object> error(Integer code,String msg) {
        ReturnMessage<Object> message = new ReturnMessage<Object>(code,msg,null);
        return message;
    }
}

2.3 自定义异常
用于已知的数据校验和异常处理。

我们通过自定以系统异常来处理失败的异常信息。通过继承RuntimeException 然后在声明code 用来定义不同类型自定义异常。主要是用于异常拦截出获取code 并将code 设置到消息类中。

package cn.lijunkui.unifiedException.customexception;
public class SbException extends RuntimeException{


    private static final long serialVersionUID = -8201518085425482189L;

    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    private Integer code;

    public SbException(Integer code,String message) {
        super(message);
        this.code = code;
    }

}


3、异常拦截统统一处理逻辑处理

我们通过声明@RestControllerAdvice 来声明该类为 restful 风格处理异常信息;

在handle方法声明@ExceptionHandler 并在该注解中指定要拦截的异常类。

package cn.lijunkui.unifiedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import cn.lijunkui.unifiedException.customexception.SbException;
import cn.lijunkui.unifiedException.message.ReturnMessage;
import cn.lijunkui.unifiedException.message.ReturnMessageUtil;



//@ControllerAdvice
@RestControllerAdvice
public class ExceptionHandle {
    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
    @ExceptionHandler(value = Exception.class)
    //@ResponseBody
    public ReturnMessage<Object> handle(Exception exception) {
        if(exception instanceof SbException) {
            SbException sbexception = (SbException)exception;
            return ReturnMessageUtil.error(sbexception.getCode(), sbexception.getMessage());
        }else {
            logger.error("系统异常 {}",exception);
            return ReturnMessageUtil.error(-1"未知异常"+exception.getMessage());
        }
    }
}


4、统一异常处理测试

进行测试 分别测试自定义异常和系统异常。

  • 我们通过customException测试自定义异常

  • 通过unknownException测试未知的系统异常

package cn.lijunkui.unifiedException.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.lijunkui.unifiedException.customexception.SbException;

@RestController
@RequestMapping("/error")
public class DemoException {

    @GetMapping(value = "custome")
    public void customException() {
        SbException sbe = new SbException(100"这个是自定义异常!");
        throw sbe;
    }
    @GetMapping(value = "unknown")
    public void unknownException() {
        int i = 0;
        int b = 1/i;
    }
}

测试结果:



项目源码地址:

    https://github.com/zhuoqianmingyue/springbootexamples


往期回顾:

玩转springboot2.x之异步调用@Async

●玩转springboot2.x之整合邮件发送篇

●玩转springboot2.x之使用JSP篇

玩转springboot2.x之整合mybatis篇

●玩转springboot2.x之自定义Filter过滤器篇

●玩转springboot2.x之使用SpringDateJpa篇

玩转springboot2.x之搭建Actuator和spring boot admin监控篇

玩转springboot2.x之整合webSocket篇

●玩转springboot2.x之整合swagger篇

玩转SpringBoot2.x之定时任务详解

玩转springboot2.x之整合JWT篇

玩转springboot2.x之整合freemarker

玩转springboot2.x之IntellJ IDEA快速搭建

玩转springboot2.x之restful api开发篇

●你真的会高效的在GitHub搜索开源项目吗?


-END-

    喜欢本文的朋友们,欢迎扫码关注订阅号Java学习之道,收看更多精彩内容!


    一 起努力吧!

你也可以顺手点个在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存