Загрузка файлов с Java-клиента на HTTP-сервер

Я хотел бы загрузить несколько файлов на HTTP-сервер. В основном мне нужен какой-то запрос POST на сервер с несколькими параметрами и файлами. Я видел примеры только загрузки файлов, но не нашел, как также передать дополнительные параметры.

Что самое простое и бесплатное решение для этого? У кого-нибудь есть примеры загрузки файлов, которые я мог бы изучить? Я гуглил несколько часов, но (может быть, это просто один из тех дней) не мог найти именно то, что мне нужно. Лучшим решением было бы то, что не включает в себя какие-либо сторонние классы или библиотеки.

6 ответов


вы обычно используете java.net.URLConnection для запуска HTTP-запросов. Вы также обычно используете multipart/form-data кодировка для смешанного содержимого POST (двоичные и символьные данные). Нажмите на ссылку, содержит информацию и примеры как составлять multipart/form-data тело запроса. Спецификация более подробно описана в RFC2388.

вот пример стартового:

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

этот код менее подробный, когда вы используете стороннюю библиотеку, такую как Apache Commons Клиент HttpComponents.

Община Апачей FileUpload как некоторые неправильно предполагают, здесь представляет интерес только сервер. Вы не можете использовать и не нуждаетесь в нем на стороне клиента.

см. также


вот как вы это сделаете с Apache HttpClient (это решение для тех, кто не против использовать стороннюю библиотеку):

    MultipartEntity entity = new MultipartEntity();
    entity.addPart("file", new FileBody(file));

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

    HttpClient client = new DefaultHttpClient();
    HttpResponse response = client.execute(request);

нажмите ссылку Получить пример загрузки файла clint java с Apache HttpComponents

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

и библиотека downalod link

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

использовать 4.5.3.zip он отлично работает в моем коде

и мой рабочий код..

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

и использовать <form enctype="multipart/form-data"> и использовать <input type="file"> в html


Это может зависеть от вашей структуры. (для каждого из них может существовать более простое решение).

но чтобы ответить на ваш вопрос: есть много внешних библиотек для этой функции. Посмотри здесь как использовать Apache commons fileupload.