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


111

我试图弄清楚如何通过使用HTTPClient从Android发布JSON。我已经尝试解决了一段时间,我在网上找到了很多示例,但我无法使用其中的任何示例。我认为这是因为我总体上缺乏JSON /网络知识。我知道那里有很多示例,但是有人可以指出我的实际教程吗?我正在寻找包含代码的逐步过程,并解释为什么您执行每个步骤或该步骤执行的操作。不需要很复杂,简单就足够了。

再说一次,我知道那里有很多例子,我只是在寻找一个例子,解释一下到底发生了什么以及为什么这样做。

如果有人知道一本关于Android的好书,那么请告诉我。

再次感谢@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();
    }
 }

也许您可以发布一个您无法使用的示例之一?通过使某些东西起作用,您将了解各个部分如何组合在一起。
fredw 2011年

Answers:


157

在这个答案中,我使用Justin Grammens发布的示例

关于JSON

JSON代表JavaScript对象符号。在JavaScript中,可以像这样object1.name和这样 引用属性object['name'];。本文中的示例使用了这部分JSON。

零件
A风扇对象,电子邮件为键,foo@bar.com为值

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

因此,等效对象为fan.email;fan['email'];。两者的值相同'foo@bar.com'

关于HttpClient请求

以下是我们的作者用来发出HttpClient Request的内容。我并不声称自己是专家,因此,如果有人有更好的措词来表达某些术语,您就可以放心了。

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数据结构,请查看Java Map参考。简而言之,地图类似于字典或哈希。

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;
}

请随意评论有关此帖子的任何问题,或者如果我没有说清楚什么,或者如果我还没有谈过您仍然感到困惑的事情……等等,那么您的脑海中突然浮现。

(如果贾斯汀·格莱门斯(Justin Grammens)不赞成,我将表示反对。但如果不接受,则感谢贾斯汀对此事的冷静。)

更新资料

我刚巧对如何使用代码发表评论,并意识到返回类型有误。方法签名设置为返回字符串,但在这种情况下,它未返回任何内容。我将签名更改为HttpResponse,并将把您引向HttpResponse获取响应正文上的此链接,路径变量为url,我进行了更新以修复代码中的错误。


谢谢@Terrance。因此,在不同的类中,他正在创建具有不同键和值的映射,这些映射和值随后将转换为JSONObjects。我尝试实现类似的东西,但是我也没有使用地图的经验,我会将尝试实现的代码添加到原始帖子中。从那时起,您对发生的事情进行了解释,通过创建带有硬编码名称和值的JSONObject,我成功地使它起作用。谢谢!

哇,很高兴我能帮上忙。
Terrance

贾斯汀说他批准。他现在应该有足够的代表来发表自己的意见。
阿比森2011年

我想使用此代码。我该怎么办?请指定什么是路径变量以及必须返回什么,以便在Java端可以获取数据。
Prateek

3
没有理由为getJsonObjectFromMap():JSONObject的有一个构造函数一个Mapdeveloper.android.com/reference/org/json/...
pr1001

41

这是@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;
}

通过使用Jackson而不是Gson 可以完成类似的操作。我还建议您看一下Retrofit,它为您隐藏了很多样板代码。对于经验丰富的开发人员,我建议尝试RxAndroid


我的应用程序通过HttpPut方法发送数据。当服务器收到请求时,它将作为json数据进行回复。我不知道如何从json获取数据。请告诉我。代码
kongkea 2013年

@kongkea请访问GSON库。它能够将JSON文件解析为Java对象。
JJD

@JJD到目前为止,您的建议是将数据发送到远程服务器,这是一个很好的解释,但是想知道如何使用HTTP协议解析JSON对象。您是否还可以使用JSON解析来详细说明您的答案。这将对每个新手都非常有帮助。
AndroidDev 2014年

@AndroidDev,因为这个问题是关于将数据从客户端发送到服务器的,所以请打开一个新问题。请随意在此处删除链接。
JJD 2014年

@JJD您正在调用抽象方法execute(),它当然失败了
Konstantin Konopko 2014年

33

我建议使用这个HttpURLConnection代替HttpGet。正如HttpGetAndroid 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();
} 

5

此任务的代码太多,请签出该库https://github.com/kodart/Httpzoid Is在内部使用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();

很好的解决方案,不幸的是,该插件缺少gradle支持:/
electronicix384128

3

建立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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.