Spring Boot处理全局统一异常的两种方法与区别

前言

在后端发生异常或者是请求出错时,前端通常显示如下

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Jun 07 15:38:07 CST 2019
There was an unexpected error (type=Not Found, status=404).
No message available

对于用户来说非常不友好。

本文主要讲解如何在SpringBoot应用中使用统一异常处理。

实现方式

  • 第一种:使用@ControllerAdvice和@ExceptionHandler注解
  • 第二种: 使用ErrorController类来实现。

第一种:使用@ControllerAdvice和@ExceptionHandler注解

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

 @ResponseBody
 @ExceptionHandler(NullPointerException.class)
 public BaseResult globalException(HttpServletResponse response,NullPointerException ex){

 log.info("GlobalExceptionHandler...");
log.info("错误代码:" + response.getStatus());
BaseResult result = new WebResult(WebResult.RESULT_FAIL,"request error:"+response.getStatus()
     ,"GlobalExceptionHandler:"+ex.getMessage());
 return result;
}

}

注解@ControllerAdvice表示这是一个控制器增强类,当控制器发生异常且符合类中定义的拦截异常类,将会被拦截。

可以定义拦截的控制器所在的包路径

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
 @AliasFor("basePackages")
 String[] value() default {};

 @AliasFor("value")
 String[] basePackages() default {};

 Class<?>[] basePackageClasses() default {};

 Class<?>[] assignableTypes() default {};

 Class<? extends Annotation>[] annotations() default {};
}

注解ExceptionHandler定义拦截的异常类

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
 Class<? extends Throwable>[] value() default {};
}

第二种: 使用ErrorController类来实现。

系统默认的错误处理类为BasicErrorController,将会显示如上的错误页面。

这里编写一个自己的错误处理类,上面默认的处理类将不会起作用。

getErrorPath()返回的路径服务器将会重定向到该路径对应的处理类,本例中为error方法。

@Slf4j
@RestController
public class HttpErrorController implements ErrorController {

 private final static String ERROR_PATH = "/error";

 @ResponseBody
 @RequestMapping(path = ERROR_PATH )
 public BaseResult error(HttpServletRequest request, HttpServletResponse response){
 log.info("访问/error" + " 错误代码:" + response.getStatus());
 BaseResult result = new WebResult(WebResult.RESULT_FAIL,"HttpErrorController error:"+response.getStatus());
return result;
 }
 @Override
 public String getErrorPath() {
 return ERROR_PATH;
 }
}

测试

以上定义了一个统一的返回类BaseResult,方便前端进行处理。

package com.microblog.common.result;

import java.io.Serializable;

public class BaseResult implements Serializable {

 private static final long serialVersionUID = 1L;

 public static final int RESULT_FAIL = 0;
 public static final int RESULT_SUCCESS = 1;

 //返回代码
 private Integer code;

 //返回消息
 private String message;

 //返回对象
 private Object data;

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

 public BaseResult(Integer code, String message, Object object) {
  this.code = code;
  this.message = message;
  this.data = object;
 }

 public Integer getCode() {
  return code;
 }

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

 public String getMessage() {
  return message;
 }

 public void setMessage(String message) {
  this.message = message;
 }

 public Object getData() {
  return data;
 }

 public void setData(Object data) {
  this.data = data;
 }
}

编写一个测试控制器

@Slf4j
@RestController
@RequestMapping("/user")
public class TestController {

 @RequestMapping("/info1")
 public String test(){
  log.info("/user/info1");

  throw new NullPointerException("TestController have exception");

 }
}

1.发出一个错误的请求,也就是没有对应的处理类。

从返回可以看到是由HttpErrorController类处理

{"code":0,"message":"HttpErrorController error:404","data":null}

2.发出一个正常的请求(TestController的test()处理),处理类中抛出空异样

从返回中可以看出是由GlobalExceptionHandler类处理

{"code":0,"message":"request error:200","data":"GlobalExceptionHandler:TestController have exception"}

区别

1.注解@ControllerAdvice方式只能处理控制器抛出的异常。此时请求已经进入控制器中。

2.类ErrorController方式可以处理所有的异常,包括未进入控制器的错误,比如404,401等错误

3.如果应用中两者共同存在,则@ControllerAdvice方式处理控制器抛出的异常,类ErrorController方式未进入控制器的异常。

4.@ControllerAdvice方式可以定义多个拦截方法,拦截不同的异常类,并且可以获取抛出的异常信息,自由度更大。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • SpringBoot使用统一异常处理详解

    场景:针对异常处理,我们原来的做法是一般在最外层捕获异常即可,例如在Controller中 @Controller public class HelloController { private static final Logger logger = LoggerFactory.getLogger(HelloController.class); @GetMapping(value = "/hello") @ResponseBody public Result hello() { try

  • SpringBoot全局异常与数据校验的方法

    异常处理是每个项目中都绕不开的话题,那么如何优雅的处理异常,是本文的话题.本文将结合SpringBoot框架一起和大家探讨下. 要思考的问题 在现在的前后端交互中,通常都规范了接口返回方式,如返回的接口状态(成功|失败)以及要返回的数据在那个字段取,或者说失败了以后提示信息从接口哪里返回,因此,如果想做全局异常,并且异常发生后能准确的返回给前端解析,那么需要异常发生时返回给前端的格式与正常失败场景的格式一致. 项目建立 利用idea 工具,很容易的搭建一个SpringBoot项目,要引入的mav

  • springboot全局异常处理详解

    一.单个controller范围的异常处理 package com.xxx.secondboot.web; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import

  • springboot结合全局异常处理实现登录注册验证

    在学校做一个校企合作项目,注册登录这一块需要对注册登录进行输入合法的服务器端验证,因为是前后端分离开发,所以要求返回JSON数据. 方法有很多,这觉得用全局异常处理比较容易上手 全局异常处理 首先来创建一个sprIngboot的web项目或模块,目录结构如下 实体类User.java @Data public class User { private String userName; private String passwold; } 实体类UserResult.java 把数据封装到这里返回

  • SpringBoot初始教程之统一异常处理详解

    1.介绍 在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示.SpringBoot在页面发生异常的时候会自动把请求转到/error,SpringBoot内置了一个BasicErrorController对异常进行统一的处理,当然也可以自定义这个路径 application.yaml server: port: 8080 error: path: /custom/error BasicErrorController提供两种返回错误一种是页面返回.当

  • SpringBoot学习之全局异常处理设置(返回JSON)

    SpringBoot学习--全局异常处理设置(返回JSON) 需求 现在习惯使用ajax的方式发起请求,所以经常需要服务端返回一个json或者字符串. 控制全局的异常处理. 如果在单个方法中使用try,catch把方法包裹起来,工作量大,而且会异常的抛出而导致@Transactional注解的方法事务不会回滚. 说明 使用@ControllerAdvice注解 使用@ExceptionHandler注解 @ControllerAdvice 该注解是spring2.3以后新增的一个注解,主要是用来

  • SpringBoot 统一异常处理详解

    代码结构 配置pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/

  • springboot springmvc抛出全局异常的解决方法

    springboot中抛出异常,springboot自带的是springmvc框架,这个就不多说了. springmvc统一异常解决方法这里要说明的是.只是结合了springboot的使用而已.直接上代码,有效有用的才是ok. 1.定义异常捕获 package com.example.rest.error; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.Exce

  • SpringBoot如何优雅的处理全局异常

    前言 本篇文章主要介绍的是SpringBoot项目进行全局异常的处理. SpringBoot全局异常准备 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码. 开发准备 环境要求 JDK:1.8 SpringBoot:1.5.17.RELEASE 首先还是Maven的相关依赖: <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.

  • Spring Boot处理全局统一异常的两种方法与区别

    前言 在后端发生异常或者是请求出错时,前端通常显示如下 Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Fri Jun 07 15:38:07 CST 2019 There was an unexpected error (type=Not Found, status=404). No message available

  • PHP中数组合并的两种方法及区别介绍

    PHP数组合并两种方法及区别 如果是关联数组,如下: 复制代码 代码如下: $a = array( 'where' => 'uid=1', 'order' => 'uid', ); $b = array( 'where' => 'uid=2', 'order' => 'uid desc', ); 1. array_merge,如果两个数组存在相同的key,后面的一个会覆盖前面的 复制代码 代码如下: <?php $c = array_merge($a, $b); var_ex

  • Spring Data JPA实现动态查询的两种方法

    前言 一般在写业务接口的过程中,很有可能需要实现可以动态组合各种查询条件的接口.如果我们根据一种查询条件组合一个方法的做法来写,那么将会有大量方法存在,繁琐,维护起来相当困难.想要实现动态查询,其实就是要实现拼接SQL语句.无论实现如何复杂,基本都是包括select的字段,from或者join的表,where或者having的条件.在Spring Data JPA有两种方法可以实现查询条件的动态查询,两种方法都用到了Criteria API. Criteria API 这套API可用于构建对数据

  • js截取字符串的两种方法及区别详解

    var long2="1988-0w-07"; alert(long2.substring(0,4)+"------"+long2.substring(5,6));   1988------0 alert(long2.substr(0,4)+"------"+long2.substr(5,2));            1988-----0w substring 截取的时候坐标  包括前边  不包括后边 substr    截取字符串前边参数的坐

  • Ajax中解析Json的两种方法对比分析

    eval();  //此方法不推荐 JSON.parse();  //推荐方法 一.两种方法的区别 我们先初始化一个json格式的对象: var jsonDate = '{ "name":"周星驰","age":23 }' var jsonObj = eval( '(' + jsonDate + ')' ); // eval();方法 var jsonObj = JSON.parse( jsonDate ); // JSON.parse(); 方

  • python list排序的两种方法及实例讲解

    对List进行排序,Python提供了两个方法 方法1.用List的内建函数list.sort进行排序 list.sort(func=None, key=None, reverse=False) Python实例: >>> list = [2,5,8,9,3] >>> list [2,5,8,9,3] >>> list.sort() >>> list [2, 3, 5, 8, 9] 方法2.用序列类型函数sorted(list)进行排

  • Spring Boot 捕捉全局异常 统一返回值的问题

    在前后端分离的情况下,我们经常会定义一个统一的反回数据格式,通常都会包含状态码,返回信息,返回的数据,是否成功等参数. 1.ResultCode 单独定义了一个ReturnCode枚举类用于存储代码和返回的Message public enum ResultCode { //成功 SUCCESS(200), // 失败 FAIL(400), // 未认证(签名错误) UNAUTHORIZED(401), // 接口不存在 NOT_FOUND(404), // 服务器内部错误 INTERNAL_S

  • Spring Boot全局统一异常处理器

    一.封装统一返回结果类 import com.jiusen.exercise.enums.ErrorEnum; import com.jiusen.exercise.exception.BusinessException; import lombok.Getter; import lombok.Setter; /** * @author: Lawson * @date: 2021/5/11 * @description: TODO 统一的返回结果 */ @Getter @Setter publi

  • 阿里nacos+springboot+dubbo2.7.3统一处理异常的两种方式

    目录 1.为什么要抛异常? 2.给出解决方案 3.两种抛异常的实例解说 dubbo工程搭建 在网上很多关于dubbo异常统一处理的博文,90%都是抄来抄去.大多都是先上一段dubbo中对于异常的统一处理的原码,然后说一堆的(甚至有12345,五种)不靠谱方案,最后再说“本篇使用的是方案4”,然后再对所谓的方案4写了一段文字,最后还说不清!!! 本篇解决方案不会那么罗里吧嗦也不会贴dubbo源码来凑字数,我就直接从刚结束不久的双11保卫战性能全链路优化中我们的面对10万级别TPS的方案中提取的代码

  • 浅谈spring boot 1.5.4 异常控制

    spring boot 已经做了统一的异常处理,下面看看如何自定义处理异常 1.错误码页面映射 1.1静态页面 必须配置在 resources/static/error文件夹下,以错误码命名 下面是404错误页面内容,当访问一个不存在的链接的时候,定位到此页 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Not F

随机推荐