【spring boot】捕获全局异常@RestControllerAdvice

摘要:
I Origin场景:Java验证用于输入参数验证,但这种类型的输入参数验证在进入控制器之前无法通过现场验证,因此直接将异常信息返回到前端。前端异常提醒类似于以下不友好的后端接口错误提示信息:2.解决方案1.要解决上述问题,您需要捕获并处理异常,Springboot提供@RestControllerAdvice来完成全局异常捕获和处理。2.具体实施2.1定义请求输入
一.由来

场景:  使用 Java的validation做入参的校验  ,但是这种入参校验在还没有进入controller就会字段校验不通过,从而直接返回异常信息给前端,

    前端的异常提醒, 类似于下面这种 很不友好的 

【spring boot】捕获全局异常@RestControllerAdvice第1张

后端接口报错提示信息:

 【spring boot】捕获全局异常@RestControllerAdvice第2张

二.解决方法

1.解决如上问题,需要对异常做捕获处理,Spring boot 提供了@RestControllerAdvice 可以完成 全局异常捕获处理

2.具体实现

【spring boot】捕获全局异常@RestControllerAdvice第3张

 

2.1  定义请求入参GlobalParams

【比如,使用Java的validation做入参的校验 这种场景】

【spring boot】捕获全局异常@RestControllerAdvice第4张【spring boot】捕获全局异常@RestControllerAdvice第5张
package com.sxd.swapping.globalException.param;

import lombok.Data;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;


/**
 * 使用 Java的validation做入参的校验
 * 测试一下全局异常怎么捕获这种入参类型的校验(因为此处入参校验未通过,压根就不会进Controller)
 */
@Data
public class GlobalParams {

    @NotNull(message = "ID不能为空")
    private Long id;

    @NotEmpty(message = "集合不能为空")
    private List<String>  myStrList;



}
View Code

2.2 定义请求响应GlobalResult 

【可一定要getter/setter方法】

【spring boot】捕获全局异常@RestControllerAdvice第6张【spring boot】捕获全局异常@RestControllerAdvice第7张
package com.sxd.swapping.globalException.result;

import lombok.Data;

/**
 * 自定义一个 统一响应体
 */
@Data
public class GlobalResult {

    public static final String SUCCESS_CODE = "0000";

    public static final String ERROR_CODE = "9999";

    /**
     * 状态码
     */
    private String code;

    /**
     * 状态码描述
     */
    private String message;

    /**
     * 响应结果
     */
    private Object data;

    private GlobalResult(String code, String message) {
        this(code, message, null);
    }

    private GlobalResult(String code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }


    public static GlobalResult build(String code, String message) {
        return new GlobalResult(code, message);
    }

    public static GlobalResult build(String code, String message, Object data) {
        return new GlobalResult(code, message, data);
    }

    public static GlobalResult success() {
        return build(SUCCESS_CODE, "处理成功");
    }

    public static GlobalResult success(String code, String message) {
        return build(code, message);
    }

    public static GlobalResult success(Object data) {
        return build(SUCCESS_CODE, "处理成功", data);
    }

    public static GlobalResult error() {
        return build(ERROR_CODE, "处理失败");
    }

    public static GlobalResult error(String message) {
        return error(ERROR_CODE, message);
    }

    public static GlobalResult error(String code, String message) {
        return build(code, message);
    }
}
View Code

2.3 定义全局异常捕获GlobalAdvice

【可捕获一种特定异常,也可捕获多种异常,依顺序从上往下】

【spring boot】捕获全局异常@RestControllerAdvice第8张【spring boot】捕获全局异常@RestControllerAdvice第9张
package com.sxd.swapping.globalException.advice;

import com.sxd.swapping.globalException.result.GlobalResult;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 全局异常捕获
 *@RestControllerAdvice都是对Controller进行增强的,可以全局捕获spring mvc抛的异常。
 *
 * ExceptionHandler 可以全局仅捕获一种异常,也可以全局捕获多种异常,从上到下 依次处理
 *
 */
@RestControllerAdvice
public class GlobalAdvice {


    /**
     * ExceptionHandler的作用是用来捕获指定的异常
     * 这里示例 捕获 Java的validation做入参的校验 的校验失败的异常
     * 统一处理,免得返回前端
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public GlobalResult handleStoreAuthException(MethodArgumentNotValidException e) {
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        StringBuilder detailMsg = new StringBuilder();
        if (CollectionUtils.isNotEmpty(allErrors)) {
            allErrors.stream().forEach(i -> detailMsg.append(i.getDefaultMessage()).append(";"));
        }
        return GlobalResult.build(GlobalResult.ERROR_CODE, detailMsg.toString());
    }


    /**
     * ExceptionHandler的作用是用来捕获指定的异常
     * 这里示例 捕获 Exception异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public GlobalResult handleStoreAuthException(Exception e) {
        return GlobalResult.build(GlobalResult.ERROR_CODE, e.getMessage());
    }
}
View Code

2.4 定义接口GlobalExceptionController

【spring boot】捕获全局异常@RestControllerAdvice第10张【spring boot】捕获全局异常@RestControllerAdvice第11张
package com.sxd.swapping.globalException.controller;

import com.sxd.swapping.globalException.param.GlobalParams;
import com.sxd.swapping.globalException.result.GlobalResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;


@Slf4j
@Controller
@RequestMapping("/myglobal/exception")
public class GlobalExceptionController {


    @ResponseBody
    @PostMapping(value = "/test")
    public GlobalResult myTest(@Valid @RequestBody GlobalParams params){

        Long id = params.getId();
        id = id / 0;
        log.info("业务处理!!!");
        return GlobalResult.success();
    }


}
View Code
三.验证结果

【spring boot】捕获全局异常@RestControllerAdvice第12张

 

前端控件也可返回友好的异常提醒

【spring boot】捕获全局异常@RestControllerAdvice第13张

 

免责声明:文章转载自《【spring boot】捕获全局异常@RestControllerAdvice》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Thinkpad T61 on screen display 设置Oracle 与 ODAC 一起安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#-微信公众平台接口-上传临时素材

最烦做微信公众平台的东西。。文档说得不清不楚,又没示例代码,只能自己 慢慢搜索,弄了一晚上,基本弄出来了,把本地的图片上传到微信的临时素材那里,返回媒体ID,用于其他操作,代码如下 :(自己导入相应的类System.Net.Http,JSON解析用的LitJson)         /// <summary>        /// 上传临时素材...

WinForm 自动完成控件

在Web的应用方面有js的插件实现自动完成(或叫智能提示)功能,但在WinForm窗体应用方面就没那么好了。 TextBox控件本身是提供了一个自动提示功能,只要用上这三个属性: AutoCompleteCustomSource:AutoCompleteSource 属性设置为CustomSource 时要使用的 StringCollection。 Aut...

通过url 下载文件

1、问题简介   通过文件的url,将文件下载到本地。文件存储的位置为:tomcat服务器的文件夹(通过读取properties文件:可看:http://www.cnblogs.com/0201zcr/p/4700418.html) 2、实现思路   读取properties文件,将获得文件将要存储的位置   通过java的Url类,将网上的文件下载到本地...

微信APP支付(Java后台生成签名具体步骤)

public class PayCommonUtil { //定义签名,微信根据参数字段的ASCII码值进行排序 加密签名,故使用SortMap进行参数排序public static String createSign(String characterEncoding,SortedMap<String,String> parameter...

word的常用操作

using System;using System.Collections.Generic;using System.Text;using Microsoft.Office.Interop.Word;using System.IO;using System.Web;using System.Data;using System.Reflection;usin...

数据词典与ABAP类型映射

数据词典与ABAP类型映射 这些不能够直接在ABAP程序中使用,但可以使用对它们进行包装后的Data element来间接使用,在程序中使用数据字典类型时,将转化为相应的ABAP内置类型。 Type 允许最大长度m Meaning ABAP Type ACCP 6 Accounting period n(6) CHAR 1-255 Char...