我已经编写了一个实现ContainerRequestFilter和ContainerResponseFilter的类。在请求过滤器中,有一个身份验证检查,如果失败,它将使用ResponseBuilder构建401响应。
当我从客户端检查HTTP响应代码时(我已经用浏览器调试器和SoapUI进行了测试(,它是200而不是401。但响应主体是我设置的内容。我的调试日志和Jersey响应LoggerFeature都报告状态代码为401。令人困惑。
日志:
[2021-07-14 15:57:45.974][TRACE][] - [Entering filter response]
[2021-07-14 15:57:45.975][TRACE][] - [Response context org.glassfish.jersey.server.ContainerResponse@62e8911f]
[2021-07-14 15:57:45.976][TRACE][] - [Response status info 401 Unauthorized]
[2021-07-14 15:57:45.977][DEBUG][o.g.jersey.logging.LoggingFeature] - [4 * Server
responded with a response on thread http-nio-8180-exec-7
4 < 401
4 < Cache-Control: no-cache, no-store, no-transform
4 < Content-Encoding: ISO-8859-1
]
ResponseBuilder代码:
ResponseBuilder rb = Response
.status(Statuses.from(response.getStatus(), "TheStatus"))
.entity(response.getBodyContent())
.encoding(response.getCharacterEncoding())
.cacheControl(CC);
for (Cookie c : response.getCookies())
rb = rb.cookie(CookieConverter.toJaxRsNewCookie(c));
OutboundJaxrsResponse actualResponse = (OutboundJaxrsResponse) rb.build();
logger.trace("Actual response {}", actualResponse);
logger.trace("Status {}", actualResponse.getStatus());
logger.trace("Context {}", requestContext);
logger.trace("ResponseBuilder {}", rb);
requestContext.abortWith(actualResponse);
SoapUI(以及浏览器/调试器(显示了它接收到的内容:
HTTP/1.1 200
Set-Cookie: GWCHALLENGE=YES; Domain=.sand.idfconnect.lan; Path=/; HttpOnly
WWW-Authenticate: Basic realm="rm-gw"
Content-Length: 190
Date: Wed, 14 Jul 2021 19:57:45 GMT
Keep-Alive: timeout=20
Connection: keep-alive
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>401: Access Denied</TITLE>
</HEAD>
<BODY>
<h1>401: Access Denied</h1>
<br>
</BODY>
</HTML>
我一定是错过了什么。。。我试过2.29到2.33的球衣,差别是一样的。
非常感谢您的帮助!
根本原因是过滤器后面的特定服务在设置状态代码之前为响应主体编写HTML,这是错误的。一旦将某些内容写入响应主体,就无法更改状态代码。