Java - 使用Apache Http客户端发布GZIP文件

时间:2012-09-06 10:31:54

标签: java servlets httpclient

我需要从一个java应用程序(通过Servlet)向另一个应用程序发送tar.gzip文件 - 我正在使用带有MultipartEntity的HTTP客户端来实现此目的。

在文件传输过程中,文件的大小似乎加倍 - 好像它正在被解压缩 - 并且它不再被识别为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;

这是上面代码POST到的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();
}

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

谢谢, 皮特

2 个答案:

答案 0 :(得分:3)

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

FileWriter out = new FileWriter(outputFile);

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

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

另见:


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

答案 1 :(得分: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);
    }
}