JavaでのHTTP POSTリクエストの送信


294

このURLを想定しましょう...

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

(ここで、IDはPOSTリクエストで送信する必要があります)

id = 10サーバーのに送信します。サーバーはpage.php、それをPOSTメソッドで受け入れます。

Javaからこれを行うにはどうすればよいですか?

私はこれを試しました:

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

しかし、それでもPOSTで送信する方法がわかりません

回答:


339

更新された回答:

一部のクラスは、元の回答では、Apache HTTPコンポーネントの新しいバージョンでは非推奨であるため、この更新を投稿します。

ちなみに、他の例については、こちらの完全なドキュメントにアクセスできます。

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

元の答え:

Apache HttpClientの使用をお勧めします。より速く、より簡単に実装できます。

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.

詳細については、次のURLを確認してくださいhttp : //hc.apache.org/


25
しばらく試してみたPostMethodところ、実際には現在HttpPoststackoverflow.com / a / 9242394/1338936のように呼び出されているようです
Martin Lyne

1
@Juan(およびMartin Lyne)はコメントをありがとうございます。答えを更新しました。
mhshams 2013年

あなたの修正された回答はまだhc.apache.orgを使用していますか?
djangofan 2013年

@djangofanはい。修正された回答にもapache-hcへのリンクがあります。
mhshams 2013年

6
インポートしたライブラリを追加する必要があります
gouchaoer '22 / 02/22

191

バニラJavaでは、POSTリクエストの送信は簡単です。から始めて、URLそれをURLConnectionusingに変換する必要はありませんurl.openConnection();。その後、それをにキャストする必要があるHttpURLConnectionので、そのsetRequestMethod()メソッドにアクセスしてメソッドを設定できます。最後に、接続を介してデータを送信するとします。

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

次に、何を送信するかを述べる必要があります。

簡単なフォームを送信する

httpフォームからの通常のPOSTには、明確に定義された形式があります。入力をこの形式に変換する必要があります。

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;

次に、適切なヘッダーを使用してフォームのコンテンツをhttpリクエストに添付し、送信します。

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の送信

javaを使用してjsonを送信することもできます。これも簡単です。

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

サーバーによってjsonのコンテンツタイプが異なることに注意してください。この質問を参照してください。


Java投稿でファイルを送信する

ファイルの送信は、形式がより複雑であるため、処理するのがより困難であると考えることができます。また、ファイルをメモリに完全にバッファリングする必要がないため、ファイルを文字列として送信するためのサポートも追加します。

このために、いくつかのヘルパーメソッドを定義します。

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

次に、これらのメソッドを使用して、次のようにマルチパート投稿リクエストを作成できます。

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
この投稿は便利ですが、かなり欠陥があります。機能するまで2日かかりました。したがって、機能させるには、StandartCharsets.UTF8をStandardCharsets.UTF_8に置き換える必要があります。borderBytesおよびfinishBoundaryBytesは、Content-Typeで送信されない2つの追加ハイフンを取得する必要があるため、boundaryBytes =( "-" + border + "\ r \ n")。get ...また、boundaryBytesを1回送信する必要があります。最初のフィールドまたは最初のフィールドが無視される前に!
アルゴマン2016年

なぜout.write(finishBoundaryBytes);ラインが必要ですか?http.connect();POSTを送信しますね。
ヤーノシュ

16
「POSTリクエストの送信はバニラJavaでは簡単です。」そして、Pythonのようなものと比較して、数十行のコードが続きrequests.post('http://httpbin.org/post', data = {'key':'value'})ます...私はJavaを初めて使用するので、これは「簡単」という言葉の非常に奇妙な使用法です:)
Lynn

1
それはJavaだと思っていたよりも比較的簡単です:)
shaahiin

不可解な\ r \ n \ r \ nはCRLF CRLF(キャリッジリターン+ラインフィード)を意味します。2x新しいラインを作成します。最初の新しい行は現在の行を終了することです。2行目は、リクエストのhttpヘッダーとhttp本文を区別することです。HTTPはASCIIベースのプロトコルです。これは、\ 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());

注意することが重要です:String.getBytes()以外のものを使用しても機能しないようです。たとえば、PrintWriterの使用は完全に失敗します。
Little Bobby Tables

5
2つの投稿データを設定する方法?コロン、カンマで区切りますか?
騒々しい猫

10
encode(String)廃止予定です。encode(String, String)エンコーディングタイプを指定するを使用する必要があります。例:encode(rawData, "UTF-8")
sudo 14年

3
最後にフォローすることをお勧めします。これにより、要求が完了し、サーバーが応答を処理する機会が得られます。conn.getResponseCode();
Szymon Jachim 14年

3
文字列全体をエンコードしないでください。各パラメータの値のみをエンコードする必要があります
user2914191

22

最初の答えは素晴らしかったが、Javaコンパイラエラーを回避するためにtry / catchを追加する必要がありました。
また、HttpResponseJavaライブラリーでのの読み方を理解するのに苦労しました。

より完全なコードは次のとおりです。

/*
 * 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は役に立ちました。
ジェイ

6
申し訳ありませんが、エラーは見つかりませんでした。導入しました。例外を処理できない場所でキャッチすることは、明らかに間違っており、e.printStackTrace()何も処理しません。
maaartinus 2014年

java.net.ConnectException:接続がタイムアウトしました:connect
kerZy Hart


5

postリクエストでパラメータを送信する最も簡単な方法:

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

あなたがやった。今、あなたは使うことができますresponsePOST。文字列として応答コンテンツを取得します。

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

POSTがデフォルトのメソッドになるため、呼び出しHttpURLConnection.setRequestMethod("POST")HttpURLConnection.setDoOutput(true);実際には後者のみが必要です。


it it HttpURLConnection.setRequestMethod():)
ホセ・ディアス

1

私は、apache http api上に構築されたhttp-requestを使用することをお勧めします。

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();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.