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

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. linux版本依赖

    记住, 你的模块代码一定要为每个它要连接的内核版本重新编译 -- 至少, 在缺乏 modversions 时, 这里不涉及因为它们更多的是给内核发布制作者, 而不是开发者. 模块 是紧密结合到一个特殊 ...

  2. Apache ServiceMix介绍

    Apache ServiceMix介绍 Apache ServiceMix 是一个广泛使用的开源ESB,适合SOA项目的集成,它提供类似商业ESB产品一样的功能呢,它的核心是基于开放标准和规范. Se ...

  3. vue 父组件中调用子组件函数

    2019/06/06 在父组件中调用子组件的方法:  1.给子组件定义一个ref属性.eg:ref="childItem"  2.在子组件的methods中声明一个函数.eg: u ...

  4. MFC 封装类为静态链接库

    mfc自带的基本控件都不怎么美观,所以一般开发者都会自定义类对控件进行重绘.手里也积累了不少控件的重绘,对对话框.静态文本.列表框等. 但是每次都要把这些类重新导入到新的工程里,比较麻烦,而且我也不想 ...

  5. 很多.net 程序员不知道又非常重要的 .net高级调试技巧.调试别人的dll方法内的变量

    事情是这样的, 最近需要开发Orcale的数据库. 于是使用了EF 加上 Oracle.ManagedDataAccess.Client 这个Oracle.ManagedDataAccess 很好用, ...

  6. BZOJ 3166

    BZOJ3196: Tyvj 1730 二逼平衡树 传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题意: 1.查询k在区间内的排名 ...

  7. HBase 原理

    遗留问题: 数据在更新时首先写入Log(WAL log)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的 ...

  8. $AT2292\ Division\ into\ Two$ $dp$

    正解:$dp$ 解题报告: 传送门$QwQ$ 不妨令$A\geq B$,于是先$sort$然后预处理判下如果有三个元素两两差都小于$B$的就直接$GG$了. 然后考虑对集合$X$进行$dp$,剩下的数 ...

  9. Ecshop在模板中判断用户是否登陆,获取用户等级信息

    ecshop模板中smarty怎样判断用户等级.用户id.用户昵称用户名,请看以下方法,使用全局变量 <!-- {if $smarty.session.user_rank gt 1}--> ...

  10. 子网划分及NAT技术总结

    近段项目需要用到网络相关的知识,硬着头皮又回顾了一波,这里做一下记录. 一 分类的IP地址 我们使用的IP地址(IP V4)可以划分为A,B,C,D,E 5个类型,其中的D,为组播地址,E类地址为保留 ...