Mengirim Permintaan HTTP POST Di Java

295

mari kita asumsikan URL ini ...

http://www.example.com/page.php?id=10            

(Di sini id harus dikirim dalam permintaan POST)

Saya ingin mengirim id = 10ke server page.php, yang menerimanya dengan metode POST.

Bagaimana saya bisa melakukan ini dari dalam Java?

Saya mencoba ini:

URL aaa = new URL("http://www.example.com/page.php");
URLConnection ccc = aaa.openConnection();

Tapi saya masih tidak tahu bagaimana cara mengirimnya melalui POST

Jazz
sumber

Jawaban:

339

Jawaban yang Diperbarui:

Karena beberapa kelas, dalam jawaban asli, sudah usang dalam versi yang lebih baru dari Komponen HTTP Apache, saya memposting pembaruan ini.

Omong-omong, Anda dapat mengakses dokumentasi lengkap untuk lebih banyak contoh di sini .

HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("http://www.a-domain.com/foo/");

// Request parameters and other properties.
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("param-1", "12345"));
params.add(new BasicNameValuePair("param-2", "Hello!"));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));

//Execute and get the response.
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();

if (entity != null) {
    try (InputStream instream = entity.getContent()) {
        // do something useful
    }
}

Jawaban asli:

Saya merekomendasikan untuk menggunakan Apache HttpClient. lebih cepat dan lebih mudah diimplementasikan.

HttpPost post = new HttpPost("http://jakarata.apache.org/");
NameValuePair[] data = {
    new NameValuePair("user", "joe"),
    new NameValuePair("password", "bloggs")
};
post.setRequestBody(data);
// execute method and handle any error responses.
...
InputStream in = post.getResponseBodyAsStream();
// handle response.

untuk informasi lebih lanjut, periksa url ini: http://hc.apache.org/

mhshams
sumber
25
Setelah mencoba beberapa saat untuk mendapatkan tangan saya PostMethodtampaknya sekarang benar-benar sekarang disebut HttpPostsebagai per stackoverflow.com/a/9242394/1338936 - hanya untuk siapa pun yang menemukan jawaban ini seperti yang saya lakukan :)
Martin Lyne
1
@Juan (dan Martin Lyne) terima kasih atas komentarnya. Saya baru saja memperbarui jawabannya.
mhshams
Apakah jawaban Anda yang direvisi masih menggunakan hc.apache.org?
Djangofan
@ Djangofan ya. ada tautan ke apache-hc dalam jawaban yang direvisi juga.
mhshams
6
Anda harus menambahkan libs yang diimpor
gouchaoer
192

Mengirim permintaan POST mudah di vanilla Java. Dimulai dengan a URL, kita perlu mengubahnya menjadi URLConnectionmenggunakan url.openConnection();. Setelah itu, kita perlu melemparkannya ke a HttpURLConnection, sehingga kita dapat mengakses setRequestMethod()metodenya untuk mengatur metode kita. Kami akhirnya mengatakan bahwa kami akan mengirim data melalui koneksi.

URL url = new URL("https://www.example.com/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);

Maka kita perlu menyatakan apa yang akan kita kirim:

Mengirim formulir sederhana

POST normal yang berasal dari formulir http memiliki format yang jelas . Kami perlu mengonversi input kami ke format ini:

Map<String,String> arguments = new HashMap<>();
arguments.put("username", "root");
arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
    sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" 
         + URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;

Kami kemudian dapat melampirkan konten formulir kami ke permintaan http dengan tajuk yang tepat dan mengirimkannya.

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

Mengirim JSON

Kami juga dapat mengirim json menggunakan java, ini juga mudah:

byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
int length = out.length;

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

Ingat bahwa server yang berbeda menerima tipe konten yang berbeda untuk json, lihat pertanyaan ini .


Mengirim file dengan posting java

Mengirim file dapat dianggap lebih sulit untuk ditangani karena formatnya lebih kompleks. Kami juga akan menambahkan dukungan untuk mengirim file sebagai string, karena kami tidak ingin buffer file sepenuhnya ke dalam memori.

Untuk ini, kami mendefinisikan beberapa metode pembantu:

private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
    String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8") 
             + "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    byte[] buffer = new byte[2048];
    for (int n = 0; n >= 0; n = in.read(buffer))
        out.write(buffer, 0, n);
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

private void sendField(OutputStream out, String name, String field) {
    String o = "Content-Disposition: form-data; name=\"" 
             + URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

Kami kemudian dapat menggunakan metode ini untuk membuat permintaan pos multi-bagian sebagai berikut:

String boundary = UUID.randomUUID().toString();
byte[] boundaryBytes = 
           ("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
byte[] finishBoundaryBytes = 
           ("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
http.setRequestProperty("Content-Type", 
           "multipart/form-data; charset=UTF-8; boundary=" + boundary);

// Enable streaming mode with default settings
http.setChunkedStreamingMode(0); 

// Send our fields:
try(OutputStream out = http.getOutputStream()) {
    // Send our header (thx Algoman)
    out.write(boundaryBytes);

    // Send our first field
    sendField(out, "username", "root");

    // Send a seperator
    out.write(boundaryBytes);

    // Send our second field
    sendField(out, "password", "toor");

    // Send another seperator
    out.write(boundaryBytes);

    // Send our file
    try(InputStream file = new FileInputStream("test.txt")) {
        sendFile(out, "identification", file, "text.txt");
    }

    // Finish the request
    out.write(finishBoundaryBytes);
}


// Do something with http.getInputStream()
Ferrybig
sumber
5
Posting ini bermanfaat, tetapi cukup cacat. Butuh saya 2 hari untuk membuatnya bekerja. Jadi untuk membuatnya berfungsi, Anda harus mengganti StandartCharsets.UTF8 dengan StandardCharsets.UTF_8. boundaryBytes dan finishBoundaryBytes perlu mendapatkan dua tanda hubung tambahan yang TIDAK ditransmisikan dalam Tipe-Konten, jadi boundaryBytes = ("-" + boundary + "\ r \ n"). dapatkan ... Anda juga perlu mengirim boundaryBytes sekali SEBELUM bidang pertama atau bidang pertama akan diabaikan!
Algoman
Mengapa out.write(finishBoundaryBytes);garis perlu? http.connect();akan melakukan pengiriman POST, bukan?
János
17
"Mengirim permintaan POST mudah di vanilla Java." Dan kemudian lusinan baris kode mengikuti, dibandingkan dengan sesuatu seperti requests.post('http://httpbin.org/post', data = {'key':'value'})di Python ... Saya baru di Jawa, jadi ini adalah penggunaan kata "mudah" yang sangat aneh bagi saya :)
Lynn
1
Ini relatif lebih mudah daripada yang saya harapkan mengingat Java :)
shaahiin
enigmatic \ r \ n \ r \ n berarti CRLF CRLF (carriage return + line feed). Ini menciptakan 2x baris baru. Baris baru pertama adalah untuk menyelesaikan garis saat ini. Baris kedua adalah membedakan header http dari http body dalam satu permintaan. HTTP adalah protokol berbasis ASCII. Ini adalah aturan untuk memasukkan \ r \ n.
Mitja Gustin
99
String rawData = "id=10";
String type = "application/x-www-form-urlencoded";
String encodedData = URLEncoder.encode( rawData, "UTF-8" ); 
URL u = new URL("http://www.example.com/page.php");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty( "Content-Type", type );
conn.setRequestProperty( "Content-Length", String.valueOf(encodedData.length()));
OutputStream os = conn.getOutputStream();
os.write(encodedData.getBytes());
DuduAlul
sumber
Penting untuk diperhatikan: menggunakan yang lain selain String.getBytes () tampaknya tidak berfungsi. Misalnya, menggunakan PrintWriter gagal total.
Little Bobby Tables
5
dan bagaimana cara mengatur 2 data posting? Dipisahkan oleh titik dua, koma?
kucing berisik
10
encode(String)sudah ditinggalkan. Anda harus menggunakan encode(String, String), yang menentukan jenis penyandian. Contoh: encode(rawData, "UTF-8").
sudo
3
Anda mungkin ingin mengikuti di bagian akhir. Ini akan memastikan permintaan selesai dan server mendapat kesempatan untuk memproses respons: conn.getResponseCode ();
Szymon Jachim
3
dont encode seluruh string .. Anda harus menyandikan hanya nilai dari setiap parameter
user2914191
22

Jawaban pertama sangat bagus, tetapi saya harus menambahkan try / catch untuk menghindari kesalahan kompiler Java.
Juga, saya memiliki masalah untuk mencari cara membaca HttpResponsedengan perpustakaan Java.

Ini kode yang lebih lengkap:

/*
 * Create the POST request
 */
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://example.com/");
// Request parameters and other properties.
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("user", "Bob"));
try {
    httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
    // writing error to Log
    e.printStackTrace();
}
/*
 * Execute the HTTP Request
 */
try {
    HttpResponse response = httpClient.execute(httpPost);
    HttpEntity respEntity = response.getEntity();

    if (respEntity != null) {
        // EntityUtils to get the response content
        String content =  EntityUtils.toString(respEntity);
    }
} catch (ClientProtocolException e) {
    // writing exception to log
    e.printStackTrace();
} catch (IOException e) {
    // writing exception to log
    e.printStackTrace();
}
Mar Cnu
sumber
EntityUtils sangat membantu.
Jay
6
Maaf, tetapi Anda tidak menemukan kesalahan, Anda memperkenalkannya. Menangkap pengecualian di tempat di mana Anda tidak bisa menanganinya jelas salah dan e.printStackTrace()tidak menangani apa pun.
maaartinus
java.net.ConnectException: Waktu koneksi habis: hubungkan
kerZy Hart
5

cara paling sederhana untuk mengirim parameter dengan permintaan pos:

String postURL = "http://www.example.com/page.php";

HttpPost post = new HttpPost(postURL);

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", "10"));

UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, "UTF-8");
post.setEntity(ent);

HttpClient client = new DefaultHttpClient();
HttpResponse responsePOST = client.execute(post);

Sudah selesai. sekarang kamu bisa menggunakannya responsePOST. Dapatkan konten respons sebagai string:

BufferedReader reader = new BufferedReader(new  InputStreamReader(responsePOST.getEntity().getContent()), 2048);

if (responsePOST != null) {
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(" line : " + line);
        sb.append(line);
    }
    String getResponseString = "";
    getResponseString = sb.toString();
//use server output getResponseString as string value.
}
chandan kumar
sumber
1

Panggil HttpURLConnection.setRequestMethod("POST")dan HttpURLConnection.setDoOutput(true);Sebenarnya hanya yang terakhir diperlukan karena POST kemudian menjadi metode default.

Marquis dari Lorne
sumber
it it HttpURLConnection.setRequestMethod () :)
Jose Diaz
1

Saya merekomendasikan menggunakan http-request yang dibangun di atas apache http api.

HttpRequest<String> httpRequest = HttpRequestBuilder.createPost("http://www.example.com/page.php", String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();

public void send(){
   String response = httpRequest.execute("id", "10").get();
}
Beno Arakelyan
sumber