【问题标题】:Java - Posting GZIP file using Apache Http clientJava - 使用 Apache Http 客户端发布 GZIP 文件
【发布时间】:2012-09-06 10:31:53
【问题描述】:

我需要将 tar.gzip 文件从一个 java 应用程序(通过 Servlet)发送到另一个 - 我正在使用 HTTP 客户端和 MultipartEntity 来实现这一点。

在文件传输过程中,文件的大小似乎翻了一番 - 好像它正在被解压缩 - 并且它不再被识别为 tar.gz 或 tar 文件。

这里是发送方法:

    HttpClient http = new DefaultHttpClient();
    HttpPost post = new HttpPost(url);

    MultipartEntity multipart = new MultipartEntity();
    ContentBody fileContent = new FileBody(file, "application/octet-stream");
    ContentBody pathContent = new StringBody(file.getAbsolutePath());

    multipart.addPart("package", fileContent);
    multipart.addPart("path", pathContent);

    post.setEntity(multipart);
    HttpResponse response = null;

    try {
        response = http.execute(post);
        StringWriter sw = new StringWriter();
        IOUtils.copy(response.getEntity().getContent(), sw);
    } catch (Exception ex){
        log.error("Unable to POST to ["+url+"].",ex);
    }

    return result;

这是上面代码发布到的 servlet 方法:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    log.info("File transfer request received, collecting file information and saving to server.");
    Part filePart = req.getPart("package");
    Part filePathPart = req.getPart("path");

    StringWriter sw = new StringWriter();
    IOUtils.copy(filePathPart.getInputStream(), sw);
    String path = sw.getBuffer().toString();

    File outputFile = new File(path);

    FileWriter out = new FileWriter(outputFile);
    IOUtils.copy(filePart.getInputStream(), out);

    log.info("File ["+path+"] has been saved to the server.");

    out.close();
    sw.close();
}

我不是这方面的专家 - 而且 Google 似乎没有太多帮助...任何帮助都会很棒。

谢谢, 皮特

【问题讨论】:

    标签: java servlets httpclient


    【解决方案1】:

    您的具体问题是因为您在这里使用FileWriter 而不是FileOutputStream 将传入的字节转换为字符:

    FileWriter out = new FileWriter(outputFile);
    

    ZIP 文件是二进制文件,由特定的字节序列表示,而不是文本、HTML、XML 等字符文件。通过这种方式将字节转换为字符,您只会破坏原始二进制内容,从而导致文件不再可识别为 ZIP 文件。你最终会得到一个损坏的文件。

    如果您改用FileOutputStream,那么您的问题将得到解决。完全没有必要用 Commons FileUpload 替换这一切。

    另见:


    与具体问题无关,出于安全原因,在服务器端重用客户端特定的绝对路径并不是一个好主意,但您迟早会发现这一点。最好重用文件名,最好与 File#createTempFile() 结合使用以自动生成唯一的文件名后缀。

    【讨论】:

      【解决方案2】:

      我使用Apache commons File Upload 完成了这项工作:

      发送代码:

          HttpClient http = new DefaultHttpClient();
          HttpPost post = new HttpPost(url);
      
          post.addHeader("path", file.getAbsolutePath());       
          MultipartEntity multipart = new MultipartEntity();
          ContentBody fileContent = new FileBody(file); //For tar.gz: "application/x-gzip"
          multipart.addPart("package", fileContent);
      
          post.setEntity(multipart);
      

      接收代码:

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          log.info("File transfer request received, collecting file information and saving to server.");
      
          FileItemFactory factory = new DiskFileItemFactory();
          ServletFileUpload upload = new ServletFileUpload(factory);
      
          try {
              List fileItems = upload.parseRequest(req);
              Iterator iterator = fileItems.iterator();
              if (iterator.hasNext()){
                  FileItem fileItem = (FileItem) iterator.next();
                  File file = new File(req.getHeader("path"));
                  fileItem.write(file);
                  log.info("File ["+fileItem.getName()+"] has been saved to the server.");
              }
          } catch (Exception ex) {
              log.error("Unable to retrieve or write file set...",ex);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-13
        • 1970-01-01
        • 2013-05-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多