异常处理器与拦截器 深入探究 --拦截器状态码无法被识别

简介: 异常处理器与拦截器 深入探究 --拦截器状态码无法被识别

异常处理器与拦截器 深入探究 --拦截器状态码无法被识别


首先来阐述前景提要 我先是做了一个什么拦截器


下面是引用回我之前做过的思维导图 以及拦截器的实现

拦截器


那么前面发生了什么问题呢?


首先客户端的每一个请求都需要经过两个拦截器 然后报错的话直接返回

Java
@Slf4j
@RestControllerAdvice
public class WebExceptionAdvice {

@ExceptionHandler(RuntimeException.class)
public Result handleRuntimeException(RuntimeException e) {
log.error(e.toString(), e);
return Result.fail(“服务器异常”);
}
}

报错就直接报服务器异常了 虽然在拦截器2中也有设置状态码

Java
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.判断是否需要拦截(ThreadLocal中是否有用户)
if (UserHolder.getUser() == null&&ListenerHolder.getListener()==null) {
response.setStatus(10002);
System.out.println(“拦截器报错啦!!!”);
response.getHeader(“erro”);
return false;
}

return true;
}
}

但实际上 在支付宝小程序中这里的状态码却无法被识别 这是一个极其奇怪的事情 在前端看到的状态码是不一样的


后面发现在定义fail的时候就把外层的状态码给定死为了200!这是个极其不好的点 设计的时候贪图方便没有管他 导致了后面 实际发生异常跟没有登录的报错没办法区分开 于是 我做了以下的改进


首先是重写了 报错体系

Java
@Slf4j
@RestControllerAdvice
public class WebExceptionAdvice {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity handleRuntimeException(HttpServletRequest request, RuntimeException e) {
log.error(e.toString(), e);
Result result = Result.fail(“服务器异常”);
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
if (e instanceof UnAuthorException) {
//这个是拦截器报错才设置的状态码
status = HttpStatus.UNAUTHORIZED;
}
ResponseEntity resultResponseEntity = new ResponseEntity<>(result, status);
log.error(resultResponseEntity.toString());
return resultResponseEntity;
}
}

自己定义了一个特殊的错误类型 用到RuntimeException 下面是他的定义

Java
public class UnAuthorException extends RuntimeException {
public UnAuthorException(String message) {
super(message);
}
}//非常简单_

然后在合适的地方抛出他 当然是在拦截器中 表示用户未登录的时候 抛出这个自定义异常UnAuthorException

Java
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.判断是否需要拦截(ThreadLocal中是否有用户)
if (UserHolder.getUser() == null&&ListenerHolder.getListener()==null) {
System.out.println(“拦截器报错啦!!!”);
//response.getHeader(“erro”);
throw new UnAuthorException(“用户未登录”);
}
return true;
}
}

后面反思了一下为什么没被识别到状态码 因为在定义Result对象的时候 对于fail方法并没有重新定义他的状态码 这是个很大的问题 在下一个项目中不应该出现 应该提前定义好

相关文章
基于事件驱动构建 AI 原生应用
AI 应用在商业化服务的阶段会面临诸多挑战,比如更快的服务交付速度,更实时、精准的结果以及更人性化的体验等,传统架构限制于同步交互,无法满足上述需求,本篇文章给大家分享一下如何基于事件驱动架构应对上述挑战。
502 204
textarea文本框根据输入内容自动适应高度
textarea文本框根据输入内容自动适应高度
240 0
192Echarts - 自定义系列(Custom Calendar Icon)
192Echarts - 自定义系列(Custom Calendar Icon)
53 0
《云上业务稳定性保障实践白皮书》——三.故障管理体系——3.故障管理全流程——3.3.3 故障快恢
《云上业务稳定性保障实践白皮书》——三.故障管理体系——3.故障管理全流程——3.3.3 故障快恢
298 0
【AWS系列】boto3入门-下篇
下载文件和上传文件是对称的Client、Bucket、Object三个对象提供了、。是并行的,是串行的,这两个函数同样提供了ExtraArgs和Callback参数。描述了下载过程的ExtraArgs的可用参数。
1283 0
【AWS系列】boto3入门-下篇
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问