在JSF中读取和显示加密的PDF文件

时间:2014-03-31 14:29:23

标签: java jsf pdf encryption primefaces

根据BalusC's homepage我实现了函数downloadPDF(),它从文件系统读取PDF文件并在浏览器中显示。此功能按预期工作。

此外我有一个类EncryptionService,它允许我加密和/或解密给定的文件。这也符合预期。

遗憾的是,似乎无法读取PDF文件,将其解密并在浏览器中显示。它以浏览器试图反复加载文件而不显示任何内容而结束。

下面的代码显示了我对BalusC的PDF处理程序的简单修改。

public void showDocument(String path, boolean decrypt) throws IOException, InvalidKeyException {

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();

    File file = new File(path);
    BufferedInputStream input = null;
    BufferedOutputStream output = null;

    try {
        if(!decrypt)
            input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
        else {
            // update MessageDigets, return Key
            cipher.init(Cipher.DECRYPT_MODE, genKey(passphrase));

            input = new BufferedInputStream(new CipherInputStream(new FileInputStream(file), cipher), DEFAULT_BUFFER_SIZE);
        }

        response.reset();
        response.setHeader("Content-Type", "application/pdf");
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + path + "\"");

        output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }

        output.flush();
    } finally {
        try {
            input.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    facesContext.responseComplete();
}

1 个答案:

答案 0 :(得分:1)

发生了什么

就像控制台错误一样

  

净:: ERR_CONTENT_LENGTH_MISMATCH

这表示响应正文中返回的内容的实际大小与响应的Content-Length标头中指示的大小不匹配。

为什么会发生

出现差异的原因分为两个因素:

  • 加密通常会增加加密内容的大小。加密过程需要通过密码对内容进行模糊处理,这通常意味着投入会使内容无法使用的内容。另一方面,解密会将内容恢复为原始大小

  • 浏览器容易缓存。如果您提供足够多次不同的文件(使用相同的文件名),您的浏览器可能只是决定它是具有相同内容的同一文件 并且仅提供缓存版本的文件。在您的情况下,您将声明对加密文件的引用,访问该文件,对其进行解密,然后将解密的内容写回加密版本的同一文件句柄中。

  • 基于磁盘的I / O与RAM或CPU不是100%的步调。写入磁盘和从磁盘读取仍然会以RAM的形式承载等待磁盘的开销。

修复

  • 为您的操作中涉及的每个文件生成随机/不同的文件名。这意味着加密内容的单独文件名和解密表单的单独文件名

  • 作为上述要点的推论,打开不同的输出流到不同的文件,也使用不同的File访问变量。

相关: