Spring Boot简明教程--全局异常处理

实现思路

为了统一开发过程中的异常处理方式和返回值,需要为项目制定统一的全局异常处理。在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 codes = new HashMap<>();

    public Map getCodes() {
        return codes;
    }

    public void setCodes(Map 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 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 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 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 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;
    }
}

测试

你可能感兴趣的:(Spring Boot简明教程--全局异常处理)