简体   繁体   English

HTTPServletResponse状态代码不在HTTP响应标头中

[英]HTTPServletResponse status code is not in HTTP response header

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. 如您所见,尽管HTTP状态代码是手动设置的,但它根本没有改变。 Why does this happen? 为什么会这样? I've spent a lot of hours googling without any results. 我花了很多时间在Google搜索上没有任何结果。

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. Glassfish使用JERSEY作为JAX-RS实现。 I use embedded variant of Glassfish. 我使用Glassfish的嵌入式变体。

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. 该方法将执行,并且您与ServletResponse交互并将状态代码设置为500。但是由于您没有写入任何数据,因此不会提交响应。

  • Then the method returns a String value. 然后,该方法返回一个String值。 Since Jersey has no way of knowing if you've interacted with the ServletResponse or not, it behaves normally. 由于Jersey无法知道您是否已与ServletResponse进行交互,因此它的行为正常。

  • A String method that returns implies a 200 response code (void implies 204, etc). 返回的String方法表示200响应代码(无效表示204等)。 Jersey tries to set the response code to the default, ultimately by calling setStatus(200) on the response instance. Jersey尝试最终通过在响应实例上调用setStatus(200)来将响应代码设置为默认值。 Since the response hasn't been committed yet, this isn't a problem, and the response of 500 is changed to 200. 由于尚未提交响应,因此这不是问题,将响应500更改为200。

  • The HttpServletResponse is committed and is sent back to the client. 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 WebApplicationException in the exceptional case. 这样做的方法是在正常情况下返回String,然后在特殊情况下抛出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控制如何将其呈现为响应。

Jersey building a new response so setting the response code in your code, is override later. Jersey建立了新的响应,因此稍后在代码中设置响应代码。 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. 您必须在代码中构建一个新的响应,然后在响应中添加字符串(并更改其返回值),或者您可以创建一个过滤器,该过滤器稍后将在过滤器跟踪中工作并更改响应状态。

look here for more details 在这里查看更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM