大家好,并提前感谢您阅读本文(第一篇stackoverflow post..yaay ^^)
我正在尝试将带有JSON有效内容和cookie(包含身份验证信息)的POST请求发送到REST Web服务。 JavaEE-Server读取HttpServletRequest的InputStream,但缺少最后23个字节(即使它们在请求中)。服务器可以正常处理通过curl或Java RESTClient发送的请求(WizTools.org)
当查看发送的数据包时,我注意到读取inputStream时忽略的字节数与接受的Cookie的描述相同,即Cookie2:$ Version = 1 \ r \ n \ n
所以可能发生的事情是请求内容长度对于JSONdata(27字节)是正确的,但因为inputStream包含'Cookie2:$ Version = 1 \ r \ n'(23字节)只有4个字节在Reader退出之前读取JSON字符串。
现在问题:我无法摆脱CookiePolicy信息!
(使用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 wire logs 对我来说似乎没问题(虽然不知道围绕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有效载荷的一部分非常感谢=)
谢谢和最诚挚的问候, 扬
答案 0 :(得分:0)
HTTP消息头的长度(请求行或状态行加标题)和内容实体(正文)的长度完全无关。 Cookie2标头与您的问题无关。
您可以打开有线记录,查看HttpClient通过线路传输的HTTP消息的确切组成
答案 1 :(得分:0)
请求中的第一个EOL是问题,因为消息正文应该在请求的第一个空行之后开始。
知道这有助于我发现'creds'cookie的值以换行符结束。在创建Base64编码的字符串时使用标志NO_WRAP消除了问题。
感谢oleg帮我缩小问题范围。