348 Stimmen

Java - einfaches Senden von HTTP-Parametern über die POST-Methode

Ich verwende diesen Code erfolgreich zum Senden von HTTP Anfragen mit einigen Parametern über GET 方法

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

Jetzt muss ich möglicherweise die Parameter (d.h. param1, param2, param3) über POST Methode, weil sie sehr lang sind. Ich dachte daran, dieser Methode einen zusätzlichen Parameter hinzuzufügen (z. B. String httpMethod).

Wie kann ich den obigen Code so wenig wie möglich ändern, um die Parameter entweder über GET o POST ?

Ich hatte gehofft, dass die Änderung

connection.setRequestMethod("GET");

zu

connection.setRequestMethod("POST");

hätte es auch getan, aber die Parameter werden immer noch über die GET-Methode gesendet.

Hat HttpURLConnection Haben Sie eine Methode, die helfen könnte? Gibt es ein hilfreiches Java-Konstrukt?

Für jede Hilfe wären wir sehr dankbar.

0voto

Gunnar Bernstein Punkte 5786

Für diejenigen, die Probleme haben, die Anfrage auf einer php-Seite mit $_POST zu empfangen, weil Sie Schlüssel-Wert-Paare erwarten:

Während alle Antworten sehr hilfreich waren, fehlte mir einige grundlegende Verständnis auf welche Zeichenfolge tatsächlich zu posten, da in der alten Apache HttpClient ich verwendet

new UrlEncodedFormEntity(nameValuePairs); (Java)

und könnte dann $_POST in php verwenden, um die Schlüssel-Wert-Paare zu erhalten.

Soweit ich weiß, muss man diese Zeichenkette nun manuell erstellen, bevor man sie bucht. Die Zeichenfolge muss also wie folgt aussehen

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

sondern fügen sie einfach der URL hinzu, unter der sie veröffentlicht wird (in der Kopfzeile).

Die Alternative wäre, stattdessen einen json-string zu verwenden:

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

und ziehen Sie es in php ohne $_POST:

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

Hier finden Sie einen Beispielcode in 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"
            // https://stackoverflow.com/questions/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
    }
}

0voto

Oren Hahiashvili Punkte 151

Jetzt musste ich eine HTTP-Anforderungsklasse erstellen, die wahrscheinlich nicht die effizienteste Klasse ist, aber sie funktioniert. Ich habe einige Codes von dieser Seite gesammelt und sie dynamischer gemacht.

Wer einen vollständigen Code benötigt, findet ihn unten angehängt. Ein Beispiel für die Verwendung des Codes finden Sie in der main Methode.

Auch wenn Sie bereit sind, den Online-Unterricht zu verbessern, sind Sie herzlich willkommen, mir zu helfen, diesen Kurs zu verbessern.

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

public class HttpRequest {

    String result = "";

    HttpRequest(String _url, String _method, Map<String, String> _postData, String _contentType) {

        try {
            URL url = new URL( _url );
            URLConnection con = url.openConnection();
            HttpURLConnection http = (HttpURLConnection)con;
            http.setRequestMethod(_method); // PUT is another valid option
            http.setDoOutput(true);         

            StringJoiner sj = new StringJoiner("&");
            for(Map.Entry<String,String> entry : _postData.entrySet())
                sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + entry.getValue());
                //sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue()));
            byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
            int length = out.length;
            http.setFixedLengthStreamingMode(length);
            http.setRequestProperty("Content-Type", _contentType);
            http.setRequestProperty( "charset", "utf-8");
            http.setRequestProperty( "Content-Length", Integer.toString( length ));
            http.setInstanceFollowRedirects( false );
            http.setUseCaches( false );
            http.connect();
            try(OutputStream os = http.getOutputStream()) {
                os.write(out);
            }
            if (http.getResponseCode() == HttpURLConnection.HTTP_OK) {
                try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(http.getInputStream()))) {
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                  result = result + line;
                }
            }
          } else {
            System.out.println("Bad response!");
          }
        }catch (IOException e) {
            // writing exception to log
            e.printStackTrace();
        }

    }

    HttpRequest(String _url, String _method, Map<String, String> _postData) {
        this(_url, _method, _postData, "text/html");
    }

    HttpRequest(String _url, String _method) {
        this(_url, _method, new HashMap<String, String>());
    }

    HttpRequest(String _url) {
        this(_url, "GET");
    }

    public String toString() {
        return result;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map<String, String> postData = new HashMap<String, String>();
        postData.putIfAbsent("email", "test@test.com");
        postData.putIfAbsent("password", "test");

        HttpRequest result = new HttpRequest("https://httpbin.org/anything", "POST", postData, "application/x-www-form-urlencoded");
        System.out.println(result.toString());
    }
}

-1voto

rogerdpack Punkte 55995

Anscheinend müssen Sie auch die connection.getOutputStream() "mindestens einmal" (sowie setDoOutput(true) ), damit er sie als POST behandelt.

Der erforderliche Mindestcode ist also:

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

Überraschenderweise können Sie sogar Parameter im Stil von "GET" im urlString verwenden. Das könnte allerdings zu Verwirrung führen.

Sie können auch Folgendes verwenden NameWertPaar offenbar.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X