浅析如何自定义Java异常类且修改返回http状态码及解决状态码始终是200的问题和303状态码理解

1、问题背景:

  有个业务限制普通用户浏览文章数单日最多80,故我们需要自定义一个异常类。我们之前有自定义内容不存在的404资源异常类,可以参考编写

// 1、使用处,抛出自定义异常类
// 限制普通用户当天最多只能看80篇文章
if (isEsUser) {
  int viewOneDay = knowledgeDao.getViewOneDay(UserUtils.getCurrentUserId());
  if (viewOneDay > 80) {
    throw new KnowledgeLimitExceedException();
  }
}

// 2、声明自定义异常类
public class EmcsKnowledgeLimitExceedException extends CustomException {
    public KnowledgeLimitExceedException() {
        super("文章浏览超出当日限制", HttpStatus.RESET_CONTENT);
    }
}

// 3、继承至自定义的公共异常类,下面就是2个方法重载咯
@EqualsAndHashCode(callSuper = true)
@Data
public class CustomException extends RuntimeException {
    //异常信息
    private String message;
    private String code;
    private HttpStatus status;
    private Object data;

    public CustomException(String message) {
        super(message);
        this.message = message;
    }
    public EmcsCustomException(String message, HttpStatus status) {
        super(message);
        this.message = message;
        this.status = status;
    }
}

  然后运行,发现接口是报了异常,但是返回的http code却不是设定的HttpStatus.RESET_CONTENT,而始终是200

2、问题发现:ResponseBodyAdvice 的全局处理

  这是2个全局结果捕获,最后走异常都会全局捕获到这个类 ResponseBodyAdvice 里去处理,这里面有对我自定义的继承类 CustomException 的处理,但是没有对自定义的 EmcsKnowledgeLimitExceedException 的处理

    @ExceptionHandler(CustomException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public OperationInfo emcsCustomException(HttpServletRequest request, HttpServletResponse response, EmcsCustomException ex) {
        log.info("{}, {}, {}", request.getRequestURI(), ex.getMessage(), LogUtil.getStack(ex));
        OperationInfo info = OperationInfo.failure(ex.getMessage(), ex.getData());
        info.setOperateCode(ex.getCode());
        return info;
    }

  所以原因就清楚了,是在 ResponseBodyAdvice 的全局处理里又将http code变成了HttpStatus.OK即200

  所以解决也很简单了,加上对自定义的异常类EmcsKnowledgeLimitExceedException的捕获即可

    @ExceptionHandler(EmcsKnowledgeLimitExceedException.class)
    @ResponseStatus(HttpStatus.RESET_CONTENT)
    public void knowledgeLimitExceedException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        log.info("{}, 文章浏览超出当日限制,{}", request.getRequestURI(), LogUtil.getStack(ex));
    }

  这样就可以咯

3、扩展了解:http code 303状态码理解

  起初我用的 HttpStatus 里的 SEE_OTHER(303, "See Other"),结果就是前端请求里 303 的请求都没有任何返回,ajax 里也不好做业务处理,比如像下面这样,你会发现这里并不会生效,而是直接在控制台就报了 303 的错误

} else if (data.status === 303) {
  router.push('/limit')
}

  303 See Other。通常是指所请求的资源在别的地方,并且同302一样,会在header中的location标明资源的位置。

  Http Status Code 303 状态是HTTP协议的一种响应码,是我们请求访问网站时,服务器端返回的3xx 重定向状态系列响应码之一

posted @ 2017-06-15 10:24  古兰精  阅读(3295)  评论(0编辑  收藏  举报