मैं जावा का उपयोग करके मल्टीपार्ट / फॉर्म-डेटा POST अनुरोध कैसे कर सकता हूं?


96

Apache Commons HttpClient के संस्करण 3.x के दिनों में, मल्टीपार्ट / फॉर्म-डेटा POST अनुरोध करना संभव था ( 2004 से एक उदाहरण )। दुर्भाग्य से यह अब HttpClient के संस्करण 4.0 में संभव नहीं है ।

हमारी मुख्य गतिविधि "HTTP" के लिए, मल्टीपार्ट कुछ हद तक दायरे से बाहर है। हम किसी अन्य परियोजना द्वारा बनाए गए मल्टीपार्ट कोड का उपयोग करना पसंद करेंगे, जिसके लिए यह गुंजाइश में है, लेकिन मुझे किसी के बारे में पता नहीं है। हमने कुछ साल पहले मल्टीपार्ट कोड को कॉमन्स-कोडेक में स्थानांतरित करने की कोशिश की थी, लेकिन मैंने वहां नहीं लिया। ओलेग ने हाल ही में एक और परियोजना का उल्लेख किया है जिसमें मल्टीपर्सिंग पार्सिंग कोड है और हमारी मल्टीपार्ट फॉर्मेटिंग कोड में रुचि हो सकती है। मुझे उस पर वर्तमान स्थिति का पता नहीं है। ( http://www.nabble.com/multipart-form-data-in-4.0-td14224819.html )

क्या किसी भी जावा लाइब्रेरी के बारे में पता है जो मुझे एक HTTP क्लाइंट लिखने की अनुमति देता है जो एक मल्टीपार्ट / फॉर्म-डेटा POST अनुरोध कर सकता है?

पृष्ठभूमि: मैं ज़ोहो राइटर के रिमोट एपीआई का उपयोग करना चाहता हूं ।


जवाबों:


151

मल्टीपार्ट फाइल पोस्ट बनाने के लिए हम HttpClient 4.x का उपयोग करते हैं।

अद्यतन : HttpClient 4.3 के रूप में , कुछ वर्गों को हटा दिया गया है। यहाँ नए एपीआई के साथ कोड है:

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 एपीआई के साथ कोड का मूल स्निपेट है :

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

62
आह, मल्टीपार्ट सामान को org.apache.httpcompendersors-httpmime-4.0 पर ले जाया गया है! कहीं उल्लेख किया जा सकता है: /

मैंने आपके अपडेट किए गए कोड की कोशिश की, जो छोटी फ़ाइलों के साथ ठीक काम करता है, लेकिन बड़ी फ़ाइलों के साथ काम नहीं करता है। क्या आप इस प्रश्न में
AabinGunz

हाय ZZ, मैंने अपने कोड में उपरोक्त बदलाव किया है, हालांकि, मैं अब एक नए मुद्दे का सामना कर रहा हूं - मेरा REST समापन बिंदु अनुरोध स्वीकार नहीं कर रहा है। यह निम्नलिखित मापदंडों की उम्मीद कर रहा है: ~ @ PathVariable अंतिम स्ट्रिंग आईडी, @RequestParam ("छवि") अंतिम MultipartFile छवि, @RequestParam ("l") अंतिम स्ट्रिंग l, @RequestParam ("लो") अंतिम स्ट्रिंग लो, @RequestParam (" Bac ") अंतिम स्ट्रिंग Bac, @RequestParam (" cac ") अंतिम स्ट्रिंग cac, @RequestParam (" m ") अंतिम स्ट्रिंग m ... पूर्व में, अनुरोध स्वीकार किया जा रहा था। लेकिन अब मुझे 500 त्रुटि मिल रही हैं। कोई विचार क्यों ऐसा हो रहा है?
लोगन

मैंने उत्तर को संपादित किया ताकि कोड का उदाहरण क्षैतिज स्क्रॉल न हो। --- स्क्रॉल ने मुझे एक महत्वपूर्ण अंतिम पैरामीटर को याद करने का कारण बनाया जब मैंने इसे अपने काम में उपयोग करने की कोशिश की।
जी। सिल्वी डेविस

अपडेट किए गए उत्तर के लिए यहां मावेन निर्भरताएं हैं <निर्भरता> <GroupId> org.apache.httpcompenders </ groupId> <विरूपण साक्ष्य> httpclient </ विरूपण साक्ष्य> <संस्करण> 4.3+ </ संस्करण> </ निर्भरता> <! mvnrepository.com/artifact/org.apache.httpcompenders/httpmime -> <निर्भरता> <groupId> org.apache.httpcompendersors </ groupId> <विरूपण साक्ष्य / httpmime </ विरूपण साक्ष्य> <संस्करण> 4.3.6 </ संस्करण> <संस्करण> / निर्भरता>
१६

39

मेरे पास ये मावेन निर्भरताएं हैं।

जावा कोड:

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

Pom.xml में मावेन निर्भरता:

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

1
आपको httpcore की आवश्यकता होगी, कम से कम 4.2 में, HttpEntityक्लास के लिए
अल्लॉन्ड्स

19

यदि JARs का आकार मायने रखता है (उदाहरण के लिए एप्लेट के मामले में), तो व्यक्ति सीधे http के साथ java.net का भी उपयोग कर सकता है। HttpClient के बजाय http: //ttpURLConnection।

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

Pom.xml में निर्भरता:

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

FileBody यह कहाँ से आया है? क्या एपास का उपयोग नहीं करने का एक आसान (आसान) तरीका है।
जून

6

मल्टीपार्ट में पोस्ट का उपयोग करके सर्वर पर छवियों या किसी अन्य फाइल को अपलोड करने के लिए इस कोड का उपयोग करें।

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.jarऔर commons-logging-1.1.1.jarवर्गपथ में हैं।


4

आप HTTP क्लाइंट पर बनने वाले REST एश्योर्ड का भी उपयोग कर सकते हैं । यह बहुत सरल है:

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

यह "फ़ाइल" नामक एक नियंत्रण नाम ग्रहण करेगा। आप तो एक अलग नियंत्रण नाम है, तो आप इसे निर्दिष्ट करने की आवश्यकता: multiPart("controlName", new File("/somedir/file.bin")), देख github.com/rest-assured/rest-assured/wiki/...
asmaier

REST एश्योर्ड में बहुत अच्छा API है और कई सुविधाओं का समर्थन करता है। इसके साथ काम करना खुशी की बात है। लेकिन उचित होने के लिए यह ध्यान देने योग्य है कि कुछ वार्म अप प्रक्रियाओं के कारण आपको पहली कॉल पर प्रदर्शन में कमी आ सकती है। आप इंटरनेट पर और अधिक जानकारी पा सकते हैं। यहाँ sqa.stackexchange.com/questions/39532/…
user1053510

REST एश्योर्ड एक शानदार लाइब्रेरी है, लेकिन इसे वेब एपीआई परीक्षण के लिए डिज़ाइन किया गया है और मुझे नहीं लगता कि यह उत्पादन कोड में HTTP कॉल करने के लिए सही उपकरण है, भले ही यह समान अंतर्निहित पुस्तकालयों का उपयोग करता हो।
बजे रानिल विजयरत्ने

3

यहाँ एक समाधान है कि किसी भी पुस्तकालयों की आवश्यकता नहीं है।

यह रूटीन डायरेक्टरी की हर फाइल को ट्रांसमिट करता d:/data/mpf10हैurlToConnect


String boundary = Long.toHexString(System.currentTimeMillis());
URLConnection connection = new URL(urlToConnect).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
    writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
    File dir = new File("d:/data/mpf10");
    for (File file : dir.listFiles()) {
        if (file.isDirectory()) {
            continue;
        }
        writer.println("--" + boundary);
        writer.println("Content-Disposition: form-data; name=\"" + file.getName() + "\"; filename=\"" + file.getName() + "\"");
        writer.println("Content-Type: text/plain; charset=UTF-8");
        writer.println();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
            for (String line; (line = reader.readLine()) != null;) {
                writer.println(line);
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }
    writer.println("--" + boundary + "--");
} finally {
    if (writer != null) writer.close();
}
// Connection is lazily executed whenever you request any status.
int responseCode = ((HttpURLConnection) connection).getResponseCode();
// Handle response

2

httpcomponents-client-4.0.1मेरे लिए काम किया। हालाँकि, मुझे बाहरी जार apache-mime4j-0.6.jar ( org.apache.james.mime4j ) जोड़ना reqEntity.addPart("bin", bin);होगा अन्यथा संकलन नहीं होगा। अब यह आकर्षण की तरह काम कर रहा है।


2

मुझे यह नमूना अपाचे के क्विकस्टार्ट गाइड में मिला । यह संस्करण 4.5 के लिए है:

/**
 * Example how to use multipart/form encoded POST request.
 */
public class ClientMultipartFormPost {

    public static void main(String[] args) throws Exception {
        if (args.length != 1)  {
            System.out.println("File path not given");
            System.exit(1);
        }
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost("http://localhost:8080" +
                    "/servlets-examples/servlet/RequestInfoExample");

            FileBody bin = new FileBody(new File(args[0]));
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("bin", bin)
                    .addPart("comment", comment)
                    .build();


            httppost.setEntity(reqEntity);

            System.out.println("executing request " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

0

हमारे पास jdk के बाहर किसी भी बाहरी निर्भरता या पुस्तकालयों का उपयोग किए बिना मल्टीपार्ट-फॉर्म सबमिट का शुद्ध जावा कार्यान्वयन है। 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);
    }
}

0

सर्वर के लिए मेरा कोड पोस्ट मल्टीफ़र्टाइल।

  public static HttpResponse doPost(
    String host,
    String path,
    String method,
    MultipartFile multipartFile
  ) throws IOException
  {

    HttpClient httpClient = wrapClient(host);
    HttpPost httpPost = new HttpPost(buildUrl(host, path));

    if (multipartFile != null) {

      HttpEntity httpEntity;

      ContentBody contentBody;
      contentBody = new ByteArrayBody(multipartFile.getBytes(), multipartFile.getOriginalFilename());
      httpEntity = MultipartEntityBuilder.create()
                                         .addPart("nameOfMultipartFile", contentBody)
                                         .build();

      httpPost.setEntity(httpEntity);

    }
    return httpClient.execute(httpPost);
  }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.