2009-09-04 48 views
78

Apache Commons HttpClientのバージョン3.xの時代には、マルチパート/フォームデータのPOST要求を行うことができました(an example from 2004)。残念ながら、これはversion 4.0 of HttpClientではもう不可能です。Javaを使用してマルチパート/フォームデータのPOSTリクエストを作成するにはどうすればよいですか?

コアアクティビティが「HTTP」の場合、マルチパートは範囲外である程度 です。私たちは、一部の 他のプロジェクトで管理されているマルチパートコードを使用したいと考えていますが、それについてはわかりません。 マルチパートコードをコモンズコーデックに数年前に移動しようとしましたが、 が前に出ましたが、私はそこにはいませんでした。 Oleg氏は最近、マルチパート解析コードを持つ別の プロジェクトを紹介しました。マルチパートの書式設定コードには が関心を持つかもしれません。私はその上に現在の状態 を知らない。 (http://www.nabble.com/multipart-form-data-in-4.0-td14224819.html

は私がmultipart/form-dataのPOSTリクエストを作ることができるHTTPクライアントを書くことができます任意のJavaライブラリを認識して誰ですか?

背景:Remote API of Zoho Writerを使用します。

+0

も参照 - http://bayou.io/release/1.0/docs/http/Http_Client.html – ZhongYu

答えて

133

HttpClient 4.xを使用してマルチパートファイルの投稿を行います。

UPDATEのHttpClient 4.3のように、一部のクラスが廃止されました。ここでは、新しいAPIを使用してコードです:

HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost(url); 

FileBody bin = new FileBody(new File(fileName)); 
StringBody comment = new StringBody("Filename: " + fileName); 

MultipartEntity reqEntity = new MultipartEntity(); 
reqEntity.addPart("bin", bin); 
reqEntity.addPart("comment", comment); 
httppost.setEntity(reqEntity); 

HttpResponse response = httpclient.execute(httppost); 
HttpEntity resEntity = response.getEntity(); 
+60

ああ、マルチパートものがに移動されているorg.apache.httpcomponents-httpmime-4.0 !どこかで言及することができます:/ –

+0

小さなファイルでうまく動作し、大きなファイルでは動作しない更新されたコードを試しました。あなたはこの[質問]で私を助けることができます(http://stackoverflow.com/questions/25850077/how-to-upload-large-files-by-multipart-request-in-java) – abi1964

+0

こんにちはZZ、私は作ったしかし、私のコードの上記の変更は今、新しい問題に直面しています。私のRESTエンドポイントは要求を受け入れていません。 @RequestParam( "lo")final String lo、 @RequestParam( "image")最終的な文字列id、@RequestParam( "image")最終的なMultipartFileイメージ、 @RequestParam( "l") ( "bac")final String bac、 @RequestParam( "cac")final String cac、@RequestParam( "m")final String m ...これまでは要求が受け入れられていました。しかし、今私は500エラーを取得しています。これがなぜ起こっているのでしょうか? – Logan

2

httpcomponents-client-4.0.1私の仕事:以下

CloseableHttpClient httpClient = HttpClients.createDefault(); 
HttpPost uploadFile = new HttpPost("..."); 
MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
builder.addTextBody("field1", "yes", ContentType.TEXT_PLAIN); 

// This attaches the file to the POST: 
File f = new File("[/path/to/upload]"); 
builder.addBinaryBody(
    "file", 
    new FileInputStream(f), 
    ContentType.APPLICATION_OCTET_STREAM, 
    f.getName() 
); 

HttpEntity multipart = builder.build(); 
uploadFile.setEntity(multipart); 
CloseableHttpResponse response = httpClient.execute(uploadFile); 
HttpEntity responseEntity = response.getEntity(); 

廃止予定のHttpClient 4.0 APIとコードの本来のスニペットがあります。しかし、外付けのjarを追加する必要がありました。apache-mime4j-0.6.jarorg.apache.james.mime4j)それ以外の場合は reqEntity.addPart("bin", bin);はコンパイルされません。今は魅力のように働いています。

34

これは私が持っているMavenの依存関係です。

Javaコード:のpom.xmlで

HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httpPost = new HttpPost(url); 

FileBody uploadFilePart = new FileBody(uploadFile); 
MultipartEntity reqEntity = new MultipartEntity(); 
reqEntity.addPart("upload-file", uploadFilePart); 
httpPost.setEntity(reqEntity); 

HttpResponse response = httpclient.execute(httpPost); 

Mavenの依存性:

<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpclient</artifactId> 
    <version>4.0.1</version> 
    <scope>compile</scope> 
</dependency> 
<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpmime</artifactId> 
    <version>4.0.1</version> 
    <scope>compile</scope> 
</dependency> 
+4

+1 Maven依存関係を追加しています。時間の節約! –

+1

'HttpEntity'クラスのために少なくとも4.2でhttpcoreも必要です – alalonde

4

また、HTTPクライアント上に構築REST Assuredを使用することができます。 (例えば、アプレットの場合)JARファイルの問題の大きさならば

given().multiPart(new File("/somedir/file.bin")).when().post("/fileUpload"); 
+0

" file "という名前の制御名を仮定します。別のコントロール名を持っているなら、それを指定する必要があります: 'multiPart(" controlName "、新しいファイル("/somedir/file.bin "))'、https://github.com/rest-assured/rest -assured/wiki/Usage#multi-part-form-data – asmaier

14

、1はまた、直接のjava.net.HttpURLConnectionの代わりのHttpClientでhttpmimeを使用することができます。それは非常に簡単です。

httpclient-4.2.4:  423KB 
httpmime-4.2.4:   26KB 
httpcore-4.2.4:  222KB 
commons-codec-1.6:  228KB 
commons-logging-1.1.1: 60KB 
Sum:     959KB 

httpmime-4.2.4:   26KB 
httpcore-4.2.4:  222KB 
Sum:     248KB 

コード:ポンポンで

HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
connection.setDoOutput(true); 
connection.setRequestMethod("POST"); 

FileBody fileBody = new FileBody(new File(fileName)); 
MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.STRICT); 
multipartEntity.addPart("file", fileBody); 

connection.setRequestProperty("Content-Type", multipartEntity.getContentType().getValue()); 
OutputStream out = connection.getOutputStream(); 
try { 
    multipartEntity.writeTo(out); 
} finally { 
    out.close(); 
} 
int status = connection.getResponseCode(); 
... 

依存。xml:

<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpmime</artifactId> 
    <version>4.2.4</version> 
</dependency> 
+0

これはFileBodyの由来ですか? apace.httpcomponentsを使用しない(簡単な)方法はありますか? –

4

このコードを使用して、マルチパートの投稿を使用して画像やその他のファイルをサーバーにアップロードします。

import java.io.File; 
import java.io.IOException; 
import java.io.UnsupportedEncodingException; 

import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.ResponseHandler; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.mime.MultipartEntity; 
import org.apache.http.entity.mime.content.FileBody; 
import org.apache.http.entity.mime.content.StringBody; 
import org.apache.http.impl.client.BasicResponseHandler; 
import org.apache.http.impl.client.DefaultHttpClient; 

public class SimplePostRequestTest { 

    public static void main(String[] args) throws UnsupportedEncodingException, IOException { 
     HttpClient httpclient = new DefaultHttpClient(); 
     HttpPost httppost = new HttpPost("http://192.168.0.102/uploadtest/upload_photo"); 

     try { 
      FileBody bin = new FileBody(new File("/home/ubuntu/cd.png")); 
      StringBody id = new StringBody("3"); 
      MultipartEntity reqEntity = new MultipartEntity(); 
      reqEntity.addPart("upload_image", bin); 
      reqEntity.addPart("id", id); 
      reqEntity.addPart("image_title", new StringBody("CoolPic")); 

      httppost.setEntity(reqEntity); 
      System.out.println("Requesting : " + httppost.getRequestLine()); 
      ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
      String responseBody = httpclient.execute(httppost, responseHandler); 
      System.out.println("responseBody : " + responseBody); 

     } catch (ClientProtocolException e) { 

     } finally { 
      httpclient.getConnectionManager().shutdown(); 
     } 
    } 

} 

アップロードするには以下のファイルが必要です。

ライブラリがクラスパスにあることが httpclient-4.1.2.jar, httpcore-4.1.2.jar, httpmime-4.1.2.jar, httpclient-cache-4.1.2.jar, commons-codec.jarcommons-logging-1.1.1.jarです。

0

私たちは、jdk以外の外部依存関係やライブラリを使用せずに、multipart-form submitの純粋なjava実装を持っています。参照してくださいhttps://github.com/atulsm/https-multipart-purejava/blob/master/src/main/java/com/atul/MultipartPure.java

private static String body = "{\"key1\":\"val1\", \"key2\":\"val2\"}"; 
private static String subdata1 = "@@ -2,3 +2,4 @@\r\n"; 
private static String subdata2 = "<data>subdata2</data>"; 

public static void main(String[] args) throws Exception{   
    String url = "https://" + ip + ":" + port + "/dataupload"; 
    String token = "Basic "+ Base64.getEncoder().encodeToString((userName+":"+password).getBytes()); 

    MultipartBuilder multipart = new MultipartBuilder(url,token);  
    multipart.addFormField("entity", "main", "application/json",body); 
    multipart.addFormField("attachment", "subdata1", "application/octet-stream",subdata1); 
    multipart.addFormField("attachment", "subdata2", "application/octet-stream",subdata2);   
    List<String> response = multipart.finish();   
    for (String line : response) { 
     System.out.println(line); 
    } 
} 
関連する問題