如何在 Android 中使用 HTTPClient 在 JSON 中发送 POST 请求?

我正在试图弄清楚如何使用 HTTPClient 从 Android 发布 JSON。我已经尝试了一段时间,我在网上找到了很多例子,但我不能让他们中的任何一个工作。我相信这是因为我缺乏一般的 JSON/网络知识。我知道这里有很多例子,但是谁能给我一个实际的教程?我正在寻找一个一步一步的过程与代码和解释为什么你做每一个步骤,或该步骤做什么。不需要太复杂,简单就够了。

同样,我知道这里有很多例子,我只是在寻找一个例子来解释到底发生了什么,为什么会这样。

如果有人知道一本关于这方面的好的 Android 书,请让我知道。

再次感谢这个 help@terrance,下面是我在下面描述的代码

public void shNameVerParams() throws Exception{
String path = //removed
HashMap  params = new HashMap();


params.put(new String("Name"), "Value");
params.put(new String("Name"), "Value");


try {
HttpClient.SendHttpPost(path, params);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
268609 次浏览

In this answer I am using an example posted by Justin Grammens.

About JSON

JSON stands for JavaScript Object Notation. In JavaScript properties can be referenced both like this object1.name and like this object['name'];. The example from the article uses this bit of JSON.

The Parts
A fan object with email as a key and foo@bar.com as a value

{
fan:
{
email : 'foo@bar.com'
}
}

So the object equivalent would be fan.email; or fan['email'];. Both would have the same value of 'foo@bar.com'.

About HttpClient Request

The following is what our author used to make a HttpClient Request. I do not claim to be an expert at all this so if anyone has a better way to word some of the terminology feel free.

public static HttpResponse makeRequest(String path, Map params) throws Exception
{
//instantiates httpclient to make request
DefaultHttpClient httpclient = new DefaultHttpClient();


//url with the post data
HttpPost httpost = new HttpPost(path);


//convert parameters into JSON object
JSONObject holder = getJsonObjectFromMap(params);


//passes the results to a string builder/entity
StringEntity se = new StringEntity(holder.toString());


//sets the post request as the resulting string
httpost.setEntity(se);
//sets a request header so the page receving the request
//will know what to do with it
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");


//Handles what is returned from the page
ResponseHandler responseHandler = new BasicResponseHandler();
return httpclient.execute(httpost, responseHandler);
}

Map

If you are not familiar with the Map data structure please take a look at the Java Map reference. In short, a map is similar to a dictionary or a hash.

private static JSONObject getJsonObjectFromMap(Map params) throws JSONException {


//all the passed parameters from the post request
//iterator used to loop through all the parameters
//passed in the post request
Iterator iter = params.entrySet().iterator();


//Stores JSON
JSONObject holder = new JSONObject();


//using the earlier example your first entry would get email
//and the inner while would get the value which would be 'foo@bar.com'
//{ fan: { email : 'foo@bar.com' } }


//While there is another entry
while (iter.hasNext())
{
//gets an entry in the params
Map.Entry pairs = (Map.Entry)iter.next();


//creates a key for Map
String key = (String)pairs.getKey();


//Create a new map
Map m = (Map)pairs.getValue();


//object for storing Json
JSONObject data = new JSONObject();


//gets the value
Iterator iter2 = m.entrySet().iterator();
while (iter2.hasNext())
{
Map.Entry pairs2 = (Map.Entry)iter2.next();
data.put((String)pairs2.getKey(), (String)pairs2.getValue());
}


//puts email and 'foo@bar.com'  together in map
holder.put(key, data);
}
return holder;
}

Please feel free to comment on any questions that arise about this post or if I have not made something clear or if I have not touched on something that your still confused about... etc whatever pops in your head really.

(I will take down if Justin Grammens does not approve. But if not then thanks Justin for being cool about it.)

Update

I just happend to get a comment about how to use the code and realized that there was a mistake in the return type. The method signature was set to return a string but in this case it wasnt returning anything. I changed the signature to HttpResponse and will refer you to this link on Getting Response Body of HttpResponse the path variable is the url and I updated to fix a mistake in the code.

Here is an alternative solution to @Terrance's answer. You can easly outsource the conversion. The Gson library does wonderful work converting various data structures into JSON and the other way around.

public static void execute() {
Map<String, String> comment = new HashMap<String, String>();
comment.put("subject", "Using the GSON library");
comment.put("message", "Using libraries is convenient.");
String json = new GsonBuilder().create().toJson(comment, Map.class);
makeRequest("http://192.168.0.1:3000/post/77/comments", json);
}


public static HttpResponse makeRequest(String uri, String json) {
try {
HttpPost httpPost = new HttpPost(uri);
httpPost.setEntity(new StringEntity(json));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
return new DefaultHttpClient().execute(httpPost);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

Similar can be done by using Jackson instead of Gson. I also recommend taking a look at Retrofit which hides a lot of this boilerplate code for you. For more experienced developers I recommend trying out RxAndroid.

Too much code for this task, checkout this library https://github.com/kodart/Httpzoid Is uses GSON internally and provides API that works with objects. All JSON details are hidden.

Http http = HttpFactory.create(context);
http.get("http://example.com/users")
.handler(new ResponseHandler<User[]>() {
@Override
public void success(User[] users, HttpResponse response) {
}
}).execute();

I recommend using this HttpURLConnectioninstead HttpGet. As HttpGet is already deprecated in Android API level 22.

HttpURLConnection httpcon;
String url = null;
String data = null;
String result = null;
try {
//Connect
httpcon = (HttpURLConnection) ((new URL (url).openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
httpcon.connect();


//Write
OutputStream os = httpcon.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(data);
writer.close();
os.close();


//Read
BufferedReader br = new BufferedReader(new InputStreamReader(httpcon.getInputStream(),"UTF-8"));


String line = null;
StringBuilder sb = new StringBuilder();


while ((line = br.readLine()) != null) {
sb.append(line);
}


br.close();
result = sb.toString();


} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

There are couple of ways to establish HHTP connection and fetch data from a RESTFULL web service. The most recent one is GSON. But before you proceed to GSON you must have some idea of the most traditional way of creating an HTTP Client and perform data communication with a remote server. I have mentioned both the methods to send POST & GET requests using HTTPClient.

/**
* This method is used to process GET requests to the server.
*
* @param url
* @return String
* @throws IOException
*/
public static String connect(String url) throws IOException {


HttpGet httpget = new HttpGet(url);
HttpResponse response;
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 60*1000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 60*1000;


HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
try {


response = httpclient.execute(httpget);


HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
//instream.close();
}
}
catch (ClientProtocolException e) {
Utilities.showDLog("connect","ClientProtocolException:-"+e);
} catch (IOException e) {
Utilities.showDLog("connect","IOException:-"+e);
}
return result;
}




/**
* This method is used to send POST requests to the server.
*
* @param URL
* @param paramenter
* @return result of server response
*/
static public String postHTPPRequest(String URL, String paramenter) {


HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 60*1000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 60*1000;


HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(URL);
httppost.setHeader("Content-Type", "application/json");
try {
if (paramenter != null) {
StringEntity tmp = null;
tmp = new StringEntity(paramenter, "UTF-8");
httppost.setEntity(tmp);
}
HttpResponse httpResponse = null;
httpResponse = httpclient.execute(httppost);
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream input = null;
input = entity.getContent();
String res = convertStreamToString(input);
return res;
}
}
catch (Exception e) {
System.out.print(e.toString());
}
return null;
}