正常来说一个系统肯定有很多业务异常。而这些业务异常的信息如何返回给前台呈现给用户。比如用户的某些操作不被允许,需要给用户提示。

Spring 提供了@ControllerAdvice这个注解,这个注解可以实现全局异常处理,全局数据绑定,全局数据预处理,这里主要说下使用这个注解实现全局异常处理。

1.定义我们自己的业务异常ErrorCodeException

package com.nijunyang.exception.exception;

/**
* Description:
* Created by nijunyang on 2019/12/20 9:36
*/
public class ErrorCodeException extends RuntimeException { private int code;
/**
* 用于填充资源文件中占位符
*/
private Object[] args; public ErrorCodeException(int code, Object... args) {
this.code = code;
this.args = args;
} public int getCode() {
return code;
} public Object[] getArgs() {
return args;
} }

2.编写统一异常处理器RestExceptionHandler,使用@ControllerAdvice注解修饰,在异常处理器编写针对某个异常的处理方法,使用@ExceptionHandler注解指向某个指定异常。当代码中抛了该异常就会进入此方法执行,从而返回我们处理后的信息给请求者。

3.资源文件放置提示信息,根据错误码去匹配提示信息。

package com.nijunyang.exception.handler;

import com.nijunyang.exception.exception.ErrorCodeException;
import com.nijunyang.exception.model.RestErrorResponse;
import com.nijunyang.exception.model.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Locale; /**
* Description: 控制层统一异常处理
* Created by nijunyang on 2019/12/20 9:33
*/
@ControllerAdvice
public class RestExceptionHandler { @Autowired
private MessageSource messageSource; //locale可以处理国际化资源文件,不同的语言
@ExceptionHandler(value = ErrorCodeException.class)
public final ResponseEntity<RestErrorResponse> handleBadRequestException(ErrorCodeException errorCodeException, Locale locale) {
String message = messageSource.getMessage(String.valueOf(errorCodeException.getCode()), errorCodeException.getArgs(), locale);
RestErrorResponse restErrorResponse = new RestErrorResponse(Status.FAILED, errorCodeException.getCode(), message);
return new ResponseEntity<>(restErrorResponse, HttpStatus.OK);
}
}

4.配置文件指向资源文件位置(spring.messages.basename=xxx)

spring.messages.basename指向资源的前缀名字就行了,后面的国家语言标志不需要,Locale会根据系统的语言去识别,资源文件需要配置一个默认的(messages.properties),不然启动的时候可能无法正常注入资源,因为默认的是去加载不带国家语言标志的文件。

当然前缀随便配置什么都可以 只要再springboot的配置文件spring.messages.basename的路径配置正确就行,就像这样子也是可以的

5.控制层模拟异常抛出:

package com.nijunyang.exception.controller;

import com.nijunyang.exception.exception.ErrorCodeException;
import com.nijunyang.exception.model.ErrorCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* Description:
* Created by nijunyang on 2019/12/20 9:58
*/
@RestController
@RequestMapping("/error")
public class Controller { @GetMapping("/file")
public ResponseEntity test() {
//模拟文件不存在
String path = "a/b/c/d.txt";
throw new ErrorCodeException(ErrorCode.FILE_DOES_NOT_EXIST_51001, path);
}
}

6.前台调用结果

z/b/c/d.txt就去填充了资源文件中的占位符

错误码:

package com.nijunyang.exception.model;

/**
* Description:
* Created by nijunyang on 2020/1/20 20:28
*/
public final class ErrorCode {
public static int FILE_DOES_NOT_EXIST_51001 = 51001;
}

结果状态:

package com.nijunyang.exception.model;

/**
* Description:
* Created by nijunyang on 2019/12/20 10:21
*/
public enum Status {
SUCCESS,
FAILED
}

异常统一结果返回对象

package com.nijunyang.exception.model;

/**
* Description:
* Created by nijunyang on 2019/12/20 9:38
*/
public class RestErrorResponse { private Status status;
/**
* 错误码
*/
private Integer errorCode;
/**
* 错误信息
*/
private String errorMsg; public RestErrorResponse(Status status, Integer errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
this.status = status;
} public Integer getErrorCode() {
return errorCode;
} public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
} public String getErrorMsg() {
return errorMsg;
} public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
} public Status getStatus() {
return status;
} }

pom文件依赖:springBoot版本是2.1.7.RELEASE

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
</dependencies>

完整代码:https://github.com/bluedarkni/study.git  ---->springboot--->exception项目

@ControllerAdvice自定义异常统一处理的更多相关文章

  1. springBoot2.0 配置@ControllerAdvice 捕获异常统一处理

    一.前言 基于上一篇 springBoot2.0 配置shiro实现权限管理 这一篇配置 异常统一处理 二.新建文件夹:common,param 三.返回结果集对象 1.ResultData.java ...

  2. C#自定义异常 统一异常处理

    异常类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...

  3. 统一异常处理@ControllerAdvice

    一.异常处理 有异常就必须处理,通常会在方法后面throws异常,或者是在方法内部进行try catch处理. 直接throws Exception 直接throws Exception,抛的异常太过 ...

  4. Spring Boot中Web应用的统一异常处理

    我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来 ...

  5. spring boot配置统一异常处理

    基于@ControllerAdvice的统一异常处理 >.这里ServerException是我自定义的异常,和普通Exception分开处理 >.这里的RequestResult是我自定 ...

  6. [转] Spring Boot中Web应用的统一异常处理

    [From] http://blog.didispace.com/springbootexception/ 我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供 ...

  7. Java生鲜电商平台-统一异常处理及架构实战

    Java生鲜电商平台-统一异常处理及架构实战 补充说明:本文讲得比较细,所以篇幅较长. 请认真读完,希望读完后能对统一异常处理有一个清晰的认识. 背景 软件开发过程中,不可避免的是需要处理各种异常,就 ...

  8. SpringBoot接口 - 如何优雅的写Controller并统一异常处理?

    SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?@pdai 为什么要优雅的处理异常 如果我们不统一的处理异常,经 ...

  9. SpringBoot入门教程(十九)@ControllerAdvice+@ExceptionHandler全局捕获Controller异常

    在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler.@InitBinder.@ModelAttribute,并应用到所有@Requ ...

随机推荐

  1. java Dialog

    Dialog构造方法 * Dialog(Frame owner, String title, boolean modal) 构造一个最初不可见的 Dialog,它带有指定的所有者 Frame.标题和模 ...

  2. linux 在 1 MB 之下的 ISA 内存

    一个最著名的 I/O 内存区是在个人计算机上的 ISA 范围. 这是在 640 KB(0xA0000)和 1 MB(0x100000)之间的内存范围. 因此, 它正好出现于常规内存 RAM 中间. 这 ...

  3. 【39.68%】【CF 714 C】Filya and Homework

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  4. Linux 内核设备属性

    sysfs 中的设备入口可有属性. 相关的结构是: struct device_attribute { struct attribute attr; ssize_t (*show)(struct de ...

  5. Fetch 记录

    encodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号.正斜杠.问号和井字号:而encodeURIComponent()则会对它发现的任何非标准字符进行编码. Fetch 请求body ...

  6. 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之Tarjan算法)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  7. C++Review1_多态和虚函数

    继承是实现多态的基础.虚函数是实现多态的方法.虚函数.多态.继承都是紧密相关的概念.而继承是所有概念的基础: 多态:简单来讲就是接口一样,实现多样.多态是指通过基类的指针或者引用,在运行时动态调用实际 ...

  8. echarts实现group关系图案例

    官网案例:https://www.echartsjs.com/examples/zh/editor.html?c=graph-simple 自己在项目中实现了两个group图: 1.先看实现效果,两个 ...

  9. win32汇编简单实现窗口程序

    .386 .model flat,stdcall option casemap:none ;========================== ;include部分 include windows. ...

  10. 洛谷P1248 加工生产调度 贪心

    正解:贪心 解题报告: 传送门$QwQ$ $umm$直接看可能比较难想,可以先考虑另一个题? 有$n$个小怪,每打一只小怪会扣$a_i$的血,打完之后会回升$b_i$的血,问至少要多少血量才能使全程血 ...