介绍野图BOSS
如题,今天我们来战SpringBoot是如何统一处理全局异常的。既然是第一战,那就要来点不一样的,通常SpringBoot中的全局异常处理主要起作用的两个注解是@ControllerAdvice和@ExceptionHandler ,但是今天,我们用另一种方式,来更快更漂亮的拿下我们的Exception这个BOSS!
准备配置武器
第一步,规划武器模型
配置参数
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--阿里 FastJson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
第二步,升级武器物理伤害
消息code类
public enum ResultCode {
SUCCESS("200"),//成功
FAIL("400"),//失败
NOT_FOUND("404"),//接口不存在
INTERNAL_SERVER_ERROR("500"),//服务器内部错误
ERROR("9999");
private final String code;
ResultCode(String code) {
this.code = code;
}
public String code() {
return code;
}
}
第三步,升级武器法术伤害
返回的消息类
@Data
public class Result<T> {
private String code;
private String msg;
private T data;
public Result setCode(ResultCode resultCode) {
this.code = resultCode.code();
return this;
}
public Result setMsg(String msg) {
this.msg = msg;
return this;
}
public Result setData(T data) {
this.data = data;
return this;
}
}
第四步,提升武器等级
返回工具类
public class ResultGenerator {
private static final String DEFAULT_SUCCESS_MESSAGE = "成功";
public static Result getSuccessResult() {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMsg(DEFAULT_SUCCESS_MESSAGE);
}
public static <T> Result<T> getSuccessResult(T data) {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMsg(DEFAULT_SUCCESS_MESSAGE)
.setData(data);
}
public static Result getFailResult(String msg) {
return new Result()
.setCode(ResultCode.FAIL)
.setMsg(msg);
}
public static Result getErrorResult(String msg) {
return new Result()
.setCode(ResultCode.ERROR)
.setMsg(msg);
}
}
第五步,根据爱好自定义武器外观
自定义异常
public class ServiceException extends RuntimeException {
public ServiceException() {
}
public ServiceException(String message) {
super(message);
}
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
}
合成武器
使用WebMvcConfigurer拦截异常
public class WebMvcConfigurer extends WebMvcConfigurationSupport {
//统一异常处理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
exceptionResolvers.add(new HandlerExceptionResolver() {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
Result result = new Result();
if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误”
result.setCode(ResultCode.FAIL).setMsg(e.getMessage());
log.info(e.getMessage());
} else if (e instanceof NoHandlerFoundException) {
result.setCode(ResultCode.NOT_FOUND).setMsg("接口 [" + request.getRequestURI() + "] 不存在");
} else if (e instanceof ServletException) {
result.setCode(ResultCode.FAIL).setMsg(e.getMessage());
} else {
result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMsg("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员");
String message;
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s",
request.getRequestURI(),
handlerMethod.getBean().getClass().getName(),
handlerMethod.getMethod().getName(),
e.getMessage());
} else {
message = e.getMessage();
}
log.error(message, e);
}
responseResult(response, result);
return new ModelAndView();
}
});
}
private void responseResult(HttpServletResponse response, Result result) {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "application/json;charset=UTF-8");
response.setStatus(200);
try {
response.getWriter().write(JSON.toJSONString(result));
} catch (IOException ex) {
log.error(ex.getMessage());
}
}
}
开始战斗
@RestController
public class TestController {
@GetMapping("getString")
public Result getString(String name){
if(StringUtils.isEmpty(name)){
throw new ServiceException("参数为空");
}else if ("boss".equals(name)) {
// 这里没有查询操作,当请求参数是boss的时候,模拟成查询结果为空
throw new ServiceException("结果为空");
}
// 这里模拟一下除自定义异常外的其他异常
int i = 0;
i = 5/i;
return ResultGenerator.getFailResult("失败");
}
}
成功击杀
最后看效果,是不是很简单: