HTTPServletResponse状态代码不在HTTP响应头中 [英] HTTPServletResponse status code is not in HTTP response header

查看:471
本文介绍了HTTPServletResponse状态代码不在HTTP响应头中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有非常简单的JAX-RS WS:

I have pretty simple 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,
结果是:

After deployment I execute: curl -v localhost:8080/foo, the result was:

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中的状态代码根本没有改变,尽管它是手动设置的。
为什么会这样?我花了很多时间用谷歌搜索没有任何结果。

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.

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

Such workaround as returning Response object, something like this:

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

完美无缺!

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

Glassfish uses JERSEY as JAX-RS implementation. I use embedded variant of Glassfish.

推荐答案

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

Basically, that's not how you should use Jersey.

以下是发生的事情:


  • 该方法执行,您与ServletResponse交互并设置状态但是由于您没有写任何数据,因此不会提交响应。

  • 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.

然后该方法返回一个String值。由于Jersey无法知道您是否与ServletResponse进行了交互,因此它的行为正常。

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.

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

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.

HttpServletResponse已提交,被发送回客户端。

The HttpServletResponse is committed and is sent back to the client.

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

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.

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

或者,您可以抛出标准异常,并控制它的呈现方式单独的 ExceptionMapper 的回复。

Alternatively, you can throw a standard exception, and control how it is rendered as a response with a separate ExceptionMapper.

这篇关于HTTPServletResponse状态代码不在HTTP响应头中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆