看看人家 SpringBoot 的全局异常处理多么优雅_第1页
看看人家 SpringBoot 的全局异常处理多么优雅_第2页
看看人家 SpringBoot 的全局异常处理多么优雅_第3页
看看人家 SpringBoot 的全局异常处理多么优雅_第4页
看看人家 SpringBoot 的全局异常处理多么优雅_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

看看人家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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论