提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
在实际开发工作中,我们期望的两种情况是,一种是当正常操作时按接口要求返回数据,而另一种则是当非正常流程时要获取异常信息进行记录并提示给用户
然而业务代码不显式地对异常进行捕获、处理,但是异常肯定还是要处理的否则系统会出现很多异常未捕获导致崩溃,下面讲介绍如何通过SpringMVC提供的控制器增强类统一由一个类去完成异常的捕获,从而更优雅的去掉try {…} catch {…} finally {…} 代码块,增加代码可读性
提示:以下是本篇文章正文内容,下面案例可供参考
一、创建全局异常处理器
@ExceptionHandler
Spring3.0提供的标识在方法上或类上的注解,用来表明方法的处理异常类型。
@ControllerAdvice或@RestControllerAdvice
(这个根据你的Controller层用的是@Controller还是@RestController来决定)
Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强, 在项目中来增强
SpringMVC中的Controller。通常和 @ExceptionHandler 结合使用,来处理SpringMVC的异常
信息。
@ResponseStatus
Spring3.0提供的标识在方法上或类上的注解,用状态代码和应返回的原因标记方法或异常类。
调用处理程序方法时,状态代码将应用于HTTP响应。
注:@ControllerAdvice=@ControllerAdvice + @ResponseBody
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 系统异常 预期以外异常
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse exception(Exception e) {
log.error("【系统异常】{}", e.getMessage(), e);
return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
}
}
CommonError类是自定义的异常类型枚举类
public enum CommonError {
UNKOWN_ERROR("执行过程异常,请重试。"),
PARAMS_ERROR("非法参数"),
OBJECT_NULL("对象为空"),
QUERY_NULL("查询结果为空"),
REQUEST_NULL("请求参数为空");
private String errMessage;
public String getErrMessage() {
return errMessage;
}
private CommonError( String errMessage) {
this.errMessage = errMessage;
}
}
RestErrorResponse类 是用于 错误响应参数包装
/**
* 错误响应参数包装
* 和前端约定返回的异常信息模型 将来以后返回的json属性名称叫做errMessage
*/
public class RestErrorResponse {
private String errMessage;
public RestErrorResponse(String errMessage){
this.errMessage= errMessage;
}
public String getErrMessage() {
return errMessage;
}
public void setErrMessage(String errMessage) {
this.errMessage = errMessage;
}
}
二、自定义异常处理类
继承RuntimeException实现自己的自定义异常
/**
* 统一异常处理
*/
public class MyException extends RuntimeException {
private String errMessage;
public MyException () {
super();
}
public MyException (String errMessage) {
super(errMessage);
this.errMessage = errMessage;
}
public String getErrMessage() {
return errMessage;
}
public static void cast(CommonError commonError) {
throw new MyException (commonError.getErrMessage());
}
public static void cast(String errMessage) {
throw new MyException (errMessage);
}
}
/**
* 文件信息异常类
*
*/
public class FileException extends RuntimeException {
public FileException(String code, Object[] args) {
super("file", code, args, null);
}
public FileException(String name) {
super("file", name,null);
}
}
三、全局异常处理器中添加自定义异常处理
将第二步中的MyException 和 FileException 添加到第一步中的全局异常处理器GlobalExceptionHandler 中
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 非系统自定义异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse exception(Exception e) {
log.error("【系统异常】{}", e.getMessage(), e);
return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
}
/**
* 系统自定义异常
*/
@ExceptionHandler(MyException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse customException(MyExceptione) {
log.error("【系统异常】{}", e.getErrMessage(), e);
return new RestErrorResponse(e.getErrMessage());
}
}
四、手动抛出异常
String name ="";
if(StringUtils.isEmpty(name)){
MysException.cast("名称不能为空!");
}