Java - łatwe przesyłanie parametrów HTTP metodą POST

319

Z powodzeniem używam tego kodu do wysyłania HTTP żądań z pewnymi parametrami za pomocą GETmetody

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

Teraz może być konieczne przesłanie parametrów (tj. Param1, param2, param3) POSTmetodą, ponieważ są one bardzo długie. Myślałem o dodaniu dodatkowego parametru do tej metody (tj. String httpMethod).

Jak mogę jak najmniej zmienić powyższy kod, aby móc przesyłać parametry za pośrednictwem GET lub POST?

Miałem nadzieję, że to się zmieni

connection.setRequestMethod("GET");

do

connection.setRequestMethod("POST");

zrobiłby lewę, ale parametry są nadal wysyłane metodą GET.

Ma HttpURLConnection jakaś metoda, która by pomogła? Czy jest jakiś pomocny konstrukt Java?

Każda pomoc byłaby bardzo mile widziana.

dan
źródło
Parametry postów są wysyłane w sekcji nagłówka http, a nie w adresie URL. (Twój adres URL postu będzie http://example.com/index.php)
dacwe
2
w Javie 1.6 nie ma zdefiniowanej metody setRequestMethod: docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html
ante.sabo
2
Przekaż go do HTTP UrlConnection ....
Peter Kriens
rozszerzenie pytania! Czy ktoś ma jakiś pomysł, jak wysłać załącznik jako parametr wpisu ...
therealprashant
1
Dlaczego pierwszy fragment kodu zaczyna się od słowa kluczowego „funkcja”?
Llew Vallis

Odpowiedzi:

470

W żądaniu GET parametry są wysyłane jako część adresu URL.

W żądaniu POST parametry są wysyłane jako treść żądania, po nagłówkach.

Aby wykonać test POST za pomocą HttpURLConnection, musisz zapisać parametry do połączenia po jego otwarciu.

Ten kod powinien zacząć:

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
źródło
40
@Alan Geleynse: „url.openconnection ()” nie otwiera połączenia. W przypadku, gdy nie określisz instrukcji connect (), połączenie zostanie otwarte, gdy napiszesz do treści żądania HTTP / usłyszałeś i wyślesz. Próbowałem tego z certyfikatami. Uzgadnianie ssl odbywa się tylko po nawiązaniu połączenia lub wysłaniu danych do serwera.
Ashwin
14
getBytes () używa domyślnego zestawu znaków środowiska, NIE UTF-8 charset = utf-8 musi podążać za typem treści: application / x-www-form-urlencoded; charset = utf-8 W tym przykładzie dwukrotnie konwertujesz bajty. Powinieneś zrobić: byte [] data = urlParameters.getData („UTF-8”); connection.getOutputStream (). write (data); nie ma sensu zamykać ORAZ przepłukiwać ORAZ rozłączać
Peter Kriens
8
@PeterKriens Dzięki za dodanie - wierzę, że miałeś na myśli byte[] data = urlParameters.getBytes(Charset.forName("UTF-8")):).
gerrytan
7
@AlanGeleynse Don't miss miss wr.flush (); i wr.close (); na końcu?
confile
9
Jak to się dzieje, że ma tak wiele pozytywnych opinii, jeśli to nie działa? Trzeba zadzwonić albo conn.getResponseCode()czy conn.getInputStream()inaczej nie wyśle żadnych danych.
Imaskar
229

Oto prosty przykład, który przesyła formularz, a następnie zrzuca stronę wyników System.out. Zmień odpowiednio adres URL i parametry POST, oczywiście:

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

Jeśli chcesz otrzymać wynik Stringzamiast bezpośrednio wydrukować:

        StringBuilder sb = new StringBuilder();
        for (int c; (c = in.read()) >= 0;)
            sb.append((char)c);
        String response = sb.toString();
Boann
źródło
To najlepsza odpowiedź, ponieważ obejmuje kodowanie parametrów i korzystanie z Map.
Airy
4
Niestety kod ten zakłada, że ​​kodowanie treści jest takie UTF-8, co nie zawsze jest prawdą. Aby pobrać zestaw znaków, należy pobrać nagłówek Content-Typei parsować zestaw znaków. Kiedy ten nagłówek nie jest dostępny, należy użyć standardowego http: ISO-8859-1.
inżynier
@Aprel IFTFY ... używanie wyrażeń z efektami ubocznymi w ocenach jest naprawdę brzydkie.
1
@engineercoding Niestety dla HTML jest jeszcze trudniej zrobić to całkowicie poprawnie, ponieważ w dokumencie może być również BOM Unicode <meta charset="...">lub <meta http-equiv="Content-Type" content="...">nagłówek lub dokument, który należy przeanalizować.
Boann
1
@Nepster Nie rób tego. response += line;jest fenomenalnie wolny i zjada przerwy w linii. Do odpowiedzi dodałem przykład otrzymania odpowiedzi łańcuchowej.
Boann
63

Nie mogłem przekonać przykładu Alana do zrobienia tego postu, więc skończyłem z tym:

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
źródło
1
Niestety ten kod nie odczytuje odpowiedzi. Odczytuje pusty formularz HTML.
Kovács Imre
To, co musiałem dodać do przykładu Alana, to otwarcie strumienia odpowiedzi. zanim to zrobiłem, żadne bajty nie zostały wysłane.
beefeather
1
Usunięcie wywołania writer.close () zrobiło to dla mnie.
Maxime T
23

HttpURLConnectionUżywanie jest dla mnie bardzo kłopotliwe. I musisz napisać dużo bojlera, podatnego na błędy kodu. Potrzebowałem lekkiego opakowania dla moich projektów na Androida i wyszedłem z biblioteką, której możesz także użyć: DavidWebb .

Powyższy przykład można zapisać w następujący sposób:

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

Listę alternatywnych bibliotek można znaleźć pod podanym linkiem.

hgoebl
źródło
1
Nie zamierzam głosować, ponieważ twój post był mniej odpowiedzią, a raczej reklamą ... ale bawiłem się twoją biblioteką i podoba mi się to. Bardzo zwięzły; dużo cukru syntaktycznego; jeśli używasz Javy jako trochę języka skryptowego, tak jak ja, to jest to świetna biblioteka do bardzo szybkiego i wydajnego dodawania niektórych interakcji http. Zerowy bojler jest czasem cenny i może być przydatny dla PO.
Dean
3
Będę głosować. Z powodzeniem wykorzystałem DavidWebb w jednej z moich aplikacji i zrobię to jeszcze przez dwa kolejne. Bardzo łatwy w użyciu.
William T. Mallard
Dziękujemy, użycie DefaultHttpClient z https na Androidzie kończy się niepowodzeniem z SSLPeerUnverifiedException: Brak certyfikatu równorzędnego (nawet na poprawnie podpisanych certyfikatach https), używanie adresu URL jest kłopotliwe (kodowanie parametrów, sprawdzanie wyniku). Dzięki DavidWebb działało dla mnie, dzięki.
Martin Vysny
brak obsługi AsyncTask? Więc domyślnie blokowanie wątku interfejsu użytkownika ... to źle
slinden77
To bardzo podstawowa biblioteka. Programista musi wywołać go z wątku w tle, w AsyncTask, w IntentService, w module obsługi synchronizacji i tym podobnych. I to nie zależy od Androida -> można go również używać w Java SE i EE.
hgoebl
12

Przeczytałem powyższe odpowiedzi i utworzyłem klasę narzędzi w celu uproszczenia żądania HTTP. mam nadzieję, że ci to pomoże.

Wywołanie metody

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

Klasa użyteczności

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
źródło
10

Widzę, że niektóre inne odpowiedzi dały alternatywę, osobiście uważam, że intuicyjnie postępujesz właściwie;). Przepraszamy, na devoxx, gdzie kilku mówców wypowiada się na ten temat.

Właśnie dlatego osobiście korzystam z bibliotek HTTP Apache HTTPClient / HttpCore do tego rodzaju pracy. Uważam, że ich interfejs API jest łatwiejszy w użyciu niż natywna obsługa HTTP w Javie. YMMV oczywiście!

Martijn Verburg
źródło
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();

    }

}
Manish Mistry
źródło
5
WTH import java.net.*;!
Yousha Aleayoub
4

Miałem ten sam problem. Chciałem wysłać dane przez POST. Użyłem następującego kodu:

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

Użyłem Jsoup do analizy:

    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
źródło
4

Metoda GET i POST ustawiona w ten sposób ... Dwa typy wywoływania interfejsu API 1) get () i 2) post (). Metoda get (), aby uzyskać wartość z tablicy api json, aby uzyskać metodę value & post () w naszym poście danych w adresie URL i uzyskać odpowiedź.

 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
źródło
3

Wypróbuj ten wzór:

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
źródło
3

Ta odpowiedź dotyczy konkretnego przypadku wywołania POST przy użyciu niestandardowego Java POJO.

Wykorzystanie zależności maven dla Gson do serializacji naszego obiektu Java do JSON.

Zainstaluj Gson, korzystając z zależności poniżej.

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

Dla osób korzystających z gradle można skorzystać z poniższych

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

Inne zastosowane przywozy:

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;

Teraz możemy zacząć korzystać z HttpPost dostarczonego przez 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();

Powyższy kod zwróci kod odpowiedzi otrzymany z wywołania POST

kaushalop
źródło
2

tutaj wysłałem jsonobject jako parametr // 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
źródło
2

Gorąco polecam żądanie HTTP oparte na apache http api.

W twoim przypadku możesz zobaczyć przykład:

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
}

Jeśli nie jesteś zainteresowany odpowiedzią

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

Ogólne żądanie wysyłania za pomocą żądania HTTP : Przeczytaj dokumentację i zobacz moje odpowiedzi Żądanie HTTP POST z JSON String w JAVA , Wysyłanie żądania HTTP POST W Javie , HTTP POST za pomocą JSON w Javie

Beno Arakelyan
źródło
1

Witaj proszę, skorzystaj z tej klasy, aby ulepszyć twoją metodę postów

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
źródło
0

Wziąłem odpowiedź Boanna i wykorzystałem ją do stworzenia bardziej elastycznego narzędzia do tworzenia ciągów zapytań, które obsługuje listy i tablice, podobnie jak metoda http_build_query 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
źródło
0

Dla tych, którzy mają problemy z otrzymaniem żądania na stronie php przy użyciu $ _POST, ponieważ oczekujesz par klucz-wartość:

Podczas gdy wszystkie odpowiedzi były bardzo pomocne, brakowało mi podstawowego zrozumienia, na którym ciągu napisać, ponieważ w starym apache HttpClient użyłem

new UrlEncodedFormEntity(nameValuePairs); (Java)

a następnie może użyć $ _POST w php, aby uzyskać pary klucz-wartość.

O ile mi wiadomo, przed wysłaniem należy ręcznie zbudować ten ciąg. Więc ciąg musi wyglądać

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

ale zamiast tego wystarczy dodać go do adresu URL, który jest opublikowany (w nagłówku).

Alternatywą byłoby użycie zamiast tego łańcucha json:

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

i ściągnij go w php bez $ _POST:

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

Oto przykładowy kod w 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
źródło
-3

Wygląda na to, że musisz zadzwonić connection.getOutputStream()„co najmniej raz” (a także setDoOutput(true)), aby potraktować to jako POST.

Zatem minimalny wymagany kod to:

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

Co zaskakujące, możesz nawet użyć parametrów stylu „GET” w urlString. Choć może to dezorientować.

Najwyraźniej możesz również użyć NameValuePair .

rogerdpack
źródło
Gdzie są parametry POST ...?
Yousha Aleayoub 18.04.16
Dlaczego ludzie przegłosowali to? Jest to uwaga na to, jak w ogóle robić POST, choć bez parametrów ... (tj. Bez ładunku 0 ...
rogerdpack