根据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();
}
答案 0 :(得分:1)
发生了什么
就像控制台错误一样
净:: ERR_CONTENT_LENGTH_MISMATCH
这表示响应正文中返回的内容的实际大小与响应的Content-Length
标头中指示的大小不匹配。
为什么会发生
出现差异的原因分为两个因素:
加密通常会增加加密内容的大小。加密过程需要通过密码对内容进行模糊处理,这通常意味着投入会使内容无法使用的内容。另一方面,解密会将内容恢复为原始大小
浏览器容易缓存。如果您提供足够多次不同的文件(使用相同的文件名),您的浏览器可能只是决定它是具有相同内容的同一文件 并且仅提供缓存版本的文件。在您的情况下,您将声明对加密文件的引用,访问该文件,对其进行解密,然后将解密的内容写回加密版本的同一文件句柄中。
基于磁盘的I / O与RAM或CPU不是100%的步调。写入磁盘和从磁盘读取仍然会以RAM的形式承载等待磁盘的开销。
修复
为您的操作中涉及的每个文件生成随机/不同的文件名。这意味着加密内容的单独文件名和解密表单的单独文件名
作为上述要点的推论,打开不同的输出流到不同的文件,也使用不同的File
访问变量。
相关:强>