springboot断言异常封装与统一异常处理实现代码
WalkerShen 人气:0步骤
1、异常类
package com.walker.dianping.common.exceptions; import lombok.Data; @Data //继承RuntimeException public class BizException extends RuntimeException { private String msg; public BizException(String msg) { super(msg); //此处记得实例化 this.msg = msg; } }
2、统一异常处理配置类
package com.walker.dianping.common.config; import com.walker.dianping.common.exceptions.BizException; import com.walker.dianping.model.R; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice @Slf4j public class MyExceptionHandler { @ExceptionHandler(value = BizException.class) public R BizExceptionHandler(Exception e) { log.error("错误原因是:" + e.getMessage()); return R.fail("系统异常,原因如下:"+e.getMessage()); } @ExceptionHandler(value = Exception.class) public R exceptionHandler(Exception e) { log.error("错误原因是:" + e.getMessage()); return R.fail(e.getMessage()); } }
3、断言类
可以自己进行补充
package com.walker.dianping.common.utils; import com.walker.dianping.common.exceptions.BizException; import org.apache.commons.lang3.StringUtils; public abstract class Assert { //如果字符串为空的话,就抛出异常 public static void isBlank(String str, String message) { if (StringUtils.isBlank(str)) { throw new BizException(message); } } public static void isNull(Object object, String message) { if (object == null) { throw new BizException(message); } } }
4、使用
//查询类,如果类不存在则抛出异常 TbSeckillVoucherEntity entity = getById(voucherId); Assert.isNull(entity,"该"+voucherId+"优惠券不存在");
可以让代码变得相对简洁
接下来分别对这几种异常处理器做详细说明。
补充:异常处理器说明
handleServletException
一个http
请求,在到达Controller
前,会对该请求的请求信息与目标控制器信息做一系列校验。这里简单说一下:NoHandlerFoundException:首先根据请求Url
查找有没有对应的控制器,若没有则会抛该异常,也就是大家非常熟悉的404
异常;
HttpRequestMethodNotSupportedException:若匹配到了(匹配结果是一个列表,不同的是http
方法不同,如:Get、Post等),则尝试将请求的http
方法与列表的控制器做匹配,若没有对应http
方法的控制器,则抛该异常;
HttpMediaTypeNotSupportedException:然后再对请求头与控制器支持的做比较,比如content-type
请求头,若控制器的参数签名包含注解@RequestBody
,但是请求的content-type
请求头的值没有包含application/json
,那么会抛该异常(当然,不止这种情况会抛这个异常);MissingPathVariableException:未检测到路径参数。比如url为:/licence/{licenceId}
,参数签名包含@PathVariable("licenceId")
,当请求的url为/licence
,在没有明确定义url为/licence
的情况下,会被判定为:缺少路径参数;
MissingServletRequestParameterException:缺少请求参数。比如定义了参数@RequestParam("licenceId") String licenceId,但发起请求时,未携带该参数,则会抛该异常;TypeMismatchException: 参数类型匹配失败。比如:接收参数为Long型,但传入的值确是一个字符串,那么将会出现类型转换失败的情况,这时会抛该异常;
HttpMessageNotReadableException:与上面的HttpMediaTypeNotSupportedException
举的例子完全相反,即请求头携带了"content-type: application/json;charset=UTF-8"
,但接收参数却没有添加注解@RequestBody
,或者请求体携带的 json 串反序列化成 pojo 的过程中失败了,也会抛该异常;HttpMessageNotWritableException:返回的 pojo 在序列化成 json 过程失败了,那么抛该异常;
handleBindException
参数校验异常,后文详细说明。
handleValidException
参数校验异常,后文详细说明。
handleBusinessException、handleBaseException
处理自定义的业务异常,只是handleBaseException
处理的是除了 BusinessException
意外的所有业务异常。就目前来看,这2个是可以合并成一个的。
handleException
处理所有未知的异常,比如操作数据库失败的异常。
注:上面的handleServletException
、handleException
这两个处理器,返回的异常信息,不同环境返回的可能不一样,以为这些异常信息都是框架自带的异常信息,一般都是英文的,不太好直接展示给用户看,所以统一返回SERVER_ERROR
代表的异常信息。
总结
加载全部内容