一个人调6个程序,不想调了。写一下如何实现个人的异常类。
1.首先继承RuntimeException
/**
* 业务逻辑异常 Exception
* @author
*/
public class ShishengException extends RuntimeException {
/**
* 业务错误码
*/
private Integer code;
/**
* 错误提示
*/
private String message;
/**
* 空构造方法,避免反序列化问题
*/
public ShishengException() {
}
public ShishengException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public ShishengException setCode(Integer code) {
this.code = code;
return this;
}
@Override
public String getMessage() {
return message;
}
public ShishengException setMessage(String message) {
this.message = message;
return this;
}
}
2.定义错误码和消息
当然这只是抛出了一个异常,但是你不知道如何自定义状态码和消息,那么就要在上面的类中增加这个方法
public ShishengException(ErrorCode errorCode) {
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
}
ErrorCode 非常必要的类,没有它我们就没有办法定义异常码和异常消息。
/**
* @Description * 错误码对象
* 全局错误码,占用 [0, 999],参见 {@GlobalErrorCodeConstants}
* 业务异常错误码,错误码和错误信息定义类
* - 1.错误码长度:5个数字
* - 2.前两位:业务场景
* - 3.后三位:错误码
*/
public class ErrorCode {
/**
* 错误码
*/
private final Integer code;
/**
* 错误提示
*/
private final String message;
public ErrorCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
全局错误码常量可以按以下方式写
public interface GlobalErrorCodeConstants {
ErrorCode SUCCESS = new ErrorCode(200, "请求成功");
// ========== 客户端错误段 ==========
ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
}
3.处理异常类
/**
* description : 全局异常处理器
*
* @author : shisheng
*/
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 方法入参支持:Exception、SessionAttribute、@RequestAttribute、HttpServletRequest、HttpServletResponse、HttpSession
* 方法返回支持: ModelAndView、@ResponseBody、ResponseEntity
*/
@ExceptionHandler(Throwable.class)
@ResponseBody
public Result<String> error(HttpServletResponse response, Exception e) {
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
ObjectMapper objectMapper = new ObjectMapper();
try {
response.getWriter().print(
objectMapper.writeValueAsString(ResultUtil.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), e.toString())));
} catch (IOException exc) {
log.error("全局异常捕获响应失败", exc);
}
return null;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public String handleMethodArgumentNotValid(HttpServletResponse response, Exception e) {
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
ObjectMapper objectMapper = new ObjectMapper();
MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
BindingResult bindingResult = ex.getBindingResult();
Map<String, Object> map = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
String field = error.getField();
String msg = error.getDefaultMessage();
map.put(field, msg);
}
try {
response.getWriter().print(objectMapper.writeValueAsString(
ResultUtil.of(RemoteCenterErrorCodeConstants.REQUEST_PARAMETERS_ERROR.getCode()
, RemoteCenterErrorCodeConstants.REQUEST_PARAMETERS_ERROR.getMessage(), map)));
} catch (IOException exc) {
log.error("统一参数异常处理响应失败", exc);
}
return null;
}
}
4.可能存在的问题
4.1 在非容器方法下@controlleradvice不会捕获到该异常
不是同一个线程,所以无法捕获该异常。