在 Android 中使用带有 post 参数的 HttpClient 和 HttpPost
Posted
技术标签:
【中文标题】在 Android 中使用带有 post 参数的 HttpClient 和 HttpPost【英文标题】:Using HttpClient and HttpPost in Android with post parameters 【发布时间】:2011-05-17 09:39:20 【问题描述】:我正在为一个 android 应用程序编写代码,该应用程序应该获取数据,将其打包为 Json 并将其发布到 Web 服务器,而 Web 服务器又应该使用 json 响应。
使用 GET 请求可以正常工作,但由于某种原因,使用 POST 似乎所有数据都被剥离并且服务器没有收到任何内容。
这是代码的sn-p:
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 5000);
DefaultHttpClient httpClient = new DefaultHttpClient(params);
BasicCookieStore cookieStore = new BasicCookieStore();
httpClient.setCookieStore(cookieStore);
String uri = JSON_ADDRESS;
String result = "";
String username = "user";
String apikey = "something";
String contentType = "application/json";
JSONObject jsonObj = new JSONObject();
try
jsonObj.put("username", username);
jsonObj.put("apikey", apikey);
catch (JSONException e)
Log.e(TAG, "JSONException: " + e);
HttpPost httpPost = new HttpPost(uri);
List<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new BasicNameValuePair("json", jsonObj.toString()));
HttpGet httpGet = null;
try
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postParams);
entity.setContentEncoding(HTTP.UTF_8);
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Content-Type", contentType);
httpPost.setHeader("Accept", contentType);
catch (UnsupportedEncodingException e)
Log.e(TAG, "UnsupportedEncodingException: " + e);
try
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null)
InputStream is = httpEntity.getContent();
result = StringUtils.convertStreamToString(is);
Log.i(TAG, "Result: " + result);
catch (ClientProtocolException e)
Log.e(TAG, "ClientProtocolException: " + e);
catch (IOException e)
Log.e(TAG, "IOException: " + e);
return result;
我认为我已遵循有关如何创建参数和发布参数的一般准则,但显然没有。
在这一点上,我非常欢迎任何帮助或指向我可以找到解决方案的指针(在花了几个小时后才意识到从未发送过任何帖子数据)。真正的服务器是在 Tomcat 上运行 Wicket,但我也在一个简单的 php 页面上对其进行了测试,没有任何区别。
【问题讨论】:
用解决方案更新(在这种特殊情况下至少对我有用):我删除了所有设置Content-Type
的方法调用和现在它可以工作了。在这种情况下,唯一允许的内容类型方法调用是 httpPost.setHeader("Accept", contentType);
。
这是因为 UrlEncodedFormEntity 将内容类型设置为 application/x-www-form-urlencoded。如果您将内容类型更改为其他内容(例如 application/json),服务器将无法解析您的请求参数。
【参考方案1】:
您实际上可以通过以下方式将其作为 JSON 发送:
// Build the JSON object to pass parameters
JSONObject jsonObj = new JSONObject();
jsonObj.put("username", username);
jsonObj.put("apikey", apikey);
// Create the POST object and add the parameters
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(jsonObj.toString(), HTTP.UTF_8);
entity.setContentType("application/json");
httpPost.setEntity(entity);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(httpPost);
【讨论】:
谢谢!使用 namevaluepairs 对我不起作用,但这恰到好处。 UrlEncodedFormEntity 和 StringEntity 有什么区别。服务器上是否需要不同的设置?何时使用 UrlEncodedFormEntity 以及何时使用 StringEntity? 此解决方案可能不适用于某些站点,因为较旧的站点不接受 json 作为发布请求有效负载类型。【参考方案2】:您是否尝试过不使用 JSON 对象并仅传递两个基本名称值对? 另外,它可能与您的服务器设置有关
更新: 这是我使用的一段代码:
InputStream is = null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("lastupdate", lastupdate));
try
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(connection);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Log.d("HTTP", "HTTP: OK");
catch (Exception e)
Log.e("HTTP", "Error in http connection " + e.toString());
【讨论】:
我尝试只传递两个BasicNameValuePairs
,但似乎仍然没有数据作为 POST 发送。难道请求是作为get发送的,因此服务器没有处理任何发布数据? HttpPost 应该确保不会发生这种情况,不是吗?
是的,这很像我最终得到的代码,在删除内容类型设置(我显然使用了太多)之后,正如我对原始帖子的评论中提到的那样。感谢您的帮助。【参考方案3】:
我刚刚检查过,我的代码和你一样,它工作得很好。 唯一的区别是我如何填写参数列表:
我使用的是:ArrayList<BasicNameValuePair> params
并以这种方式填写:
params.add(new BasicNameValuePair("apikey", apikey);
我不使用任何 JSONObject 将参数发送到网络服务。
您有义务使用 JSONObject 吗?
【讨论】:
由于我正在与一位 Iphone 开发人员并行工作,并且他的应用程序实际上会发布数据,因此我别无选择,只能将数据提交为 JSON。我尝试只发送两个值对,但没有区别。【参考方案4】:公共类 GetUsers 扩展 AsyncTask
@Override
protected void onPreExecute()
super.onPreExecute();
private String convertStreamToString(InputStream is)
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
catch (IOException e)
e.printStackTrace();
finally
try
is.close();
catch (IOException e)
e.printStackTrace();
return sb.toString();
public String connect()
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpPost htopost = new HttpPost("URL");
htopost.setHeader(new BasicHeader("Authorization","Basic Og=="));
try
JSONObject param = new JSONObject();
param.put("PageSize",100);
param.put("Userid",userId);
param.put("CurrentPage",1);
htopost.setEntity(new StringEntity(param.toString()));
// Execute the request
HttpResponse response;
response = httpclient.execute(htopost);
// Examine the response status
// Get hold of the response entity
HttpEntity entity = response.getEntity();
if (entity != null)
// A Simple JSON Response Read
InputStream instream = entity.getContent();
String result = convertStreamToString(instream);
// A Simple JSONObject Creation
json = new JSONArray(result);
// Closing the input stream will trigger connection release
instream.close();
return ""+response.getStatusLine().getStatusCode();
catch (Exception e)
e.printStackTrace();
return null;
@Override
protected String doInBackground(String... urls)
return connect();
@Override
protected void onPostExecute(String status)
try
if(status.equals("200"))
Global.defaultMoemntLsit.clear();
for (int i = 0; i < json.length(); i++)
JSONObject ojb = json.getJSONObject(i);
UserMomentModel u = new UserMomentModel();
u.setId(ojb.getString("Name"));
u.setUserId(ojb.getString("ID"));
Global.defaultMoemntLsit.add(u);
userAdapter = new UserAdapter(getActivity(), Global.defaultMoemntLsit);
recycleView.setAdapter(userMomentAdapter);
recycleView.setLayoutManager(mLayoutManager);
catch (Exception e)
e.printStackTrace();
【讨论】:
这段代码与问题有什么关系? edit你的答案并添加解释以上是关于在 Android 中使用带有 post 参数的 HttpClient 和 HttpPost的主要内容,如果未能解决你的问题,请参考以下文章
如何在android studio中通过带有密码的POST方法获取JSON数据
带有 CRUD/Rest 的 Alamofire POST 参数
如何发送带有 URL 参数和 JSON 正文的 POST? [关闭]