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

时间:2012-07-26 14:12:17

标签: java web-services rest servlets http-headers

我有非常简单的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";
    }
}

部署后我执行: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

正如您所看到的,HTTP中的状态代码根本没有改变,尽管它是手动设置的。 为什么会这样?我花了很多时间用谷歌搜索没有任何结果。

返回Response对象的解决方法,如下所示:

Response.status(404).entity("Hello").build();

完美无缺!

Glassfish使用JERSEY作为JAX-RS实现。我使用的是Glassfish的嵌入式变体。

2 个答案:

答案 0 :(得分:3)

基本上,这不是你应该如何使用泽西岛。

以下是发生的事情:

  • 该方法执行,您与ServletResponse交互并将状态代码设置为500.但由于您没有写任何数据,因此未提交响应。

  • 然后该方法返回一个String值。由于泽西岛无法知道您是否与ServletResponse进行了互动,因此行为正常。

  • 返回的String方法意味着200响应代码(void表示204等)。 Jersey尝试将响应代码设置为默认值,最终通过在响应实例上调用setStatus(200)。由于响应尚未提交,因此这不是问题,500的响应更改为200.

  • HttpServletResponse已提交并发送回客户端。

我假设您要做的是返回不同的状态代码,但仅限于特殊情况。这样做的方法是在正常情况下返回一个String,然后在异常情况下抛出WebApplicationException

@GET
@Produces(MediaType.TEXT_HTML)
public String performFooCall() {
    if (isNormal()) {
        return "Hello";
    }
    throw new WebApplicationException(Response.status(500).entity("Hello").build());
}

或者,您可以抛出一个标准异常,并控制它作为具有单独ExceptionMapper的响应的呈现方式。

答案 1 :(得分:-1)

泽西岛建立一个新的响应,以便在您的代码中设置响应代码,稍后将覆盖。 您必须在代码中构建一个新的响应,并在响应中添加字符串(并更改其返回值),或者您可以创建一个过滤器,该过滤器稍后将在过滤器中进行操作并更改响应状态。

查看here了解更多详情