48

バックエンドから受け取った圧縮ファイルを含む .zip ファイルを作成し、このファイルをユーザーに送信したいと考えています。2日間、私は答えを探していましたが、適切な解決策を見つけることができませんでした.多分あなたは私を助けることができます:)

今のところ、コードは次のようになっています: (Spring Controller ですべてを行うべきではないことはわかっていますが、それについては気にしないでください。これはテスト目的であり、機能させる方法を見つけるためです)

    @RequestMapping(value = "/zip")
    public byte[] zipFiles(HttpServletResponse response) throws IOException{
        //setting headers
        response.setContentType("application/zip");
        response.setStatus(HttpServletResponse.SC_OK);
        response.addHeader("Content-Disposition", "attachment; filename=\"test.zip\"");

        //creating byteArray stream, make it bufforable and passing this buffor to ZipOutputStream
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
        ZipOutputStream zipOutputStream = new ZipOutputStream(bufferedOutputStream);

        //simple file list, just for tests
        ArrayList<File> files = new ArrayList<>(2);
        files.add(new File("README.md"));

        //packing files
        for (File file : files) {
            //new zip entry and copying inputstream with file to zipOutputStream, after all closing streams
            zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
            FileInputStream fileInputStream = new FileInputStream(file);

            IOUtils.copy(fileInputStream, zipOutputStream);

            fileInputStream.close();
            zipOutputStream.closeEntry();
        }

        if (zipOutputStream != null) {
            zipOutputStream.finish();
            zipOutputStream.flush();
            IOUtils.closeQuietly(zipOutputStream);
        }
        IOUtils.closeQuietly(bufferedOutputStream);
        IOUtils.closeQuietly(byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }

しかし、問題は、コードを使用して、URL: localhost:8080/zip を入力すると、.zip ファイルではなく file: test.zip.html が取得されることです。

.html 拡張子を削除して test.zip だけを残すと、正しく開きます。この .html 拡張子が返されないようにするにはどうすればよいですか? なぜ追加されるのですか?

他に何ができるかわかりません。また、ByteArrayOuputStream を次のようなものに置き換えようとしていました。

OutputStream outputStream = response.getOutputStream();

メソッドを無効に設定して何も返さないようにしますが、作成された.zipファイルは破損していますか?

私のMacbookでは、test.zipを解凍した後、test.zip.cpgzを取得していましたが、これは再びtest.zipファイルなどを提供していました..

私が言ったように、Windowsでは.zipファイルが破損しており、開くことさえできませんでした。

また、拡張子 .html を自動的に削除することが最善の選択肢になると思いますが、どうすればよいでしょうか? 見た目ほど難しくないことを願っています:)ありがとう

4

4 に答える 4

36
@RequestMapping(value="/zip", produces="application/zip")
public void zipFiles(HttpServletResponse response) throws IOException {

    //setting headers  
    response.setStatus(HttpServletResponse.SC_OK);
    response.addHeader("Content-Disposition", "attachment; filename=\"test.zip\"");

    ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());

    // create a list to add files to be zipped
    ArrayList<File> files = new ArrayList<>(2);
    files.add(new File("README.md"));

    // package files
    for (File file : files) {
        //new zip entry and copying inputstream with file to zipOutputStream, after all closing streams
        zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
        FileInputStream fileInputStream = new FileInputStream(file);

        IOUtils.copy(fileInputStream, zipOutputStream);

        fileInputStream.close();
        zipOutputStream.closeEntry();
    }    

    zipOutputStream.close();
}
于 2016-11-09T00:12:05.997 に答える