I'm trying to figure out how to POST JSON from Android by using HTTPClient. I've been trying to figure this out for a while, I have found plenty of examples online, but I cannot get any of them to work. I believe this is because of my lack of JSON/networking knowledge in general. I know there are plenty of examples out there but could someone point me to an actual tutorial? I'm looking for a step by step process with code and explanation of why you do each step, or of what that step does. It doesn't need to be a complicated, simple will suffice.
我正在尝试通过使用HTTPClient从Android上发布JSON。我已经试着弄明白这一点有一段时间了,我在网上找到了很多例子,但是我不能让它们中的任何一个发挥作用。我认为这是因为我缺乏一般的JSON/网络知识。我知道有很多例子,但是有人能给我指出一个实际的教程吗?我正在寻找一个循序渐进的过程,用代码解释为什么你要做每一步,或者这个步骤做什么。它不需要复杂,简单就够了。
Again, I know there are a ton of examples out there, I'm just really looking for an example with an explanation of what exactly is happening and why it is doing that way.
再说一次,我知道有很多例子,我只是想找一个例子来解释到底发生了什么,为什么会这样。
If someone knows about a good Android book on this, then please let me know.
如果有人知道一本关于Android的好书,请告诉我。
Thanks again for the help @terrance, here is the code I described below
再次感谢@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();
}
}
5 个解决方案
#1
157
In this answer I am using an example posted by Justin Grammens.
在这个答案中,我使用了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.
JSON表示JavaScript对象表示法。在JavaScript中,可以像object1.name和这个对象['name'];本文中的示例使用了这一点JSON。
The Parts
A fan object with email as a key and foo@bar.com as a value
这些部分是一个fan对象,邮件作为键,foo@bar.com作为值
{
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'
.
所以等价对象是fan。email;或风扇(“电子邮件”);。两者的值都是“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.
下面是我们的作者用于发出HttpClient请求的内容。我一点也不自称是专家,所以如果有人有更好的方式来表达某些术语,请放心。
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.
如果您不熟悉映射数据结构,请查看Java映射引用。简而言之,映射类似于字典或散列。
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.
我只是碰巧得到了关于如何使用代码的评论,并意识到返回类型中有一个错误。方法签名被设置为返回一个字符串,但是在本例中它没有返回任何内容。我将签名改为HttpResponse,并将此链接提交给HttpResponse的响应体,路径变量是url,我更新了,以修复代码中的错误。
#2
41
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.
下面是另一种解决方案,可以用@Terrance的答案。你可以很容易地将转换外包出去。Gson库出色地将各种数据结构转换为JSON,反之亦然。
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.
类似的方法可以用杰克逊代替Gson。我还建议您查看一下Retrofit,它为您隐藏了许多此类样板代码。对于更有经验的开发人员,我推荐试用RxAndroid。
#3
32
I recommend using this HttpURLConnection
instead HttpGet
. As HttpGet
is already deprecated in Android API level 22.
我建议使用httpurlconnection替代HttpGet。因为HttpGet在Android API级别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();
}
#4
5
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.
这个任务的代码太多了,请检查这个库https://github.com/ko达特/ httpzoid在内部使用GSON并提供与对象一起工作的API。所有JSON细节都是隐藏的。
Http http = HttpFactory.create(context);
http.get("http://example.com/users")
.handler(new ResponseHandler<User[]>() {
@Override
public void success(User[] users, HttpResponse response) {
}
}).execute();
#5
3
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.
有两种方法可以建立HHTP连接并从RESTFULL web服务中获取数据。最近的一个是GSON。但是在继续学习GSON之前,您必须了解创建HTTP客户机和与远程服务器执行数据通信的最传统方式。我已经提到了使用HTTPClient发送POST和GET请求的两种方法。
/**
* 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;
}
#1
157
In this answer I am using an example posted by Justin Grammens.
在这个答案中,我使用了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.
JSON表示JavaScript对象表示法。在JavaScript中,可以像object1.name和这个对象['name'];本文中的示例使用了这一点JSON。
The Parts
A fan object with email as a key and foo@bar.com as a value
这些部分是一个fan对象,邮件作为键,foo@bar.com作为值
{
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'
.
所以等价对象是fan。email;或风扇(“电子邮件”);。两者的值都是“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.
下面是我们的作者用于发出HttpClient请求的内容。我一点也不自称是专家,所以如果有人有更好的方式来表达某些术语,请放心。
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.
如果您不熟悉映射数据结构,请查看Java映射引用。简而言之,映射类似于字典或散列。
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.
我只是碰巧得到了关于如何使用代码的评论,并意识到返回类型中有一个错误。方法签名被设置为返回一个字符串,但是在本例中它没有返回任何内容。我将签名改为HttpResponse,并将此链接提交给HttpResponse的响应体,路径变量是url,我更新了,以修复代码中的错误。
#2
41
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.
下面是另一种解决方案,可以用@Terrance的答案。你可以很容易地将转换外包出去。Gson库出色地将各种数据结构转换为JSON,反之亦然。
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.
类似的方法可以用杰克逊代替Gson。我还建议您查看一下Retrofit,它为您隐藏了许多此类样板代码。对于更有经验的开发人员,我推荐试用RxAndroid。
#3
32
I recommend using this HttpURLConnection
instead HttpGet
. As HttpGet
is already deprecated in Android API level 22.
我建议使用httpurlconnection替代HttpGet。因为HttpGet在Android API级别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();
}
#4
5
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.
这个任务的代码太多了,请检查这个库https://github.com/ko达特/ httpzoid在内部使用GSON并提供与对象一起工作的API。所有JSON细节都是隐藏的。
Http http = HttpFactory.create(context);
http.get("http://example.com/users")
.handler(new ResponseHandler<User[]>() {
@Override
public void success(User[] users, HttpResponse response) {
}
}).execute();
#5
3
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.
有两种方法可以建立HHTP连接并从RESTFULL web服务中获取数据。最近的一个是GSON。但是在继续学习GSON之前,您必须了解创建HTTP客户机和与远程服务器执行数据通信的最传统方式。我已经提到了使用HTTPClient发送POST和GET请求的两种方法。
/**
* 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;
}