SpringBoot处理全局统一异常
在后端发生异常或者是请求出错时,前端通常显示如下
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方式可以定义多个拦截方法,拦截不同的异常类,并且可以获取抛出的异常信息,*度更大。
下一篇: 支付宝4年后重做街头信用实验:结果惊讶