0

大家好,提前感谢您阅读本文(第一篇stackoverflow帖子..yaay ^^)

我正在尝试将带有 JSON 有效负载和 cookie(包含身份验证信息)的 POST 请求发送到 REST Web 服务。JavaEE-Server 读取 HttpServletRequest 的 InputStream 但最后 23 个字节丢失(即使它们在请求中)。服务器可以很好地处理通过 curl 或此Java RESTClient发送的请求(由 WizTools.org 提供)

在查看发送的数据包时,我注意到读取 inputStream 时忽略的字节数与接受的 Cookie 的描述相同的数据量,即 Cookie2: $Version=1\r\n

所以可能发生的是请求内容长度对于 JSONdata(27 字节)是正确的,但是因为 inputStream 包含 'Cookie2: $Version=1\r\n'(23 字节)只有 4 个字节的 JSON在 Reader 退出之前读取字符串。

现在的问题是:我无法摆脱 CookiePolicy 信息!

来自 AsyncTask 的 JavaCode:

(顺便说一句,使用 Cookie 的 GET 请求工作正常)

private void addCookieToClient(DefaultHttpClient httpClient){
    CookieStore cookieStore = new BasicCookieStore();
    BasicClientCookie cookie = new BasicClientCookie(JSONFactory.USER_CREDS, BobManager.getCreds());
    cookie.setDomain(domain);
    cookie.setPath("/");
    cookieStore.clear();
    cookieStore.addCookie(cookie);
    httpClient.setCookieStore(cookieStore);
}

@Override
protected JSONObject doInBackground(Object... params) {
    String uri = (String) params[0];

    JSONObject jerg = new JSONObject();
    String response;

    HttpClient httpClient = new DefaultHttpClient();
    ResponseHandler<String> responseHandler = new BasicResponseHandler();

    //GET if JSONRequest is null
    if(requestJSON==null){
        HttpGet httpGet = new HttpGet(uri);
        try {
            addCookieToClient((DefaultHttpClient)httpClient);
            response = httpClient.execute(httpGet,responseHandler);
            jerg = new JSONObject(response);
        } 
        //catching stuff  
        }finally{
            return jerg;
        }
    }
    //POST
    else{
        HttpPost postMethod = new HttpPost(uri);
        try {
            addCookieToClient((DefaultHttpClient)httpClient);
            StringEntity en = new StringEntity(requestJSON.toString(), HTTP.UTF_8);
            postMethod.setEntity(en);
            postMethod.setHeader("Content-Type", "application/json");
            postMethod.setHeader("Accept", "application/json");
            postMethod.setHeader("charset", HTTP.UTF_8);

            HttpResponse httpresponse = httpClient.execute(postMethod);
            String result = EntityUtils.toString(httpresponse.getEntity(), HTTP.UTF_8);
            jerg = new JSONObject(result);
        } 
        //catching stuff
        }finally{
            return jerg;
        }
    }
}

发送什么

wireshark将数据准确地显示并标记为 InputStream 返回的 JSON 有效负载,并且还显示请求中存在 JSON 的其余部分:

链接到图片

...对不起,没有足够的学分在这里发布照片^^

httpclient 线路日志对我来说似乎没问题(虽然不知道 Cookie2 参数周围的 [EndOfLines] 吗?!) - 感谢 oleg 的提示:

D/org.apache.http.wire: >> "POST /bob/srv/item/react HTTP/1.1[EOL]"
D/org.apache.http.wire: >> "Content-Type: application/json[EOL]"
D/org.apache.http.wire: >> "Accept: application/json[EOL]"
D/org.apache.http.wire: >> "charset: UTF-8[EOL]"
D/org.apache.http.wire: >> "Content-Length: 27[EOL]"
D/org.apache.http.wire: >> "Content-Encoding: UTF-8[EOL]"
D/org.apache.http.wire: >> "Host: 192.168.178.23:8080[EOL]"
D/org.apache.http.wire: >> "Connection: Keep-Alive[EOL]"
D/org.apache.http.wire: >> "User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)[EOL]"
D/org.apache.http.wire: >> "Cookie: creds=xxxxxxxxxxxxxxxx[\n]"
D/org.apache.http.wire: >> "[EOL]"
D/org.apache.http.wire: >> "Cookie2: $Version=1[EOL]"
D/org.apache.http.wire: >> "[EOL]"
D/org.apache.http.headers: >> POST /bob/srv/item/react HTTP/1.1
D/org.apache.http.headers: >> Content-Type: application/json
D/org.apache.http.headers: >> Accept: application/json
D/org.apache.http.headers: >> charset: UTF-8
D/org.apache.http.headers: >> Content-Length: 27
D/org.apache.http.headers: >> Content-Encoding: UTF-8
D/org.apache.http.headers: >> Host: 192.168.178.23:8080
D/org.apache.http.headers: >> Connection: Keep-Alive
D/org.apache.http.headers: >> User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
D/org.apache.http.headers: >> Cookie: creds=xxxxxxxxxxxxxxxx
D/org.apache.http.headers: >> Cookie2: $Version=1
D/org.apache.http.wire: >> "{"id":3,"answervalueint":4}"

我试图摆脱它

更改 cookie 策略的参数有效,但只会导致不同的内容影响假定的有效负载,并且偏移量不同于 23 字节,例如以下导致 2 字节偏移量(只有字符 '\r\n' 而不是 ' Cookie2: $Version=1\r\n' 干扰该设置):

httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);

删除参数不起作用,因为它默认为 'Cookie2: $Version=1\r\n'

httpClient.getParams().removeParameter(ClientPNames.COOKIE_POLICY);

我现在有一个非常肮脏的解决方法,但是非常感谢如何摆脱 CookiePolicy 信息或关于为什么像它是 JSON 有效负载的一部分那样处理它的信息 =)

谢谢和最好的问候,扬

4

2 回答 2

0

请求中的第一个 EOL 是问题,因为消息正文应该在请求的第一个空白行之后开始。

知道这一点帮助我发现'creds' cookie 的值以换行符结束。在创建 Base64 编码字符串时使用标志 NO_WRAP 消除了该问题。

感谢 oleg 帮助我缩小问题的范围。

于 2013-08-11T12:00:14.467 回答
0

HTTP 消息头(请求行或状态行加头)的长度与内容实体(正文)的长度完全不相关。Cookie2 标头与您的问题无关。

您可以打开线路日志记录以查看 HttpClient 通过线路传输的 HTTP 消息的确切组成

http://hc.apache.org/httpcomponents-client-ga/logging.html

于 2013-08-10T15:47:26.167 回答