Java: envío de parámetros HTTP a través del método POST fácilmente

319

Estoy usando este código con éxito para enviar HTTPsolicitudes con algunos parámetros a través del GETmétodo

void sendRequest(String request)
{
    // i.e.: request = "http://example.com/index.php?param1=a&param2=b&param3=c";
    URL url = new URL(request); 
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();           
    connection.setDoOutput(true); 
    connection.setInstanceFollowRedirects(false); 
    connection.setRequestMethod("GET"); 
    connection.setRequestProperty("Content-Type", "text/plain"); 
    connection.setRequestProperty("charset", "utf-8");
    connection.connect();
}

Ahora es posible que deba enviar los parámetros (es decir, param1, param2, param3) a través del POSTmétodo porque son muy largos. Estaba pensando en agregar un parámetro adicional a ese método (es decir, String httpMethod).

¿Cómo puedo cambiar el código anterior lo menos posible para poder enviar parámetros a través de GETo POST?

Esperaba que eso cambiara

connection.setRequestMethod("GET");

a

connection.setRequestMethod("POST");

habría hecho el truco, pero los parámetros aún se envían a través del método GET.

¿ HttpURLConnectionTiene algún método que pueda ayudar? ¿Hay alguna construcción útil de Java?

Cualquier ayuda sería muy apreciada.

dan
fuente
Los parámetros de publicación se envían dentro de la sección del encabezado http, no en la URL. (la URL de tu publicación sería http://example.com/index.php)
dacwe
2
no hay un método setRequestMethod definido en Java 1.6: docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html
ante.sabo
2
Envíalo a Http (s) UrlConnection ....
Peter Kriens
extendiendo la pregunta! ¿Alguien tiene alguna idea de cómo enviar un archivo adjunto como parámetro de publicación ...
therealprashant
1
¿Por qué el primer fragmento de código comienza con la palabra clave "función"?
Llew Vallis

Respuestas:

470

En una solicitud GET, los parámetros se envían como parte de la URL.

En una solicitud POST, los parámetros se envían como un cuerpo de la solicitud, después de los encabezados.

Para hacer una POST con HttpURLConnection, debe escribir los parámetros en la conexión después de haberla abierto.

Este código debería ayudarlo a comenzar:

String urlParameters  = "param1=a&param2=b&param3=c";
byte[] postData       = urlParameters.getBytes( StandardCharsets.UTF_8 );
int    postDataLength = postData.length;
String request        = "http://example.com/index.php";
URL    url            = new URL( request );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();           
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded"); 
conn.setRequestProperty( "charset", "utf-8");
conn.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
conn.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( conn.getOutputStream())) {
   wr.write( postData );
}
Alan Geleynse
fuente
40
@Alan Geleynse: 'url.openconnection ()' no abre la conexión. En caso de que no especifique una instrucción connect (), la conexión se abre cuando escribe en el cuerpo / solicitud de la solicitud http y la envía. He intentado esto con certificados. El protocolo de enlace SSL solo se realiza después de llamar a connect o cuando envía datos al servidor.
Ashwin
14
getBytes () usa el conjunto de caracteres predeterminado del entorno, NO UTF-8 charset = utf-8 debe seguir el tipo de contenido: application / x-www-form-urlencoded; charset = utf-8 Realiza la conversión de bytes dos veces en el ejemplo. Debe hacer: byte [] data = urlParameters.getData ("UTF-8"); connection.getOutputStream (). write (data); inútil cerrar, enjuagar y desconectar
Peter Kriens
8
@ PeterKriens Gracias por tu incorporación, creo que quisiste decir byte[] data = urlParameters.getBytes(Charset.forName("UTF-8")):).
gerrytan
77
@AlanGeleynse No te pierdas wr.flush (); y wr.close (); ¿al final?
Confile
99
¿Cómo es que esto tiene tantos votos a favor, si no funciona? Debe llamar conn.getResponseCode()o de lo conn.getInputStream()contrario no enviará ningún dato.
Imaskar
229

Aquí hay un ejemplo simple que envía un formulario y luego voltea la página de resultados System.out. Cambie la URL y los parámetros POST según corresponda, por supuesto:

import java.io.*;
import java.net.*;
import java.util.*;

class Test {
    public static void main(String[] args) throws Exception {
        URL url = new URL("http://example.net/new-message.php");
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("name", "Freddie the Fish");
        params.put("email", "[email protected]");
        params.put("reply_to_thread", 10394);
        params.put("message", "Shark attacks in Botany Bay have gotten out of control. We need more defensive dolphins to protect the schools here, but Mayor Porpoise is too busy stuffing his snout with lobsters. He's so shellfish.");

        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String,Object> param : params.entrySet()) {
            if (postData.length() != 0) postData.append('&');
            postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");

        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
        conn.setDoOutput(true);
        conn.getOutputStream().write(postDataBytes);

        Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

        for (int c; (c = in.read()) >= 0;)
            System.out.print((char)c);
    }
}

Si desea que el resultado se Stringimprima directamente en lugar de hacerlo:

        StringBuilder sb = new StringBuilder();
        for (int c; (c = in.read()) >= 0;)
            sb.append((char)c);
        String response = sb.toString();
Boann
fuente
Esta es la mejor respuesta, ya que incluye la codificación de parámetros y el uso de Map.
Airy el
44
Desafortunadamente, este código supone que la codificación del contenido es UTF-8, lo cual no siempre es el caso. Para recuperar el juego de caracteres, uno debe obtener el encabezado Content-Typey analizar el juego de caracteres de eso. Cuando esa cabecera no está disponible, utilice el estándar http: ISO-8859-1.
engineeringcoding
@Aprel IFTFY ... usar expresiones con efectos secundarios en las evaluaciones es realmente feo.
1
Por desgracia para @engineercoding HTML es aún más difícil que hacerlo completamente correcta, ya que también podría ser una lista de materiales Unicode, o una <meta charset="...">o <meta http-equiv="Content-Type" content="...">cabecera dentro del documento que se deben analizar.
Boann
1
@Nepster No hagas eso. response += line;es fenomenalmente lento y come saltos de línea. Agregué a la respuesta un ejemplo de cómo obtener una respuesta de cadena.
Boann
63

No pude obtener el ejemplo de Alan para hacer la publicación, así que terminé con esto:

String urlParameters = "param1=a&param2=b&param3=c";
URL url = new URL("http://example.com/index.php");
URLConnection conn = url.openConnection();

conn.setDoOutput(true);

OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());

writer.write(urlParameters);
writer.flush();

String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

while ((line = reader.readLine()) != null) {
    System.out.println(line);
}
writer.close();
reader.close();         
Craigo
fuente
1
Desafortunadamente, este código no lee la respuesta. Lee el formulario vacío html.
Kovács Imre
Lo que tuve que agregar al ejemplo de Alan fue abrir un flujo de respuesta. antes de hacerlo, no se enviaron bytes.
beefeather
1
Eliminar la llamada writer.close () lo hizo por mí.
Maxime T
23

Me resulta HttpURLConnectionmuy engorroso de usar. Y tienes que escribir un montón de repeticiones, código propenso a errores. Necesitaba un contenedor ligero para mis proyectos de Android y salí con una biblioteca que también puedes usar: DavidWebb .

El ejemplo anterior podría escribirse así:

Webb webb = Webb.create();
webb.post("http://example.com/index.php")
        .param("param1", "a")
        .param("param2", "b")
        .param("param3", "c")
        .ensureSuccess()
        .asVoid();

Puede encontrar una lista de bibliotecas alternativas en el enlace proporcionado.

hgoebl
fuente
1
No voy a votar porque tu publicación fue menos una respuesta y más un anuncio ... pero jugué con tu biblioteca y me gusta. Muy sucinto; mucho azúcar sintáctico; si usa Java como un poco de lenguaje de script como lo hago yo, entonces es una gran biblioteca para agregar de manera rápida y eficiente algunas interacciones http. Cero repetitivo es valioso a veces y puede haber sido útil para el OP.
Dean
3
Voy a votar He utilizado con éxito DavidWebb en una de mis aplicaciones, y lo haré por dos más que desarrollaré pronto. Muy facil de usar.
William T. Mallard
Gracias, el uso de DefaultHttpClient con https en Android falla con SSLPeerUnverifiedException: sin certificado de igual (incluso en certificados https correctamente firmados), el uso de URL es engorroso (parámetros de codificación, comprobación de resultados). Usar DavidWebb funcionó para mí, gracias.
Martin Vysny
no hay soporte de AsyncTask? Por lo tanto el bloqueo del hilo de interfaz de usuario por defecto ... eso es malo
slinden77
Es una biblioteca muy básica. El programador tiene que llamarlo desde el hilo de fondo, en AsyncTask, en IntentService, en Synchronization Handler y similares. Y no depende de Android -> también se puede usar en Java SE y EE.
hgoebl
12

He leído las respuestas anteriores y he creado una clase de utilidad para simplificar la solicitud HTTP. Espero que te ayude.

Llamada al método

  // send params with Hash Map
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("email","[email protected]");
    params.put("password","12345");

    //server url
    String url = "http://www.example.com";

    // static class "HttpUtility" with static method "newRequest(url,method,callback)"
    HttpUtility.newRequest(url,HttpUtility.METHOD_POST,params, new HttpUtility.Callback() {
        @Override
        public void OnSuccess(String response) {
        // on success
           System.out.println("Server OnSuccess response="+response);
        }
        @Override
        public void OnError(int status_code, String message) {
        // on error
              System.out.println("Server OnError status_code="+status_code+" message="+message);
        }
    });

Clase de utilidad

import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import static java.net.HttpURLConnection.HTTP_OK;

public class HttpUtility {

 public static final int METHOD_GET = 0; // METHOD GET
 public static final int METHOD_POST = 1; // METHOD POST

 // Callback interface
 public interface Callback {
  // abstract methods
  public void OnSuccess(String response);
  public void OnError(int status_code, String message);
 }
 // static method
 public static void newRequest(String web_url, int method, HashMap < String, String > params, Callback callback) {

  // thread for handling async task
  new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     String url = web_url;
     // write GET params,append with url
     if (method == METHOD_GET && params != null) {
      for (Map.Entry < String, String > item: params.entrySet()) {
       String key = URLEncoder.encode(item.getKey(), "UTF-8");
       String value = URLEncoder.encode(item.getValue(), "UTF-8");
       if (!url.contains("?")) {
        url += "?" + key + "=" + value;
       } else {
        url += "&" + key + "=" + value;
       }
      }
     }

     HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
     urlConnection.setUseCaches(false);
     urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // handle url encoded form data
     urlConnection.setRequestProperty("charset", "utf-8");
     if (method == METHOD_GET) {
      urlConnection.setRequestMethod("GET");
     } else if (method == METHOD_POST) {
      urlConnection.setDoOutput(true); // write POST params
      urlConnection.setRequestMethod("POST");
     }

     //write POST data 
     if (method == METHOD_POST && params != null) {
      StringBuilder postData = new StringBuilder();
      for (Map.Entry < String, String > item: params.entrySet()) {
       if (postData.length() != 0) postData.append('&');
       postData.append(URLEncoder.encode(item.getKey(), "UTF-8"));
       postData.append('=');
       postData.append(URLEncoder.encode(String.valueOf(item.getValue()), "UTF-8"));
      }
      byte[] postDataBytes = postData.toString().getBytes("UTF-8");
      urlConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
      urlConnection.getOutputStream().write(postDataBytes);

     }
     // server response code
     int responseCode = urlConnection.getResponseCode();
     if (responseCode == HTTP_OK && callback != null) {
      BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
      StringBuilder response = new StringBuilder();
      String line;
      while ((line = reader.readLine()) != null) {
       response.append(line);
      }
      // callback success
      callback.OnSuccess(response.toString());
      reader.close(); // close BufferReader
     } else if (callback != null) {
      // callback error
      callback.OnError(responseCode, urlConnection.getResponseMessage());
     }

     urlConnection.disconnect(); // disconnect connection
    } catch (IOException e) {
     e.printStackTrace();
     if (callback != null) {
      // callback error
      callback.OnError(500, e.getLocalizedMessage());
     }
    }
   }
  }).start(); // start thread
 }
}
Pankaj Kant Patel
fuente
10

Veo que otras respuestas han dado la alternativa, personalmente creo que intuitivamente estás haciendo lo correcto;). Lo siento, en devoxx donde varios oradores han estado despotricando sobre este tipo de cosas.

Es por eso que personalmente uso las bibliotecas HTTPClient / HttpCore de Apache para hacer este tipo de trabajo, encuentro que su API es más fácil de usar que el soporte HTTP nativo de Java. YMMV por supuesto!

Martijn Verburg
fuente
10
import java.net.*;

public class Demo{

  public static void main(){

       String data = "data=Hello+World!";
       URL url = new URL("http://localhost:8084/WebListenerServer/webListener");
       HttpURLConnection con = (HttpURLConnection) url.openConnection();
       con.setRequestMethod("POST");
       con.setDoOutput(true);
       con.getOutputStream().write(data.getBytes("UTF-8"));
       con.getInputStream();

    }

}
Mistry varonil
fuente
55
WTH import java.net.*;!
Yousha Aleayoub
4

Tuve el mismo problema. Quería enviar datos a través de POST. Use el siguiente código:

    URL url = new URL("http://example.com/getval.php");
    Map<String,Object> params = new LinkedHashMap<>();
    params.put("param1", param1);
    params.put("param2", param2);

    StringBuilder postData = new StringBuilder();
    for (Map.Entry<String,Object> param : params.entrySet()) {
        if (postData.length() != 0) postData.append('&');
        postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
        postData.append('=');
        postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
    }
    String urlParameters = postData.toString();
    URLConnection conn = url.openConnection();

    conn.setDoOutput(true);

    OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());

    writer.write(urlParameters);
    writer.flush();

    String result = "";
    String line;
    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

    while ((line = reader.readLine()) != null) {
        result += line;
    }
    writer.close();
    reader.close()
    System.out.println(result);

Usé Jsoup para analizar:

    Document doc = Jsoup.parseBodyFragment(value);
    Iterator<Element> opts = doc.select("option").iterator();
    for (;opts.hasNext();) {
        Element item = opts.next();
        if (item.hasAttr("value")) {
            System.out.println(item.attr("value"));
        }
    }
SergeyUr
fuente
4

Los métodos GET y POST se configuran de esta manera ... Dos tipos para llamadas API 1) get () y 2) post (). El método get () para obtener valor de la matriz api json para obtener el valor y el método post () se usa en nuestra publicación de datos en url y se obtiene respuesta.

 public class HttpClientForExample {

    private final String USER_AGENT = "Mozilla/5.0";

    public static void main(String[] args) throws Exception {

        HttpClientExample http = new HttpClientExample();

        System.out.println("Testing 1 - Send Http GET request");
        http.sendGet();

        System.out.println("\nTesting 2 - Send Http POST request");
        http.sendPost();

    }

    // HTTP GET request
    private void sendGet() throws Exception {

        String url = "http://www.google.com/search?q=developer";

        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);

        // add request header
        request.addHeader("User-Agent", USER_AGENT);

        HttpResponse response = client.execute(request);

        System.out.println("\nSending 'GET' request to URL : " + url);
        System.out.println("Response Code : " + 
                       response.getStatusLine().getStatusCode());

        BufferedReader rd = new BufferedReader(
                       new InputStreamReader(response.getEntity().getContent()));

        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }

        System.out.println(result.toString());

    }

    // HTTP POST request
    private void sendPost() throws Exception {

        String url = "https://selfsolve.apple.com/wcResults.do";

        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(url);

        // add header
        post.setHeader("User-Agent", USER_AGENT);

        List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
        urlParameters.add(new BasicNameValuePair("sn", "C02G8416DRJM"));
        urlParameters.add(new BasicNameValuePair("cn", ""));
        urlParameters.add(new BasicNameValuePair("locale", ""));
        urlParameters.add(new BasicNameValuePair("caller", ""));
        urlParameters.add(new BasicNameValuePair("num", "12345"));

        post.setEntity(new UrlEncodedFormEntity(urlParameters));

        HttpResponse response = client.execute(post);
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + post.getEntity());
        System.out.println("Response Code : " + 
                                    response.getStatusLine().getStatusCode());

        BufferedReader rd = new BufferedReader(
                        new InputStreamReader(response.getEntity().getContent()));

        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }

        System.out.println(result.toString());

    }

}
Chirag Patel
fuente
3

Prueba este patrón:

public static PricesResponse getResponse(EventRequestRaw request) {

    // String urlParameters  = "param1=a&param2=b&param3=c";
    String urlParameters = Piping.serialize(request);

    HttpURLConnection conn = RestClient.getPOSTConnection(endPoint, urlParameters);

    PricesResponse response = null;

    try {
        // POST
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        writer.write(urlParameters);
        writer.flush();

        // RESPONSE
        BufferedReader reader = new BufferedReader(new InputStreamReader((conn.getInputStream()), StandardCharsets.UTF_8));
        String json = Buffering.getString(reader);
        response = (PricesResponse) Piping.deserialize(json, PricesResponse.class);

        writer.close();
        reader.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    conn.disconnect();

    System.out.println("PricesClient: " + response.toString());

    return response;
}

public static HttpURLConnection getPOSTConnection(String endPoint, String urlParameters) {

    return RestClient.getConnection(endPoint, "POST", urlParameters);

}


public static HttpURLConnection getConnection(String endPoint, String method, String urlParameters) {

    System.out.println("ENDPOINT " + endPoint + " METHOD " + method);
    HttpURLConnection conn = null;

    try {
        URL url = new URL(endPoint);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "text/plain");

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

    return conn;
}
Pablo Rodriguez Bertorello
fuente
3

Esta respuesta cubre el caso específico de la llamada POST utilizando un POJO Java personalizado.

Usando la dependencia de Maven para Gson para serializar nuestro objeto Java a JSON.

Instala Gson usando la dependencia a continuación.

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.5</version>
  <scope>compile</scope>
</dependency>

Para aquellos que usan gradle pueden usar el siguiente

dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}

Otras importaciones utilizadas:

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.*;
import org.apache.http.impl.client.CloseableHttpClient;
import com.google.gson.Gson;

Ahora, podemos seguir adelante y usar el HttpPost provisto por Apache

private CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://example.com");

Product product = new Product(); //custom java object to be posted as Request Body
    Gson gson = new Gson();
    String client = gson.toJson(product);

    httppost.setEntity(new StringEntity(client, ContentType.APPLICATION_JSON));
    httppost.setHeader("RANDOM-HEADER", "headervalue");
    //Execute and get the response.
    HttpResponse response = null;
    try {
        response = httpclient.execute(httppost);
    } catch (IOException e) {
        throw new InternalServerErrorException("Post fails");
    }
    Response.Status responseStatus = Response.Status.fromStatusCode(response.getStatusLine().getStatusCode());
    return Response.status(responseStatus).build();

El código anterior regresará con el código de respuesta recibido de la llamada POST

kaushalop
fuente
2

aquí envié jsonobject como parámetro // jsonobject = {"name": "lucifer", "pass": "abc"} // serverUrl = " http://192.168.100.12/testing " //host=192.168.100.12

  public static String getJson(String serverUrl,String host,String jsonobject){

    StringBuilder sb = new StringBuilder();

    String http = serverUrl;

    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(http);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setRequestMethod("POST");
        urlConnection.setUseCaches(false);
        urlConnection.setConnectTimeout(50000);
        urlConnection.setReadTimeout(50000);
        urlConnection.setRequestProperty("Content-Type", "application/json");
        urlConnection.setRequestProperty("Host", host);
        urlConnection.connect();
        //You Can also Create JSONObject here 
        OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
        out.write(jsonobject);// here i sent the parameter
        out.close();
        int HttpResult = urlConnection.getResponseCode();
        if (HttpResult == HttpURLConnection.HTTP_OK) {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream(), "utf-8"));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            br.close();
            Log.e("new Test", "" + sb.toString());
            return sb.toString();
        } else {
            Log.e(" ", "" + urlConnection.getResponseMessage());
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    } finally {
        if (urlConnection != null)
            urlConnection.disconnect();
    }
    return null;
}
Abhisek
fuente
2

Recomiendo encarecidamente http-request basada en la api http apache.

Para su caso, puede ver un ejemplo:

private static final HttpRequest<String.class> HTTP_REQUEST = 
      HttpRequestBuilder.createPost("http://example.com/index.php", String.class)
           .responseDeserializer(ResponseDeserializer.ignorableDeserializer())
           .build();

public void sendRequest(String request){
     String parameters = request.split("\\?")[1];
     ResponseHandler<String> responseHandler = 
            HTTP_REQUEST.executeWithQuery(parameters);

   System.out.println(responseHandler.getStatusCode());
   System.out.println(responseHandler.get()); //prints response body
}

Si no está interesado en el cuerpo de respuesta

private static final HttpRequest<?> HTTP_REQUEST = 
     HttpRequestBuilder.createPost("http://example.com/index.php").build();

public void sendRequest(String request){
     ResponseHandler<String> responseHandler = 
           HTTP_REQUEST.executeWithQuery(parameters);
}

Para enviar una solicitud de envío general con http-request : lea la documentación y vea mis respuestas Solicitud HTTP POST con JSON String en JAVA , Envío de solicitud HTTP POST en Java , HTTP POST utilizando JSON en Java

Beno Arakelyan
fuente
1

Hola, por favor use esta clase para mejorar su método de publicación

public static JSONObject doPostRequest(HashMap<String, String> data, String url) {

    try {
        RequestBody requestBody;
        MultipartBuilder mBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);

        if (data != null) {


            for (String key : data.keySet()) {
                String value = data.get(key);
                Utility.printLog("Key Values", key + "-----------------" + value);

                mBuilder.addFormDataPart(key, value);

            }
        } else {
            mBuilder.addFormDataPart("temp", "temp");
        }
        requestBody = mBuilder.build();


        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        OkHttpClient client = new OkHttpClient();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        Utility.printLog("URL", url);
        Utility.printLog("Response", responseBody);
        return new JSONObject(responseBody);

    } catch (UnknownHostException | UnsupportedEncodingException e) {

        JSONObject jsonObject=new JSONObject();

        try {
            jsonObject.put("status","false");
            jsonObject.put("message",e.getLocalizedMessage());
        } catch (JSONException e1) {
            e1.printStackTrace();
        }
        Log.e(TAG, "Error: " + e.getLocalizedMessage());
    } catch (Exception e) {
        e.printStackTrace();
        JSONObject jsonObject=new JSONObject();

        try {
            jsonObject.put("status","false");
            jsonObject.put("message",e.getLocalizedMessage());
        } catch (JSONException e1) {
            e1.printStackTrace();
        }
        Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
    }
    return null;
}
CHirag RAmi
fuente
0

Tomé la respuesta de Boann y la usé para crear un generador de cadenas de consulta más flexible que admite listas y matrices, al igual que el método http_build_query de php:

public static byte[] httpBuildQueryString(Map<String, Object> postsData) throws UnsupportedEncodingException {
    StringBuilder postData = new StringBuilder();
    for (Map.Entry<String,Object> param : postsData.entrySet()) {
        if (postData.length() != 0) postData.append('&');

        Object value = param.getValue();
        String key = param.getKey();

        if(value instanceof Object[] || value instanceof List<?>)
        {
            int size = value instanceof Object[] ? ((Object[])value).length : ((List<?>)value).size();
            for(int i = 0; i < size; i++)
            {
                Object val = value instanceof Object[] ? ((Object[])value)[i] : ((List<?>)value).get(i);
                if(i>0) postData.append('&');
                postData.append(URLEncoder.encode(key + "[" + i + "]", "UTF-8"));
                postData.append('=');            
                postData.append(URLEncoder.encode(String.valueOf(val), "UTF-8"));
            }
        }
        else
        {
            postData.append(URLEncoder.encode(key, "UTF-8"));
            postData.append('=');            
            postData.append(URLEncoder.encode(String.valueOf(value), "UTF-8"));
        }
    }
    return postData.toString().getBytes("UTF-8");
}
Curtis
fuente
0

Para aquellos que tienen problemas para recibir la solicitud en una página php usando $ _POST porque esperan pares clave-valor:

Si bien todas las respuestas fueron muy útiles, carecía de una comprensión básica sobre qué cadena realmente publicar, ya que en el antiguo HttpClient de apache solía

new UrlEncodedFormEntity(nameValuePairs); (Java)

y luego podría usar $ _POST en php para obtener los pares clave-valor.

A mi entender, ahora uno ha creado esa cadena manualmente antes de publicar. Entonces la cuerda necesita verse

val data = "key1=val1&key2=val2"

pero en lugar de agregarlo a la url, se publica (en el encabezado).

La alternativa sería usar una cadena json en su lugar:

val data = "{\"key1\":\"val1\",\"key2\":\"val2\"}" // {"key1":"val1","key2":"val2"}

y tire de él en php sin $ _POST:

$json_params = file_get_contents('php://input');
// echo_p("Data: $json_params");
$data = json_decode($json_params, true);

Aquí encontrará un código de muestra en Kotlin:

class TaskDownloadTest : AsyncTask<Void, Void, Void>() {
    override fun doInBackground(vararg params: Void): Void? {
        var urlConnection: HttpURLConnection? = null

        try {

            val postData = JsonObject()
            postData.addProperty("key1", "val1")
            postData.addProperty("key2", "val2")

            // reformat json to key1=value1&key2=value2
            // keeping json because I may change the php part to interpret json requests, could be a HashMap instead
            val keys = postData.keySet()
            var request = ""
            keys.forEach { key ->
                // Log.i("data", key)
                request += "$key=${postData.get(key)}&"
            }
            request = request.replace("\"", "").removeSuffix("&")
            val requestLength = request.toByteArray().size
            // Warning in Android 9 you need to add a line in the application part of the manifest: android:usesCleartextTraffic="true"
            // /programming/45940861/android-8-cleartext-http-traffic-not-permitted
            val url = URL("http://10.0.2.2/getdata.php")
            urlConnection = url.openConnection() as HttpURLConnection
            // urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") // apparently default
            // Not sure what these are for, I do not use them
            // urlConnection.setRequestProperty("Content-Type", "application/json")
            // urlConnection.setRequestProperty("Key","Value")
            urlConnection.readTimeout = 5000
            urlConnection.connectTimeout = 5000
            urlConnection.requestMethod = "POST"
            urlConnection.doOutput = true
            // urlConnection.doInput = true
            urlConnection.useCaches = false
            urlConnection.setFixedLengthStreamingMode(requestLength)
            // urlConnection.setChunkedStreamingMode(0) // if you do not want to handle request length which is fine for small requests

            val out = urlConnection.outputStream
            val writer = BufferedWriter(
                OutputStreamWriter(
                    out, "UTF-8"
                )
            )
            writer.write(request)
            // writer.write("{\"key1\":\"val1\",\"key2\":\"val2\"}") // {"key1":"val1","key2":"val2"} JsonFormat or just postData.toString() for $json_params=file_get_contents('php://input'); json_decode($json_params, true); in php
            // writer.write("key1=val1&key2=val2") // key=value format for $_POST in php
            writer.flush()
            writer.close()
            out.close()

            val code = urlConnection.responseCode
            if (code != 200) {
                throw IOException("Invalid response from server: $code")
            }

            val rd = BufferedReader(
                InputStreamReader(
                    urlConnection.inputStream
                )
            )
            var line = rd.readLine()
            while (line != null) {
                Log.i("data", line)
                line = rd.readLine()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            urlConnection?.disconnect()
        }

        return null
    }
}
Gunnar Bernstein
fuente
-3

Parece que también debe llamar connection.getOutputStream()"al menos una vez" (así como setDoOutput(true)) para que lo trate como una POST.

Entonces, el código mínimo requerido es:

    URL url = new URL(urlString);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    //connection.setRequestMethod("POST"); this doesn't seem to do anything at all..so not useful
    connection.setDoOutput(true); // set it to POST...not enough by itself however, also need the getOutputStream call...
    connection.connect();
    connection.getOutputStream().close(); 

Incluso puede usar parámetros de estilo "GET" en urlString, sorprendentemente. Aunque eso podría confundir las cosas.

También puede usar NameValuePair aparentemente.

rogerdpack
fuente
¿Dónde están los parámetros POST ...?
Yousha Aleayoub
¿Por qué la gente rechaza esto? Es una nota sobre cómo hacer POST en absoluto, aunque sin parámetros ... (es decir, sin carga útil0 ...
rogerdpack