Question

I'd like to upload a few files to a HTTP server. Basically what I need is some sort of a POST request to the server with a few parameters and the files. I've seen examples of just uploading files, but didn't find how to also pass additional parameters.

What's the simplest and free solution of doing this? Does anyone have any file upload examples that I could study? I've been googling for a few hours, but (maybe it's just one of those days) couldn't find exactly what I needed. The best solution would be something that doesn't involve any third party classes or libraries.

Was it helpful?

Solution

You'd normally use java.net.URLConnection to fire HTTP requests. You'd also normally use multipart/form-data encoding for mixed POST content (binary and character data). Click the link, it contains information and an example how to compose a multipart/form-data request body. The specification is in more detail described in RFC2388.

Here's a kickoff example:

String url = "http://example.com/upload";
String charset = "UTF-8";
String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

try (
    OutputStream output = connection.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
) {
    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF).append(param).append(CRLF).flush();

    // Send text file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();
    Files.copy(textFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    Files.copy(binaryFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF).flush();
}

// Request is lazily fired whenever you need to obtain information about response.
int responseCode = ((HttpURLConnection) connection).getResponseCode();
System.out.println(responseCode); // Should be 200

This code is less verbose when you use a 3rd party library like Apache Commons HttpComponents Client.

The Apache Commons FileUpload as some incorrectly suggest here is only of interest in the server side. You can't use and don't need it at the client side.

See also

OTHER TIPS

Here is how you would do it with Apache HttpClient (this solution is for those who don't mind using a 3rd party library):

    HttpEntity entity = MultipartEntityBuilder.create()
                       .addPart("file", new FileBody(file))
                       .build();

    HttpPost request = new HttpPost(url);
    request.setEntity(entity);

    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute(request);

click link get example file upload clint java with apache HttpComponents

http://hc.apache.org/httpcomponents-client-ga/httpmime/examples/org/apache/http/examples/entity/mime/ClientMultipartFormPost.java

and library downalod link

https://hc.apache.org/downloads.cgi

use 4.5.3.zip it's working fine in my code

and my working code..

import java.io.File;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class ClientMultipartFormPost {

     public static void main(String[] args) throws Exception {

          CloseableHttpClient httpclient = HttpClients.createDefault();
          try {
             HttpPost httppost = new HttpPost("http://localhost:8080/MyWebSite1/UploadDownloadFileServlet");

             FileBody bin = new FileBody(new File("E:\\meter.jpg"));
             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();
      }
   }

}
public static String simSearchByImgURL(int  catid ,String imgurl) throws IOException{
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    String result =null;
    try {
        HttpPost httppost = new HttpPost("http://api0.visualsearchapi.com:8084/vsearchtech/api/v1.0/apisim_search");
        StringBody catidBody = new StringBody(catid+"" , ContentType.TEXT_PLAIN);
        StringBody keyBody = new StringBody(APPKEY , ContentType.TEXT_PLAIN);
        StringBody langBody = new StringBody(LANG , ContentType.TEXT_PLAIN);
        StringBody fmtBody = new StringBody(FMT , ContentType.TEXT_PLAIN);
        StringBody imgurlBody = new StringBody(imgurl , ContentType.TEXT_PLAIN);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addPart("apikey", keyBody).addPart("catid", catidBody)
        .addPart("lang", langBody)
        .addPart("fmt", fmtBody)
        .addPart("imgurl", imgurlBody);
        HttpEntity reqEntity =  builder.build();
        httppost.setEntity(reqEntity);
        response = httpClient.execute(httppost);
        HttpEntity resEntity = response.getEntity();
        if (resEntity != null) {
           // result = ConvertStreamToString(resEntity.getContent(), "UTF-8");
            String charset = "UTF-8";   
          String content=EntityUtils.toString(response.getEntity(), charset);   
            System.out.println(content);
        }
        EntityUtils.consume(resEntity);
    }catch(Exception e){
        e.printStackTrace();
    }finally {
        response.close();
        httpClient.close();
    }
    return result;
}
protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    boolean isMultipart = ServletFileUpload.isMultipartContent(request);

    if (!isMultipart) {
        return;
    }

    DiskFileItemFactory factory = new DiskFileItemFactory();

    factory.setSizeThreshold(MAX_MEMORY_SIZE);

    factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

    String uploadFolder = getServletContext().getRealPath("")
            + File.separator + DATA_DIRECTORY;//DATA_DIRECTORY is directory where you upload this file on the server

    ServletFileUpload upload = new ServletFileUpload(factory);

    upload.setSizeMax(MAX_REQUEST_SIZE);//MAX_REQUEST_SIZE is the size which size you prefer

And use <form enctype="multipart/form-data"> and use <input type="file"> in the html

It could depend on your framework. (for each of them could exist an easier solution).

But to answer your question: there are a lot of external libraries for this functionality. Look here how to use apache commons fileupload.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top