Java'da HTTP POST İsteği Gönderme


295

bu URL'yi varsayalım ...

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

(Burada kimliğin bir POST isteğinde gönderilmesi gerekir)

Göndermek istiyorum bir POST yönteminde kabul id = 10sunucunun page.php.

Bunu Java içinden nasıl yapabilirim?

Bunu denedim:

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

Ama yine de POST ile nasıl gönderileceğini anlayamıyorum

Yanıtlar:


340

Güncellenmiş Yanıt:

Bazı sınıflar, orijinal yanıtta, Apache HTTP Bileşenlerinin yeni sürümünde kullanımdan kaldırıldığından, bu güncelleştirmeyi gönderiyorum.

Bu arada, daha fazla örnek için belgelerin tamamına buradan ulaşabilirsiniz .

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

Orijinal Yanıt:

Apache HttpClient kullanmanızı tavsiye ederim. uygulanması daha hızlı ve kolaydır.

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.

daha fazla bilgi için bu url'yi kontrol edin: http://hc.apache.org/


25
Ellerimi almak için bir süre denedikten sonra PostMethodaslında şimdi stackoverflow.com/a/9242394/1338936HttpPost olarak adlandırılan görünüyor - sadece benim gibi bu cevabı bulan herkes için :)
Martin Lyne

1
@Juan (ve Martin Lyne) yorumlar için teşekkür ederim. Cevabı yeni güncelledim.
mhshams

Gözden geçirilmiş yanıtınız hala hc.apache.org kullanıyor mu?
djangofan

@djangofan evet. gözden geçirilmiş cevapta da apache-hc bağlantısı vardır.
mhshams

6
ithal edilen libs eklemeniz gerekir
gouchaoer

192

Vanilya Java'da bir POST isteği göndermek kolaydır. Bir başlayarak URL, biz t bir dönüştürmek gerek URLConnectionkullanarak url.openConnection();. Bundan sonra, onu bir yöntemine dökmeliyiz HttpURLConnection, böylece setRequestMethod()yöntemimizi ayarlamak için yöntemine erişebiliriz . Sonunda bağlantı üzerinden veri göndereceğimizi söylüyoruz.

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

O zaman ne göndereceğimizi belirtmemiz gerekir:

Basit bir form gönderme

Bir http formundan gelen normal bir POST, iyi tanımlanmış bir biçime sahiptir. Girişimizi şu biçime dönüştürmeliyiz:

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;

Daha sonra form içeriklerimizi uygun başlıklarla http isteğine ekleyip gönderebiliriz.

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

JSON gönderme

Json'u java kullanarak da gönderebiliriz, bu da kolaydır:

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

Farklı sunucuların json için farklı içerik türlerini kabul ettiğini unutmayın, bu soruya bakın .


Java yayını ile dosya gönderme

Biçim daha karmaşık olduğu için dosya gönderme işlemlerinin daha zor olduğu düşünülebilir. Ayrıca dosyaları dize olarak göndermek için destek ekleyeceğiz, çünkü dosyayı tam olarak belleğe arabelleğe almak istemiyoruz.

Bunun için bazı yardımcı yöntemler tanımlarız:

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

Daha sonra aşağıdaki yöntemleri kullanarak çok parçalı bir yayın isteği oluşturmak için bu yöntemleri kullanabiliriz:

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

5
Bu yazı yararlı, ancak oldukça kusurlu. Çalışması 2 günümü aldı. Çalıştırmak için StandartCharsets.UTF8 yerine StandardCharsets.UTF_8 yazmalısınız. boundaryBytes ve finishBoundaryBytes, Content-Type içinde iletilmeyen iki ek tire almalıdır, bu nedenle boundaryBytes = ("-" + sınır + "\ r \ n"). İlk alan ÖNCE veya ilk alan göz ardı edilir!
Algoman

Neden out.write(finishBoundaryBytes);hat ihtiyacı var? http.connect();POST gönderecek, değil mi?
János

17
"Vanilya Java'da bir POST isteği göndermek kolaydır." Ve sonra Python'daki gibi bir düzine kadar onlarca kod satırı takip ediyor requests.post('http://httpbin.org/post', data = {'key':'value'})… Java için yeniyim, bu benim için “kolay” kelimesinin çok garip bir kullanımı :)
Lynn

1
Java olduğunu düşündüğümden nispeten daha kolay :)
shaahiin

esrarengiz \ r \ n \ r \ n CRLF CRLF (satır başı + satır besleme) anlamına gelir. 2x yeni çizgi oluşturur. İlk yeni çizgi mevcut çizgiyi bitirmek. İkinci satır, bir istekte http üstbilgisini http gövdesinden ayırmaktır. HTTP, ASCII tabanlı bir protokoldür. \ R \ n ekleme kuralı budur.
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());

Dikkat edilmesi gereken önemli: String.getBytes () öğesinden başka bir şey kullanmak işe yaramıyor. Örneğin, bir PrintWriter kullanmak tamamen başarısız olur.
Little Bobby Tables

5
ve 2 yayın verisi nasıl ayarlanır? İki nokta üst üste ile mi virgül?
gürültülü kedi

10
encode(String)kullanımdan kaldırıldı. encode(String, String)Kodlama türünü belirten kullanmanız gerekir . Örnek: encode(rawData, "UTF-8").
sudo

3
Sonunda takip etmek isteyebilirsiniz. Bu, isteğin tamamlanmasını ve sunucunun yanıtı işleme alma şansı elde etmesini sağlar: conn.getResponseCode ();
Szymon Jachim

3
tüm dizeyi kodlamak dont .. her parametre sadece değerini kodlamak zorunda
user2914191 18:17

22

İlk cevap harikaydı, ama Java derleyici hatalarını önlemek için try / catch eklemek zorunda kaldım.
Ayrıca, nasıl okunacağını anlamakta zorlandımHttpResponse Java kütüphaneleri ile .

İşte daha eksiksiz kod:

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

EntityUtils yardımcı oldu.
Jay

6
Maalesef, herhangi bir hata yakalamadınız, tanıttınız. Bunları kaldıramayacağınız bir yerde istisnalar yakalamak oldukça yanlıştır ve e.printStackTrace()hiçbir şey yapmaz.
maaartinus

java.net.ConnectException: Bağlantı zaman aşımına uğradı: connect
kerZy Hart


5

post isteği ile parametre göndermenin en basit yolu:

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

Yaptın. şimdi kullanabilirsiniz responsePOST. Yanıt içeriğini dize olarak alın:

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

1

Arama HttpURLConnection.setRequestMethod("POST")ve HttpURLConnection.setDoOutput(true);Aslında POST varsayılan yöntem haline geldiğinden sadece ikincisine ihtiyaç vardır.


it it HttpURLConnection.setRequestMethod () :)
Jose Diaz

1

Ben apache http api üzerine inşa http-istek kullanmanızı öneririz .

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();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.