1

我的服务器上有一个 PDF 文件,需要用户从客户端下载。

使用 Spring Framework,我使用 javax.servlet.http.HttpServletResponse 创建正确的响应和相应的标头:

response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;filename="content.pdf");
response.setContentLength(content.size());

然后我使用 ServletOutputStream 来编写内容:

ServletOutputStream os;
try {
    os = response.getOutputStream();
    os.write(((ByteArrayOutputStream)baos).toByteArray());
    baos.close();
    os.flush();
    os.close();
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

在客户端,我收到 HTTP 代码 200 并收到正确的响应正文以及 PDF 文件,但没有出现“另存为...”弹出窗口。

标头配置是否有任何原因可能导致此问题,或者可能在其他地方?

谢谢你。

4

3 回答 3

0

当我运行此代码时,问题出现了

response.setHeader("Content-Disposition", "attachment;filename="content.pdf");

用于定义文件名

尝试:

response.setHeader("Content-Disposition", "attachment;filename="+"content.pdf");

它将打开对话框,并在单击保存按钮时为您提供另存为选项

于 2015-01-09T22:52:09.767 回答
0

也许:

attachment;空间filename=content.pdf

更新

public static void download(HttpServletResponse response, File file, String downloadName) throws IOException
{
    if(file == null) throw new IllegalArgumentException("file is null");

    response.reset();
    response.setHeader("Content-Length", String.valueOf(file.length()));
    response.setContentType(new MimetypesFileTypeMap().getContentType(file));
    response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadName + "\"");

    InputStream input = new FileInputStream(file);

    try
    {
        OutputStream output = response.getOutputStream();

        try
        {
            IOUtils.copy(input, output);
        }
        catch(IOException e)
        {
            e.printStackTrace();

            throw e;
        }
        finally
        {
            output.close();
        }
    }
    catch(IOException e)
    {
        throw e;
    }
    finally
    {
        input.close();
    }
}

我看到的唯一区别是在标题部分。你试过没有缓存控制、编译指示和过期吗?

更新

使用文件或流完全没有区别:

public static void download(HttpServletResponse response, InputStream input, String downloadName, String contenType) throws IOException
{
    response.reset();
    response.setHeader("Content-Length", String.valueOf(input.available()));
    response.setContentType(contenType);
    response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadName + "\"");

    OutputStream output = response.getOutputStream();
    IOUtils.copy(input, output);
    input.close();
}
于 2013-11-01T11:04:47.630 回答
0

尝试将内容类型设置为application/octet-stream

response.setContentType("application/octet-stream");

这应该强制浏览器显示“另存为...”弹出窗口。如果将其设置为application/pdf浏览器会识别文件类型并改为显示它。

于 2013-11-01T12:35:08.060 回答