【问题标题】:Java Http Client to upload file over POSTJava Http 客户端通过 POST 上传文件
【发布时间】:2011-10-18 12:40:43
【问题描述】:

我正在开发一个必须使用 HTTP 将文件上传到 Servlet 的 J2ME 客户端。

使用 Apache Commons FileUpload 覆盖 servlet 部分

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
{       

    ServletFileUpload upload = new ServletFileUpload();
    upload.setSizeMax(1000000);

    File fileItems = upload.parseRequest(request);

    // Process the uploaded items
    Iterator iter = fileItems.iterator();
    while (iter.hasNext()) {
        FileItem item = (FileItem) iter.next();
        File file = new File("\files\\"+item.getName());
        item.write(file);
    }
}

Commons Upload 似乎只能上传多部分文件,但不能上传 application/octect-stream。

但是对于客户端,没有 Multipart 类,在这种情况下,也不可能使用任何 HttpClient 库。

其他选项可能是使用 HTTP 块上传,但我还没有找到一个明确的例子来说明如何实现这一点,特别是在 servlet 方面。

我的选择是: - 为 http 块上传实现一个 servlet - 为 http 多部分创建实现原始客户端

我不知道如何实现上述选项。 有什么建议吗?

【问题讨论】:

    标签: java http servlets file-upload java-me


    【解决方案1】:

    通过 HTTP 发送文件应该使用multipart/form-data 编码。您的 servlet 部分很好,因为它已经使用 Apache Commons FileUpload 来解析 multipart/form-data 请求。

    但是,您的客户端部分显然不是很好,因为您似乎正在将文件内容原始写入请求正文。您需要确保您的客户发送正确的multipart/form-data 请求。具体如何执行取决于您用于发送 HTTP 请求的 API。如果是普通的java.net.URLConnection,那么你可以在this answer 底部附近的某个地方找到一个具体的例子。如果您为此使用Apache HttpComponents Client,那么这里有一个具体示例,取自their documentation

    String url = "https://example.com";
    File file = new File("/example.ext");
    
    try (CloseableHttpClient client = HttpClients.createDefault()) {
        HttpPost post = new HttpPost(url);
        HttpEntity entity = MultipartEntityBuilder.create().addPart("file", new FileBody(file)).build();
        post.setEntity(entity);
    
        try (CloseableHttpResponse response = client.execute(post)) {
            // ...
        }
    }
    

    与具体问题无关,您的服务器端代码中存在错误:

    File file = new File("\files\\"+item.getName());
    item.write(file);
    

    这可能会覆盖任何以前上传的同名文件。我建议改用File#createTempFile()

    String name = FilenameUtils.getBaseName(item.getName());
    String ext = FilenameUtils.getExtension(item.getName());
    File file = File.createTempFile(name + "_", "." + ext, new File("/files"));
    item.write(file);
    

    【讨论】:

    • 我怎样才能得到这个文件服务器端,例如通过使用 requset.getParameter 我们得到字符串值那么文件体中的文件呢......
    • @Aniket:就像使用常规 HTML 表单时一样。
    【解决方案2】:

    以下代码可用于通过 HTTP Client 4.x 上传文件(以上答案使用现在已弃用的 MultipartEntity)

    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    String uploadFile(String url, File file) throws IOException
    {
        HttpPost post = new HttpPost(url);
        post.setHeader("Accept", "application/json");
        _addAuthHeader(post);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        // fileParamName should be replaced with parameter name your REST API expect.
        builder.addPart("fileParamName", new FileBody(file));
        //builder.addPart("optionalParam", new StringBody("true", ContentType.create("text/plain", Consts.ASCII)));
        post.setEntity(builder.build());
        HttpResponse response = getClient().execute(post);;
        int httpStatus = response.getStatusLine().getStatusCode();
        String responseMsg = EntityUtils.toString(response.getEntity(), "UTF-8");
    
        // If the returned HTTP response code is not in 200 series then
        // throw the error
        if (httpStatus < 200 || httpStatus > 300) {
            throw new IOException("HTTP " + httpStatus + " - Error during upload of file: " + responseMsg);
        }
    
        return responseMsg;
    }
    

    您将需要以下 Apache 库的最新版本:httpclient、httpcore、httpmime。

    getClient() 可以替换为HttpClients.createDefault()

    【讨论】:

      【解决方案3】:

      请找到在 Java 中使用 HttpClient 的文件上传功能示例工作示例。

      package test;
      
      import java.io.File;
      import java.io.IOException;
      import java.io.UnsupportedEncodingException;
      
      import org.apache.http.HttpResponse;
      import org.apache.http.client.ClientProtocolException;
      import org.apache.http.client.HttpClient;
      import org.apache.http.client.methods.HttpPost;
      import org.apache.http.entity.FileEntity;
      import org.apache.http.impl.client.DefaultHttpClient;
      
      public class fileUpload {
      private static void executeRequest(HttpPost httpPost) {
          try {
              HttpClient client = new DefaultHttpClient();
              HttpResponse response = client.execute(httpPost);
              System.out.println("Response Code:  " + response.getStatusLine().getStatusCode());
          } catch (UnsupportedEncodingException e) {
              e.printStackTrace();
          } catch (ClientProtocolException e) {
              e.printStackTrace();
          } catch (IllegalStateException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      
      public void executeMultiPartRequest(String urlString, File file) throws IOException {
          HttpPost postRequest = new HttpPost(urlString);
          postRequest = addHeader(postRequest, "Access Token");
          try {
              postRequest.setEntity(new FileEntity(file));
          } catch (Exception ex) {
              ex.printStackTrace();
          }
          executeRequest(postRequest);
      }
      
      private static HttpPost addHeader(HttpPost httpPost, String accessToken) {
          httpPost.addHeader("Accept", "application/json;odata=verbose");
          httpPost.setHeader("Authorization", "Bearer " + accessToken);
          return httpPost;
      }
      
      public static void main(String args[]) throws IOException {
          fileUpload fileUpload = new fileUpload();
          File file = new File("C:\\users\\bgulati\\Desktop\\test.docx");
          fileUpload.executeMultiPartRequest(
                  "Here Goes the URL", file);
      
      }
      }
      

      【讨论】:

        【解决方案4】:

        感谢我狙击的所有代码...这是一些回复。

        Gradle
        
        compile "org.apache.httpcomponents:httpclient:4.4"  
        compile "org.apache.httpcomponents:httpmime:4.4"
        
        
        
        import java.io.File;
        import java.io.IOException;
        import java.io.InputStream;
        import java.io.StringWriter;
        import java.util.Map;
        
        import org.apache.commons.io.IOUtils;
        import org.apache.http.HttpEntity;
        import org.apache.http.client.ClientProtocolException;
        import org.apache.http.client.methods.CloseableHttpResponse;
        import org.apache.http.client.methods.HttpGet;
        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;
        
        
        public class HttpClientUtils {
        
            public static String post(String postUrl, Map<String, String> params,
                    Map<String, String> files) throws ClientProtocolException,
                    IOException {
                CloseableHttpResponse response = null;
                InputStream is = null;
                String results = null;
                CloseableHttpClient httpclient = HttpClients.createDefault();
        
                try {
        
                    HttpPost httppost = new HttpPost(postUrl);
        
                    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        
                    if (params != null) {
                        for (String key : params.keySet()) {
                            StringBody value = new StringBody(params.get(key),
                                    ContentType.TEXT_PLAIN);
                            builder.addPart(key, value);
                        }
                    }
        
                    if (files != null && files.size() > 0) {
                        for (String key : files.keySet()) {
                            String value = files.get(key);
                            FileBody body = new FileBody(new File(value));
                            builder.addPart(key, body);
                        }
                    }
        
                    HttpEntity reqEntity = builder.build();
                    httppost.setEntity(reqEntity);
        
                    response = httpclient.execute(httppost);
                    // assertEquals(200, response.getStatusLine().getStatusCode());
        
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        is = entity.getContent();
                        StringWriter writer = new StringWriter();
                        IOUtils.copy(is, writer, "UTF-8");
                        results = writer.toString();
                    }
        
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (Throwable t) {
                        // No-op
                    }
        
                    try {
                        if (response != null) {
                            response.close();
                        }
                    } catch (Throwable t) {
                        // No-op
                    }
        
                    httpclient.close();
                }
        
                return results;
            }
        
            public static String get(String getStr) throws IOException,
                    ClientProtocolException {
                CloseableHttpResponse response = null;
                InputStream is = null;
                String results = null;
                CloseableHttpClient httpclient = HttpClients.createDefault();
        
                try {
                    HttpGet httpGet = new HttpGet(getStr);
                    response = httpclient.execute(httpGet);
        
                    assertEquals(200, response.getStatusLine().getStatusCode());
        
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        is = entity.getContent();
                        StringWriter writer = new StringWriter();
                        IOUtils.copy(is, writer, "UTF-8");
                        results = writer.toString();
                    }
        
                } finally {
        
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (Throwable t) {
                        // No-op
                    }
        
                    try {
                        if (response != null) {
                            response.close();
                        }
                    } catch (Throwable t) {
                        // No-op
                    }
        
                    httpclient.close();
                }
        
                return results;
            }
        
        }
        

        【讨论】:

          【解决方案5】:

          无需输入血淋淋的细节,您的代码看起来还不错。

          现在您需要服务器端。我建议您使用 Jakarta FileUpload,这样您就不必实现任何东西。只需部署和配置。

          【讨论】:

          • 你读过这个问题吗?发布的代码已经使用 FileUpload 的服务器端。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-26
          • 2013-09-03
          • 2011-01-28
          • 2018-08-03
          • 2010-11-01
          • 2023-03-16
          相关资源
          最近更新 更多