Java Jersey ClientResponse从getClientResponseStatus返回错误的状态

时间:2014-10-08 15:52:19

标签: java junit jersey jersey-client

我觉得我在这里遗漏了一些东西。我有一个过滤器打印出我的服务器返回的信息,我报告我正在返回正确的响应(403)。我写了一个JUnit测试来验证这个逻辑,很多时候我报告的是200而不是403.奇怪的是我的服务器日志仍然显示我发送了403.泽西岛1.17中是否有一些我不知道的已知错误我需要升级才能解决?我现在不能真正升级,所以我希望我的逻辑中有一些错误。这是我的测试用例。

@Test
public void testIdsOwnedBySomeoneElse()
{
    final Login user1Cred = Logins.getInstance().getLogin(Logins.LoginType.User1);
    final Login user2Cred = Logins.getInstance().getLogin(Logins.LoginType.User2);
    final ServiceEndpointAuthenticated authUser1 = LoginHelper.Login(user1Cred);
    final ServiceEndpointAuthenticated authUser2 = LoginHelper.Login(user2Cred);

    // Create generic entry owned by user 1
    BigInteger user1Id = null;
    {
        final Object payload = endpoint.CreateEntity(authUser1.getUserId());
        final ClientResponse response = endpoint.Post(authUser1, payload);
        assertTrue(Status.OK == response.getClientResponseStatus());
        final byte[] data = Utilities.getBytes(response.getEntityInputStream());
        user1Id = endpoint.getEntityId(data);
    }

    // Using User2, try to use that id from user1!
    {
        // test 1
        final MyEndpointWrapper endpoint = new MyEndpointWrapper(user1Id, validId);
        final Object payload = endpoint.CreateEntity(authUser2.getUserId());
        final ClientResponse response = endpoint.Post(authUser2, payload);
        final Status status = response.getClientResponseStatus();
        System.out.println("Returned status = " + status);
        if (status != Status.FORBIDDEN)
        {
            byte[] data = Utilities.getBytes(response.getEntityInputStream());
            String toString = null;
            try
            {
                toString = new String(data, "UTF-8");
            }
            catch (UnsupportedEncodingException e)
            {
            }
            System.out.println("data: " + toString);
        }
        assertEquals("Status " + status + " is not forbidden!", Status.FORBIDDEN, status);
    }

    {
        // test 2
        final MyEndpointWrapper endpoint = new MyEndpointWrapper(validId, user1Id);
        final Object payload = endpoint.CreateEntity(authUser2.getUserId());
        final ClientResponse response = endpoint.Post(authUser2, payload);
        final Status status = response.getClientResponseStatus();
        System.out.println("Returned status = " + status);
        if (status != Status.FORBIDDEN)
        {
            int i = 9;
        }
        assertEquals("Status " + status + " is not forbidden!", Status.FORBIDDEN, status);
    }

    // Go ahead and delete this data for cleanup
    assertTrue(Status.OK == endpoint.Delete(authUser1, user1Id).getClientResponseStatus());
}

我的通用代码首先登录我们的服务器以获取信用。这些信誉是附加的"到WebResource,它在我构建请求时自动附加正确的标题。我首先创建一个实体,发布它,然后存储返回的id以供其他用户使用。我创建了另一个引用该违规ID的endpointwrapper,并尝试使用该id发布。服务器记录:

INFO: RESPONSE: 403 http://myendpoint MediaType:(application/json) Payload: 232 MyErrorMessage

我甚至可以打印出这条消息(如上图所示)!我不明白的部分是getClientResponseStatus回复给我了。为什么呢?

我的帖子代码如下:

@Override
public ClientResponse Post(ServiceEndpointAuthenticated endpoint, Object entity)
{
    MyUploadData uploadData = (MyUploadData)entity;
    return endpoint.getResourceBuilder("/myendpoint")
            .accept(MediaTypeExt.APPLICATION_JSON)
            .type(MediaTypeExt.APPLICATION_JSON)
            .post(ClientResponse.class, gson.toJson(uploadData));
}

[UPDATE] 我跑线捕获,实际上看到200被送回!这似乎是泽西服务器内部的东西。这就是我所看到的:

When working:
Request: 1099   17.021219000    127.0.0.1   127.0.0.1   HTTP    2214    POST /myEndpoint HTTP/1.1  (application/json)
Response: 1153  17.042535000    127.0.0.1   127.0.0.1   HTTP    628 HTTP/1.1 400 Bad Request  (application/json)

When not working:
Request: 1161   17.044313000    127.0.0.1   127.0.0.1   HTTP    250 POST /myEndpoint HTTP/1.1  (application/json)
Response: 1217  17.066059000    127.0.0.1   127.0.0.1   HTTP    412 HTTP/1.1 200 OK 

当它工作时,我在响应中看到我的正常标题(例如:Access-Control- *,Pragma no cache等)。当它没有工作时,我看不到任何标题,但我确实看到"转移编码:chunked"我的回复是我的错误消息,但我的回复代码是200.我在发送回复之前在服务器中添加了一个显式的Trace语句,以确保我发送的是正确的状态而且我是。

我可以允许分块转移,但我不能丢失我想要的http响应。

1 个答案:

答案 0 :(得分:0)

让其他人遇到类似的东西。挖掘后我终于找到了问题。我们的一些终端心跳加速。某些端点可能需要比预期更长的时间。为确保客户端不会过早断开连接,我们有一个附加到ServletOutputStream的组件。这会向客户端发送一个空间以保持连接的活动。

当抛出错误(由我们的新异常重映射器捕获)时,此保持活动组件未正确关闭。这导致泽西岛切换到分块模式。确保keep-alive组件正常关闭解决问题。