java HTTPServletResponse 状态码不在 HTTP 响应头中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11671190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTTPServletResponse status code is not in HTTP response header
提问by Steve
I have pretty simple JAX-RS WS:
我有非常简单的 JAX-RS WS:
@Stateless
@Path("/foo")
public class FooFacadeBean {
@GET
@Produces(MediaType.TEXT_HTML)
public String performFooCall(@Context HttpServletRequest request, @Context HttpServletResponse response) {
response.setStatus(500);
return "Hello";
}
}
After deployment I execute: curl -v localhost:8080/foo, the result was:
部署后我执行:curl -v localhost:8080/foo,结果是:
About to connect() to localhost port 8080
Trying 127.0.0.1...
connected
Connected to localhost (127.0.0.1) port 8080
GET /foo HTTP/1.1
User-Agent: curl/7.26.0
Host: localhost:8080
Accept: */
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2 Java/Sun Microsystems Inc./1.6)
Server: GlassFish Server Open Source Edition 3.1.2
Content-Type: text/html
Transfer-Encoding: chunked
Date: Thu, 26 Jul 2012 13:52:10 GMT
Hello
Connection to host localhost left intact
Closing connection
As you can see status code in HTTP hasn't changed at all, despite of it was set manually. Why does this happen? I've spent a lot of hours googling without any results.
正如您所看到的,HTTP 中的状态代码根本没有改变,尽管它是手动设置的。为什么会发生这种情况?我花了很多时间在谷歌上搜索,但没有任何结果。
Such workaround as returning Response object, something like this:
诸如返回 Response 对象之类的解决方法,如下所示:
Response.status(404).entity("Hello").build();
works perfectly!
完美运行!
Glassfish uses JERSEY as JAX-RS implementation. I use embedded variant of Glassfish.
Glassfish 使用 JERSEY 作为 JAX-RS 实现。我使用 Glassfish 的嵌入式变体。
回答by Sean Reilly
Basically, that's not how you should use Jersey.
基本上,这不是您应该使用 Jersey 的方式。
Here's what's happening:
这是发生了什么:
The method executes, and you interact with the ServletResponse and set the status code to 500. But since you don't write any data, the response isn't committed.
Then the method returns a String value. Since Jersey has no way of knowing if you've interacted with the ServletResponse or not, it behaves normally.
A String method that returns implies a 200 response code (void implies 204, etc). Jersey tries to set the response code to the default, ultimately by calling
setStatus(200)
on the response instance. Since the response hasn't been committed yet, this isn't a problem, and the response of 500 is changed to 200.The HttpServletResponse is committed and is sent back to the client.
该方法执行,您与 ServletResponse 交互并将状态代码设置为 500。但由于您没有写入任何数据,因此不会提交响应。
然后该方法返回一个字符串值。由于 Jersey 无法知道您是否已与 ServletResponse 交互,因此它的行为正常。
返回的 String 方法意味着 200 响应代码(void 意味着 204 等)。Jersey 尝试将响应代码设置为默认值,最终通过调用
setStatus(200)
响应实例。由于还没有提交响应,所以这不是问题,500的响应改为200。HttpServletResponse 被提交并被发送回客户端。
I'm assuming that what you want to do is return a different status code, but in an exceptional case only. The way to do that is to return a String in the normal case, and then throw a WebApplicationExceptionin the exceptional case.
我假设您想要做的是返回不同的状态代码,但仅在特殊情况下。这样做的方法是在正常情况下返回一个字符串,然后在异常情况下抛出一个WebApplicationException。
@GET
@Produces(MediaType.TEXT_HTML)
public String performFooCall() {
if (isNormal()) {
return "Hello";
}
throw new WebApplicationException(Response.status(500).entity("Hello").build());
}
Alternatively, you can throw a standard exception, and control how it is rendered as a response with a separate ExceptionMapper.
或者,您可以抛出标准异常,并使用单独的ExceptionMapper控制如何将其呈现为响应。
回答by shem
Jersey building a new response so setting the response code in your code, is override later. You have to build a new response in your code and put you string in the response (and change your return value for that), or you can create a filter that will work later on in the filter chaing and change the response status.
Jersey 构建一个新的响应,因此在您的代码中设置响应代码,稍后会被覆盖。您必须在您的代码中构建一个新的响应并将您的字符串放入响应中(并为此更改您的返回值),或者您可以创建一个过滤器,该过滤器稍后将在过滤器链中工作并更改响应状态。
look herefor more details
看这里了解更多详情