SpringBoot项目如何做到统一异常处理
在项目中,难免会出现各种各样的异常,我们希望异常信息尽可能详细,包括响应状态码,响应的字符串异常信息,甚至操作时间等等,这样可以方便地快速定位到发生异常的位置.所以,一个项目中对于异常的处理就显得尤为重要.那么,小编就以springboot框架,通过代码实例展示统一异常的处理方式.
1.首先我们简单搭建一个springboot框架的项目,项目名称是exceptionhandler(异常处理)
2.导入相关依赖
导入lombok依赖,提供@getter注解
导入日期工具类jodatime,提供datetime.now()方法
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.1.8.release</version> </parent> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> </dependency> <!--日期工具类:jodatime--> <dependency> <groupid>joda-time</groupid> <artifactid>joda-time</artifactid> </dependency> </dependencies> <build> <plugins> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> </plugin> </plugins> </build>
3.编写application.yml配置文件
注意这里添加了访问路径前缀
server: port: 8082 servlet: context-path: /exception
4.编写springboot的启动类
package com.exception; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.springbootapplication; @springbootapplication public class exceptionapplication { public static void main(string[] args) { springapplication.run(exceptionapplication.class, args); } }
5.编写异常枚举类
异常枚举类中,应该列举出项目可能出现的所有异常类型,这里只拿数学计算异常举例
package com.exception.enums; import lombok.getter; /** * 异常枚举类 */ @getter public enum exceptionenum { artithmetic(500, "数学计算异常"); private integer status; private string message; exceptionenum(integer status, string message) { this.status = status; this.message = message; } }
6.编写自定义异常类
自定义异常类继承runtimeexception,同时runtimeexception继承exception类,而exception又继承throwable类,super方法最终也是throwable中的方法
package com.exception.exceptions; import com.exception.enums.exceptionenum; import lombok.getter; /** * 自定义异常类 */ @getter public class selfdefinedexception extends runtimeexception { private integer status; public selfdefinedexception(exceptionenum exceptionenum) { super(exceptionenum.getmessage()); this.status = exceptionenum.getstatus(); } public selfdefinedexception(exceptionenum exceptionenum, throwable cause) { super(exceptionenum.getmessage(), cause); this.status = exceptionenum.getstatus(); } }
7.编写统一异常返回结果类
package com.exception.entity; import com.exception.exceptions.selfdefinedexception; import lombok.getter; import org.joda.time.datetime; /** * 统一异常返回结果类 */ @getter public class exceptionresult { private integer status; private string message; private string timestamp; public exceptionresult(selfdefinedexception e) { this.status = e.getstatus(); this.message = e.getmessage(); this.timestamp = datetime.now().tostring("yyyy-mm-dd hh:mm:ss"); } }
8.编写统一异常拦截类
需注意两个spring注解的作用:
@controlleradvice:此注解默认情况下,会拦截所有加了@controller注解的类
@exceptionhandler():此注解用在方法上,括号内声明要处理的异常类型,可以指定多个,这里我们指定的是自定义异常
package com.exception.advice; import com.exception.entity.exceptionresult; import com.exception.exceptions.selfdefinedexception; import lombok.extern.slf4j.slf4j; import org.springframework.http.responseentity; import org.springframework.web.bind.annotation.controlleradvice; import org.springframework.web.bind.annotation.exceptionhandler; /** * 统一异常拦截类 */ @controlleradvice @slf4j public class basicexceptionadvice { @exceptionhandler(selfdefinedexception.class) public responseentity<exceptionresult> handlerexception(selfdefinedexception e) {//参数类型与要处理的异常类型必须匹配 return responseentity.status(e.getstatus()).body(new exceptionresult(e));//body中的对象必须和responseentity中的对象一致 } }
9.编写测试类
package com.exception.controller; import com.exception.enums.exceptionenum; import com.exception.exceptions.selfdefinedexception; import lombok.extern.slf4j.slf4j; import org.springframework.http.responseentity; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.postmapping; import org.springframework.web.bind.annotation.restcontroller; @restcontroller @slf4j public class testcontroller { @getmapping("/test") public responseentity<string> login() { try { integer tempvalue = 10 / 0; } catch (exception e) { throw new selfdefinedexception(exceptionenum.artithmetic);//catch捕获异常后,这里throw抛出异常并未处理,所以后面的代码不会执行 } return responseentity.ok("没发现异常,返回正确的字符串"); } }
10.测试结果
通过idea自带的http client进行测试,观察响应结果如下.这样我们就得到了
总结:
因为项目中会出现各种各样的异常,所以我们通过一个异常枚举类将所有的异常进行列举.我们希望捕获自己定义的异常,所以编写了一个自定义异常类,同时我们希望响应的异常结果规则且详细,所以通过一个统一异常结果类来实现.最重要的是,我们还需要一个异常拦截类,这样在我们抛出自定义异常的时候,这个异常拦截类能够进行拦截,并将我们定义好的响应结果(也就是异常体所有信息)返回.
上一篇: 椰子的营养价值有哪些?营养是多多的哟