Como enviar solicitação POST em JSON usando HTTPClient no Android?


111

Estou tentando descobrir como POST JSON do Android usando HTTPClient. Estou tentando descobrir isso há um tempo, encontrei muitos exemplos online, mas não consigo fazer nenhum deles funcionar. Acredito que isso seja devido à minha falta de conhecimento em JSON / redes em geral. Eu sei que há muitos exemplos por aí, mas alguém poderia me indicar um tutorial real? Estou procurando um processo passo a passo com código e explicação de por que você executa cada etapa ou o que essa etapa faz. Não precisa ser complicado, basta simples.

Novamente, eu sei que há uma tonelada de exemplos por aí, estou apenas procurando um exemplo com uma explicação do que exatamente está acontecendo e por que está acontecendo dessa maneira.

Se alguém souber de um bom livro Android sobre isso, por favor, me avise.

Obrigado novamente pela ajuda @terrance, aqui está o código que descrevi abaixo

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

Talvez você possa postar um dos exemplos que você não consegue fazer funcionar? Fazendo algo funcionar, você aprenderia como as peças se encaixam.
fredw

Respostas:


157

Nesta resposta, estou usando um exemplo postado por Justin Grammens .

Sobre JSON

JSON significa JavaScript Object Notation. Em JavaScript, as propriedades podem ser referenciadas assim object1.namee assim object['name'];. O exemplo do artigo usa esse bit de JSON.

As Partes
Um objeto de fã com e-mail como chave e foo@bar.com como valor

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

Portanto, o equivalente do objeto seria fan.email;ou fan['email'];. Ambos teriam o mesmo valor de 'foo@bar.com'.

Sobre a solicitação HttpClient

O seguinte é o que nosso autor usou para fazer uma solicitação HttpClient . Não tenho a pretensão de ser um especialista em tudo isso, então, se alguém tiver uma maneira melhor de redigir um pouco da terminologia, fique à vontade.

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

Mapa

Se você não estiver familiarizado com a Mapestrutura de dados, dê uma olhada na referência do mapa Java . Resumindo, um mapa é semelhante a um dicionário ou 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;
}

Sinta-se à vontade para comentar qualquer dúvida que surgir sobre este post ou se eu não tiver deixado algo claro ou se não toquei em algo que você ainda está confuso ... etc, o que realmente vier na sua cabeça.

(Vou retirar se Justin Grammens não aprovar. Mas, se não, agradeço a Justin por ser legal quanto a isso.)

Atualizar

Acabei de receber um comentário sobre como usar o código e percebi que havia um erro no tipo de retorno. A assinatura do método foi configurada para retornar uma string, mas neste caso não estava retornando nada. Alterei a assinatura para HttpResponse e irei encaminhá-lo a este link em Getting Response Body of HttpResponse, a variável de caminho é o url e atualizei para corrigir um erro no código.


Obrigado @Terrance. Então, em uma classe diferente, ele está criando um mapa que tem chaves e valores diferentes que mais tarde serão transformados em JSONObjects. Tentei implementar algo semelhante, mas também não tenho experiência com mapas, vou adicionar o código do que tentei implementar no meu post original. Suas explicações sobre o que estava acontecendo desde então, e eu tive sucesso em fazê-lo funcionar criando JSONObjects com nomes e valores codificados permanentemente. Obrigado!

Woot, que bom que pude ajudar.
Terrance

Justin diz que aprova. Ele deve ter reputação suficiente para vir e deixar um comentário para si mesmo agora.
Abizern

Eu quero usar este código. Como faço para fazer isso? Especifique qual é a variável de caminho e o que deve ser retornado para que no meu final de java eu ​​possa buscar os dados.
Prateek

3
Não há razão para getJsonObjectFromMap(): JSONObject tem um construtor que leva um Map: developer.android.com/reference/org/json/…
pr1001

41

Aqui está uma solução alternativa para a resposta de @Terrance. Você pode facilmente terceirizar a conversão. A biblioteca Gson faz um trabalho maravilhoso convertendo várias estruturas de dados em JSON e vice-versa.

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

Semelhante pode ser feito usando Jackson em vez de Gson. Eu também recomendo dar uma olhada em Retrofit, que esconde muito desse código clichê para você. Para desenvolvedores mais experientes, recomendo experimentar o RxAndroid .


meu aplicativo está enviando dados por meio do método HttpPut. quando o servidor recebe a solicitação, ele responde como dados json. Não sei como obter dados do JSON. por favor, diga. CODE .
kongkea

@kongkea Por favor, dê uma olhada na biblioteca GSON . Ele é capaz de analisar o arquivo JSON em objetos Java.
JJD

@JJD Até agora, o que você sugere é enviar dados para o servidor remoto e é uma boa explicação, mas quer saber como analisar o objeto JSON usando o protocolo HTTP. Você também pode elaborar sua resposta com a análise JSON. Será muito útil para todos os que são novos nisso.
AndroidDev

@AndroidDev Por favor, abra uma nova pergunta, pois esta pergunta é sobre o envio de dados do cliente para o servidor. Sinta-se à vontade para deixar um link aqui.
JJD de

@JJD você está chamando um método abstrato execute()e ele falhou, é claro
Konstantin Konopko

33

Eu recomendo usar esta HttpURLConnectionvez HttpGet. Como HttpGetjá está obsoleto na API Android de nível 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

Muito código para esta tarefa, verifique esta biblioteca https://github.com/kodart/Httpzoid Is usa GSON internamente e fornece API que funciona com objetos. Todos os detalhes JSON estão ocultos.

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

ótima solução, infelizmente, este plugin não tem suporte para gradle: /
electronix384128

3

Existem algumas maneiras de estabelecer uma conexão HHTP e buscar dados de um serviço da web RESTFULL. O mais recente é GSON. Mas antes de prosseguir para GSON, você deve ter uma ideia da maneira mais tradicional de criar um cliente HTTP e realizar a comunicação de dados com um servidor remoto. Mencionei os dois métodos para enviar solicitações POST e GET usando 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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.