我使用HttpClient
4.3.6来执行http GET和POST请求。现在我使用multipartentity以文件的形式发送一些字符串参数和图像。我能够成功发布数据,但是当我收到HTTP响应时,我的问题就出现了。响应包含json数据。
发生的是HTTP响应不完整,当我尝试用数据创建一个json对象时,我得到jsonexception错误说:
角色407处的未终止对象。
我注意到响应中不包含闭括号。这是Android上的问题还是应该检查服务器?因为我能够在邮递员和ios上正确地看到数据。我以前从未遇到过这个问题,也不知道如何解决这个问题。
这是我发布并获得回复的代码:
@Override
protected String doInBackground(String... params) {
try {
String url = params[0];
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
MultipartEntity entity = new MultipartEntity();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
ByteArrayBody bab = new ByteArrayBody(imageBytes, "image.jpg");
entity.addPart("image_data", bab);
entity.addPart("action", new StringBody("1", "text/plain", Charset.forName("UTF-8")));
entity.addPart("name", new StringBody("asdfg", "text/plain", Charset.forName("UTF-8")));
entity.addPart("user_id", new StringBody("157", "text/plain", Charset.forName("UTF-8")));
entity.addPart("birthday", new StringBody("18-04-1995", "text/plain", Charset.forName("UTF-8")));
entity.addPart("gender", new StringBody("male", "text/plain", Charset.forName("UTF-8")));
entity.addPart("is_jlpt_student", new StringBody(String.valueOf(0), "text/plain", Charset.forName("UTF-8")));
entity.addPart("relationship", new StringBody("Father", "text/plain", Charset.forName("UTF-8")));
entity.addPart("relationship_id", new StringBody(String.valueOf(10002), "text/plain", Charset.forName("UTF-8")));
entity.addPart("is_creator", new StringBody(String.valueOf(1), "text/plain", Charset.forName("UTF-8")));
entity.addPart("email", new StringBody(email, "text/plain", Charset.forName("UTF-8")));
httppost.setEntity(entity);
HttpResponse resp = httpclient.execute(httppost);
String response = EntityUtils.toString(resp.getEntity());
Log.i("HttpResponse", response);
return response;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute (String result) {
super.onPostExecute(result);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(result);
JSONObject json_data = jsonObject.getJSONObject("data");
String json_userid = json_data.getString("user_id");
String json_username = json_data.getString("name");
String json_email = json_data.getString("email");
String json_country = json_data.getString("country_code");
String json_imagefilename = json_data.getString("image_filename");
String json_imgurl = json_data.getString("image_url");
Toast.makeText(ParentGuardianProfile.this, "ImageFile " + json_imagefilename, Toast.LENGTH_SHORT).show();
User new_user = userdao.createUser(json_userid, json_username, json_email,json_imagefilename,json_country,selectedImageUri.toString(), 1);
Log.i("SQLITE", "added user : " + new_user.getmUserName() + new_user.getmId());
} catch (JSONException e) {
e.printStackTrace();
}
}
我的json回复是:
{"status":1,"message":"success","data":{"child_id":"381","name":"asdfg","image_filename":"C201603021734476.jpg","image_url":"https:\/\/innokid.blob.core.windows.net\/media\/child\/381.jpg","birthday":"18-04-1995","gender":"male","is_jltp_student":"0","relationship":"Father","relationship_id":"10002","is_creator":1,"rank":1,"qrcode_url":"http:\/\/innokid.azurewebsites.net\/uploads\/qrcode\/child_381.png"
我尝试使用此帖子String is being truncated when its too long中建议的字符串缓冲区。但我仍然得到相同的结果。
答案 0 :(得分:0)
乍一看代码看起来不错。 你怎么知道json数据被削减了? Logcat可以截断文本。在这种情况下,调试器应该更可靠。
尝试使用curl / SoapUI等工具生成相同的请求,并使用某些格式化程序/验证程序验证JSON(您可以轻松找到一些此类工具)。
这超出了问题范围,但使用原始的Android内置通信库似乎有点受虐狂。你有没有考虑过使用Retrofit?
答案 1 :(得分:0)
我认为此代码存在问题String response = EntityUtils.toString(resp.getEntity());
可能应该使用其他函数将响应转换为String ...
显然json缺少两个大括号'}}'最后,由于toString代码中的一些错误,可能会发生这种情况。
答案 2 :(得分:0)
我提取了一个使用@Query
内容的旧项目,下面就是我解析响应的方法。你可以看到它相当麻烦。有许多经过测试和维护的库,更适合这种繁重的工作。
org.apache.http
// Get hold of the response entity (-> the data):
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
instream = new GZIPInputStream(instream);
}
// Convert content stream to a String
resultString = convertStreamToString(instream);
instream.close();
// Do stuff with resultString here
// Consume Content
entity.consumeContent();
}
方法:
convertStreamToString()
答案 3 :(得分:0)
我终于通过用Android Asynchronous Http Client替换httpclient库来解决这个问题。现在它工作正常。非常感谢你的帮助! 但是,当我使用httpclient时,我仍然不明白为什么响应被截断了。