SpringMVC统一异常处理配置

全局异常处理还是基于AOP的思想,在SpringMVC中实现起来很简单,参照如下代码,其中的Resp是自定义的统一响应格式类,可自行设计,RespType是自定义的响应信息常量。
注意:异常捕获的顺序是按照定义的先后顺序来的,由上到下,所以应先定义细节异常。

/**
 * 统一异常处理
 */
@RestControllerAdvice
public class ControllerExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);

    /**
     * 400 - Bad Request 参数绑定出错
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BindException.class)
    public Resp<String> handleBindException(BindException e) {
        logger.error("绑定参数出错", e);
        return new Resp<String>().error(RespType.BIND_PARAM_ERROR);
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Resp<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("请求参数读取错误", e);
        return new Resp<String>().error(RespType.BAD_REQUEST);
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Resp<String> handleValidationException(MethodArgumentNotValidException e) {
        logger.error("请求参数验证失败", e);
        return new Resp<String>().error(RespType.BAD_REQUEST);
    }

    /**
     * 405 - Method Not Allowed。HttpRequestMethodNotSupportedException
     * 是ServletException的子类,需要Servlet API支持
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Resp<String> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.error("请求方法不支持", e);
        return new Resp<String>().error(RespType.METHOD_NOT_ALLOWED);
    }

    /**
     * 415 - Unsupported Media Type。HttpMediaTypeNotSupportedException
     * 是ServletException的子类,需要Servlet API支持
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public Resp<String> handleHttpMediaTypeNotSupportedException(Exception e) {
        logger.error("content-type类型不支持", e);
        return new Resp<String>().error(RespType.UNSUPPORTED_MEDIA_TYPE);
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Resp<String> handleException(Exception e) {
        logger.error("服务器内部错误", e);
        return new Resp<String>().error(RespType.INTERNAL_SERVER_ERROR);
    }
    
}

如果你使用了验证框架,还可用以下代码进行参数验证异常的处理:

 /**
     * 处理@Validated参数验证的异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ConstraintViolationException.class)
    public ApiResponse handleConstraintViolationException(ConstraintViolationException e) {
        log.error("参数验证出错", e);
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        StringBuilder stringBuilder = new StringBuilder();
        for (ConstraintViolation<?> violation : violations) {
            stringBuilder.append(violation.getMessage()).append(";");
        }
        return ApiResponse.error("400", stringBuilder.toString());
    }

    /**
     * 处理@Valid参数验证错误
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数验证出错", e);
        BindingResult result = e.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        for (ObjectError error : result.getAllErrors()) {
            stringBuilder.append(error.getDefaultMessage()).append(";");
        }
        return ApiResponse.error("400", stringBuilder.toString());
    }

总结

通过切面抓取到不同异常后,进行一系列的自定义处理,比如返回特定结构的提示信息,这样比起默认的返回内容,有更好的展现形式,使我们的接口更加优美。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值