You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jersey JAX-RS过滤器设置401状态码但客户端实际收到200问题求助

问题根因与解决方案

排查方向0:排除中间链路篡改

先在部署Jersey服务的服务器本地抓包,确认服务端直接返回的响应状态码是多少:

  • 若本地抓包返回401,客户端收到200:说明是服务端和客户端之间的反向代理、WAF、负载均衡等中间设备修改了状态码,检查中间设备配置即可
  • 若本地抓包返回200:再按照下面的方向排查服务端逻辑

排查方向1:检查Web容器/框架的错误页配置

这是该现象最高发的原因:绝大多数Java Web容器(Tomcat、Jetty、Undertow)或集成框架(Spring Boot)如果配置了401状态码对应的错误页,容器会内部转发到错误页路径,转发过程默认会将响应状态码重置为200,仅保留错误页的响应体内容,完全匹配你遇到的现象。
解决步骤:

  • 检查项目中web.xml或者Spring Boot的server.error.*相关配置,是否配置了401对应的错误页映射
  • 若确实需要保留错误页配置,可在Jersey返回401响应时添加请求属性跳过容器错误页处理,以Tomcat+Spring Boot环境为例,添加如下代码:
// 跳过Tomcat默认错误页转发
requestContext.setProperty("org.apache.catalina.servlets.default.allowErrorPageRedirect", false);
// 清除Spring Boot错误页处理标记
requestContext.setProperty("javax.servlet.error.status_code", null);

排查方向2:检查响应过滤器的逻辑

你同时实现了ContainerRequestFilter和ContainerResponseFilter,请求过滤器调用abortWith返回响应后,响应过滤器仍然会被触发,若你在响应过滤器中存在未做判断的状态码覆盖逻辑,也可能导致状态码被篡改:

  • 检查你的ContainerResponseFilter#filter方法,是否没有判断当前响应是否为abort生成的异常响应,直接修改了状态码
  • 可在响应过滤器开头先打印当前响应状态码,确认是否是在响应过滤器执行阶段被修改

排查方向3:检查自定义Status类的兼容性

你代码中使用了自定义的Statuses.from()方法构造响应状态,若该类没有正确实现JAX-RS的Response.StatusType接口,可能导致底层容器解析状态码时出现异常,fallback为200:

  • 可以临时替换成Jersey自带的状态枚举验证:Response.status(Response.Status.UNAUTHORIZED),测试是否还会出现状态码异常
  • 检查你的Statuses.from返回的对象,getStatusCode()方法是否正确返回401,getFamily()方法是否返回Response.Status.Family.CLIENT_ERROR

排查方向4:检查过滤器链优先级

若你项目中还存在其他自定义的Servlet过滤器或Jersey过滤器,优先级比你的身份认证过滤器更高,也可能在后续流程中修改了响应状态码:

  • 给你的身份认证过滤器添加最高优先级的注解@Priority(Priorities.AUTHENTICATION),确保它是请求链中第一个执行的过滤器
  • 临时禁用其他所有自定义过滤器,验证问题是否消失

内容的提问来源于stack exchange,提问作者Richard Sand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 09:15:03