![看看人家 SpringBoot 的全局异常处理多么优雅_第1页](http://file4.renrendoc.com/view14/M01/09/3B/wKhkGWY2ZAOAc1FCAAEkEIbMxLg058.jpg)
![看看人家 SpringBoot 的全局异常处理多么优雅_第2页](http://file4.renrendoc.com/view14/M01/09/3B/wKhkGWY2ZAOAc1FCAAEkEIbMxLg0582.jpg)
![看看人家 SpringBoot 的全局异常处理多么优雅_第3页](http://file4.renrendoc.com/view14/M01/09/3B/wKhkGWY2ZAOAc1FCAAEkEIbMxLg0583.jpg)
![看看人家 SpringBoot 的全局异常处理多么优雅_第4页](http://file4.renrendoc.com/view14/M01/09/3B/wKhkGWY2ZAOAc1FCAAEkEIbMxLg0584.jpg)
![看看人家 SpringBoot 的全局异常处理多么优雅_第5页](http://file4.renrendoc.com/view14/M01/09/3B/wKhkGWY2ZAOAc1FCAAEkEIbMxLg0585.jpg)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
看看人家SpringBoot的全局异常处理,多么优雅...本篇文章主要介绍的是SpringBoot项目进行全局异常的处理。SpringBoot全局异常准备说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码。开发准备环境要求
JDK:1.8
SpringBoot:1.5.17.RELEASE首先还是Maven的相关依赖:
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<java.version>1.8java.version>
<piler.source>1.8piler.source>
<piler.target>1.8piler.target>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.17.RELEASEversion>
<relativePath
/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.41version>
dependency>
dependencies>
配置文件这块基本不需要更改,全局异常的处理只需在代码中实现即可。代码编写SpringBoot的项目已经对有一定的异常处理了,但是对于我们开发者而言可能就不太合适了,因此我们需要对这些异常进行统一的捕获并处理。SpringBoot中有一个ControllerAdvice的注解,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。我们根据下面的这个示例来看该注解是如何使用吧。示例代码:@ControllerAdvice
public
class
MyExceptionHandler
{
@ExceptionHandler(value
=Exception.class)
public
String
exceptionHandler(Exception
e){
System.out.println("未知异常!原因是:"+e);
return
e.getMessage();
}
}
上述的示例中,我们对捕获的异常进行简单的二次处理,返回异常的信息,虽然这种能够让我们知道异常的原因,但是在很多的情况下来说,可能还是不够人性化,不符合我们的要求。那么我们这里可以通过自定义的异常类以及枚举类来实现我们想要的那种数据吧。自定义基础接口类首先定义一个基础的接口类,自定义的错误描述枚举类需实现该接口。代码如下:public
interface
BaseErrorInfoInterface
{
/**
错误码*/
String
getResultCode();
/**
错误描述*/
String
getResultMsg();
}
自定义枚举类然后我们这里在自定义一个枚举类,并实现该接口。代码如下:public
enum
CommonEnum
implements
BaseErrorInfoInterface
{
//
数据操作错误定义
SUCCESS("200",
"成功!"),
BODY_NOT_MATCH("400","请求的数据格式不符!"),
SIGNATURE_NOT_MATCH("401","请求的数字签名不匹配!"),
NOT_FOUND("404",
"未找到该资源!"),
INTERNAL_SERVER_ERROR("500",
"服务器内部错误!"),
SERVER_BUSY("503","服务器正忙,请稍后再试!")
;
/**
错误码
*/
private
String
resultCode;
/**
错误描述
*/
private
String
resultMsg;
CommonEnum(String
resultCode,
String
resultMsg)
{
this.resultCode
=
resultCode;
this.resultMsg
=
resultMsg;
}
@Override
public
String
getResultCode()
{
return
resultCode;
}
@Override
public
String
getResultMsg()
{
return
resultMsg;
}
}
自定义异常类然后我们在来自定义一个异常类,用于处理我们发生的业务异常。代码如下:public
class
BizException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
1L;
/**
*
错误码
*/
protected
String
errorCode;
/**
*
错误信息
*/
protected
String
errorMsg;
public
BizException()
{
super();
}
public
BizException(BaseErrorInfoInterface
errorInfoInterface)
{
super(errorInfoInterface.getResultCode());
this.errorCode
=
errorInfoInterface.getResultCode();
this.errorMsg
=
errorInfoInterface.getResultMsg();
}
public
BizException(BaseErrorInfoInterface
errorInfoInterface,
Throwable
cause)
{
super(errorInfoInterface.getResultCode(),
cause);
this.errorCode
=
errorInfoInterface.getResultCode();
this.errorMsg
=
errorInfoInterface.getResultMsg();
}
public
BizException(String
errorMsg)
{
super(errorMsg);
this.errorMsg
=
errorMsg;
}
public
BizException(String
errorCode,
String
errorMsg)
{
super(errorCode);
this.errorCode
=
errorCode;
this.errorMsg
=
errorMsg;
}
public
BizException(String
errorCode,
String
errorMsg,
Throwable
cause)
{
super(errorCode,
cause);
this.errorCode
=
errorCode;
this.errorMsg
=
errorMsg;
}
public
String
getErrorCode()
{
return
errorCode;
}
public
void
setErrorCode(String
errorCode)
{
this.errorCode
=
errorCode;
}
public
String
getErrorMsg()
{
return
errorMsg;
}
public
void
setErrorMsg(String
errorMsg)
{
this.errorMsg
=
errorMsg;
}
public
String
getMessage()
{
return
errorMsg;
}
@Override
public
Throwable
fillInStackTrace()
{
return
this;
}
}
自定义数据格式顺便这里我们定义一下数据的传输格式。代码如下:搜索公众号后端架构师后台回复“面试”,获取一份惊喜礼包。public
class
ResultBody
{
/**
*
响应代码
*/
private
String
code;
/**
*
响应消息
*/
private
String
message;
/**
*
响应结果
*/
private
Object
result;
public
ResultBody()
{
}
public
ResultBody(BaseErrorInfoInterface
errorInfo)
{
this.code
=
errorInfo.getResultCode();
this.message
=
errorInfo.getResultMsg();
}
public
String
getCode()
{
return
code;
}
public
void
setCode(String
code)
{
this.code
=
code;
}
public
String
getMessage()
{
return
message;
}
public
void
setMessage(String
message)
{
this.message
=
message;
}
public
Object
getResult()
{
return
result;
}
public
void
setResult(Object
result)
{
this.result
=
result;
}
/**
*
成功
*
*
@return
*/
public
static
ResultBody
success()
{
return
success(null);
}
/**
*
成功
*
@param
data
*
@return
*/
public
static
ResultBody
success(Object
data)
{
ResultBody
rb
=
new
ResultBody();
rb.setCode(CommonEnum.SUCCESS.getResultCode());
rb.setMessage(CommonEnum.SUCCESS.getResultMsg());
rb.setResult(data);
return
rb;
}
/**
*
失败
*/
public
static
ResultBody
error(BaseErrorInfoInterface
errorInfo)
{
ResultBody
rb
=
new
ResultBody();
rb.setCode(errorInfo.getResultCode());
rb.setMessage(errorInfo.getResultMsg());
rb.setResult(null);
return
rb;
}
/**
*
失败
*/
public
static
ResultBody
error(String
code,
String
message)
{
ResultBody
rb
=
new
ResultBody();
rb.setCode(code);
rb.setMessage(message);
rb.setResult(null);
return
rb;
}
/**
*
失败
*/
public
static
ResultBody
error(
String
message)
{
ResultBody
rb
=
new
ResultBody();
rb.setCode("-1");
rb.setMessage(message);
rb.setResult(null);
return
rb;
}
@Override
public
String
toString()
{
return
JSONObject.toJSONString(this);
}
}
自定义全局异常处理类最后我们在来编写一个自定义全局异常处理的类。代码如下:@ControllerAdvice
public
class
GlobalExceptionHandler
{
private
static
final
Logger
logger
=
LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
*
处理自定义的业务异常
*
@param
req
*
@param
e
*
@return
*/
@ExceptionHandler(value
=
BizException.class)
@ResponseBody
public
ResultBody
bizExceptionHandler(HttpServletRequest
req,
BizException
e){
logger.error("发生业务异常!原因是:{}",e.getErrorMsg());
return
ResultBody.error(e.getErrorCode(),e.getErrorMsg());
}
/**
*
处理空指针的异常
*
@param
req
*
@param
e
*
@return
*/
@ExceptionHandler(value
=NullPointerException.class)
@ResponseBody
public
ResultBody
exceptionHandler(HttpServletRequest
req,
NullPointerException
e){
logger.error("发生空指针异常!原因是:",e);
return
ResultBody.error(CommonEnum.BODY_NOT_MATCH);
}
/**
*
处理其他异常
*
@param
req
*
@param
e
*
@return
*/
@ExceptionHandler(value
=Exception.class)
@ResponseBody
public
ResultBody
exceptionHandler(HttpServletRequest
req,
Exception
e){
logger.error("未知异常!原因是:",e);
return
ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR);
}
}
因为这里我们只是用于做全局异常处理的功能实现以及测试,所以这里我们只需在添加一个实体类和一个控制层类即可。实体类又是万能的用户表(▽)代码如下:public
class
User
implements
Serializable{
private
static
final
long
serialVersionUID
=
1L;
/**
编号
*/
private
int
id;
/**
姓名
*/
private
String
name;
/**
年龄
*/
private
int
age;
public
User(){
}
public
int
getId()
{
return
id;
}
public
void
setId(int
id)
{
this.id
=
id;
}
public
String
getName()
{
return
name;
}
public
void
setName(String
name)
{
=
name;
}
public
int
getAge()
{
return
age;
}
public
void
setAge(int
age)
{
this.age
=
age;
}
public
String
toString()
{
return
JSONObject.toJSONString(this);
}
}
Controller控制层控制层这边也比较简单,使用Restful风格实现的CRUD功能,不同的是这里我故意弄出了一些异常,好让这些异常被捕获到然后处理。这些异常中,有自定义的异常抛出,也有空指针的异常抛出,当然也有不可预知的异常抛出(这里我用类型转换异常代替),那么我们在完成代码编写之后,看看这些异常是否能够被捕获处理成功吧!代码如下:@RestController
@RequestMapping(value
=
"/api")
public
class
UserRestController
{
@PostMapping("/user")
public
boolean
insert(@RequestBody
User
user)
{
System.out.println("开始新增...");
//如果姓名为空就手动抛出一个自定义的异常!
if(user.getName()==null){
throw
new
BizException("-1","用户姓名不能为空!");
}
return
true;
}
@PutMapping("/user")
public
boolean
update(@RequestBody
User
user)
{
System.out.println("开始更新...");
//这里故意造成一个空指针的异常,并且不进行处理
String
str=null;
str.equals("111");
return
true;
}
@DeleteMapping("/user")
public
boolean
delete(@RequestBody
User
user)
{
System.out.println("开始删除...");
//这里故意造成一个异常,并且不进行处理
Integer.parseInt("abc123");
return
true;
}
@GetMapping("/user")
public
List
findByUser(User
user)
{
System.out.println("开始查询...");
List
userList
=new
ArrayList<>();
User
user2=new
User();
user2.setId(1L);
user2.setName("xuwujing");
user2.setAge(18);
userList.add(user2);
return
userList;
}
}
App入口和普通的SpringBoot项目基本一样。代码如下:@SpringBootApplication
public
class
App
{
public
static
void
main(
String[]
args
)
{
SpringApplication.run(App.class,
args);
System.out.println("程序正在运行...");
}
}
功能测试我们成功启动该程序之后,使用Postman工具来进行接口测试。搜索公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。首先进行查询,查看程序正常运行是否ok,使用GET方式进行请求。GET
[http://localhost:8181/api/user](http://localhost:8181/api/user)返回参数为:{"id":1,"name":"xuwujing","age":18}示例图:可以看到程序正常返回,并没有因自定义的全局异常而影响。然后我们再来测试下
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度新材料研发授权委托合同
- 2025年度智慧城市基础设施合作开发合同范本
- 2025年度共买房产合同协议书
- 2025年度国际货运代理海洋运输货物保险合同
- 二零二四年度企业级云计算服务合同
- 二零二四年度影视制作合同创意构思与版权归属2篇
- 2025年度股东分红权转让及分红权分配比例调整合同
- 2025年度厨房员工劳动合同员工离职手续与档案管理合同4篇
- 2025年户外探险领队岗位招聘及服务合同
- 2025年度交通设施广告制作安装及安全提示合同
- 湖北省十堰市城区2024-2025学年九年级上学期期末质量检测综合物理试题(含答案)
- 导播理论知识培训班课件
- 电厂检修安全培训课件
- 高中生物选择性必修1试题
- 电气工程及其自动化专业《毕业设计(论文)及答辩》教学大纲
- 《客舱安全管理与应急处置》课件-第14讲 应急撤离
- 危险化学品押运员培训
- 2025届高考作文押题预测5篇
- 一年级数学(上)计算题专项练习集锦
- 阿里巴巴国际站:2024年珠宝眼镜手表及配饰行业报告
- 手术室护士考试题及答案
评论
0/150
提交评论