Spring Boot简明教程--全局异常处理
2021-01-24 本文已影响0人
听城
实现思路
为了统一开发过程中的异常处理方式和返回值,需要为项目制定统一的全局异常处理。在SpringBoot中全局异常处理通过@ControllerAdvice注解以及 @ExceptionHandler注解来实现,前者是用来开启全局的异常捕获,后者则是说明捕获哪些异常,对哪些异常进行处理。
要求
- 实现Restful请求异常返回,不同错误对应不同的错误码返回前端
- 定义标准的HTTP异常类,资源请求过程中的错误均继承自该类
- 定义统一的异常处理类,方便处理各类异常
统一异常返回类
@Getter
@Setter
public class UnifyResponse {
private int code;
private String message;
private String request;
public UnifyResponse(int code, String message, String request) {
this.code = code;
this.message = message;
this.request = request;
}
}
异常返回code码配置文件
在resource/config目录下创建exception-code.properties
zp.codes.9999 = 通用异常
zp.codes.10001 = 参数异常
zp.codes.10002 = 到当地的
异常返回code码配置类
@ConfigurationProperties(prefix = "zp")
@PropertySource(value = "classpath:config/exception-code.properties")
@Component
public class ExceptionCodeConfiguration {
private Map<Integer, String> codes = new HashMap<>();
public Map<Integer, String> getCodes() {
return codes;
}
public void setCodes(Map<Integer, String> codes) {
this.codes = codes;
}
public String getMessage(int code){
String message = codes.get(code);
return message;
}
}
统一异常处理类
统一异常处理类上一定要打上@ControllerAdvice注解,在类中配合@ExceptionHandler注解绑定不同的异常处理方式,注意使用@ResponseBody注解返回json对象。
@RequiredArgsConstructor
@ControllerAdvice
public class GlobalExceptionAdvice {
private final ExceptionCodeConfiguration codeConfiguration;
@ExceptionHandler(value = Exception.class)
@ResponseBody
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
public UnifyResponse handleException(HttpServletRequest request, Exception e){
String reqUrl = request.getRequestURI();
String method = request.getMethod();
UnifyResponse response = new UnifyResponse(9999,codeConfiguration.getMessage(9999),method + " " + reqUrl);
return response;
}
@ExceptionHandler(value = HttpException.class)
public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest request, HttpException e){
String reqUrl = request.getRequestURI();
String method = request.getMethod();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
UnifyResponse message = new UnifyResponse(e.getCode(),codeConfiguration.getMessage(e.getCode()),method + " " + reqUrl);
ResponseEntity<UnifyResponse> r = new ResponseEntity<>(message,headers,httpStatus);
return r;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public UnifyResponse handleBeanValidation(HttpServletRequest req, MethodArgumentNotValidException e) {
String requestUrl = req.getRequestURI();
String method = req.getMethod();
List<ObjectError> errors = e.getBindingResult().getAllErrors();
String message = this.formatAllErrorMessages(errors);
return new UnifyResponse(10001, message,method + " " + requestUrl);
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(code= HttpStatus.BAD_REQUEST)
@ResponseBody
public UnifyResponse handleConstraintException(HttpServletRequest req, ConstraintViolationException e){
String requestUrl = req.getRequestURI();
String method = req.getMethod();
String message = e.getMessage();
return new UnifyResponse(10001, message, method + " " + requestUrl);
}
private String formatAllErrorMessages(List<ObjectError> errors) {
StringBuffer errorMsg = new StringBuffer();
errors.forEach(error ->
errorMsg.append(error.getDefaultMessage()).append(';')
);
return errorMsg.toString();
}
}
定义HTTP异常类
public class HttpException extends RuntimeException{
protected Integer code;
protected Integer httpStatusCode = 500;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public Integer getHttpStatusCode() {
return httpStatusCode;
}
public void setHttpStatusCode(Integer httpStatusCode) {
this.httpStatusCode = httpStatusCode;
}
}
定义HTTP异常类继承类
public class NotFoundException extends HttpException{
public NotFoundException(int code){
this.httpStatusCode = 404;
this.code = code;
}
}