2

あるJavaアプリから(サーブレット経由で)別のJavaアプリにtar.gzipファイルを送信する必要があります-これを実現するためにMultipartEntityでHTTPクライアントを使用しています。

ファイルの転送中に、ファイルのサイズが 2 倍になり (解凍されたかのように)、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 するサーブレット メソッドは次のとおりです。

@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 を介したヘルプはあまりないようです...どんな助けも素晴らしいでしょう.

ありがとう、ピート

4

2 に答える 2

3

具体的な問題は、次のFileWriter代わりにを使用して着信バイトを文字に変換しているために発生しFileOutputStreamます。

FileWriter out = new FileWriter(outputFile);

ZIPファイルはバイナリファイルであり、テキスト、HTML、XMLなどの文字ファイルではなく、特定のバイトシーケンスで表されます。この方法でバイトを文字に変換すると、元のバイナリコンテンツの形式が正しくないため、ファイルが正しくなくなります。もうZIPファイルとして認識できます。破損したファイルになってしまいます。

FileOutputStream代わりに使用すると、問題は解決します。これをすべてCommonsFileUploadに置き換える必要はまったくありません。

参照:


具体的な問題とは関係なく、サーバー側でクライアント側固有の絶対パスを再利用することは、セキュリティ上の理由からお勧めできませんが、遅かれ早かれそれがわかります。むしろ、ファイル名を最大限に再利用し、できればFile#createTempFile()一意のファイル名サフィックスを自動生成するために組み合わせて再利用します。

于 2012-09-07T14:18:44.607 に答える
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);
    }
}
于 2012-09-07T11:04:19.913 に答える