Java 在JSF中读取和显示加密的PDF文件
据我所知,我实现了函数Java 在JSF中读取和显示加密的PDF文件,java,jsf,pdf,encryption,primefaces,Java,Jsf,Pdf,Encryption,Primefaces,据我所知,我实现了函数downloadPDF(),它从文件系统读取PDF文件并在浏览器中显示。此功能按预期工作 此外,我还有一个类EncryptionService,它允许我加密和/或解密给定的文件。这也可以按预期工作 不幸的是,似乎无法读取PDF文件、解密并在浏览器中显示。最后,浏览器试图反复加载文件,但没有显示任何内容 下面的代码显示了我对BalusC的PDF处理程序的简单修改 public void showDocument(String path, boolean decrypt) th
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();
}
发生了什么事 就像控制台错误所说的那样 网络::错误内容长度不匹配 这表明响应正文中返回的内容的实际大小与响应的
内容长度标题中指示的大小不匹配
为什么会这样
差异的原因包括两个因素:
- 加密通常会增加加密内容的大小。加密过程需要使用密码对内容进行模糊处理,这通常意味着加入一些东西,否则内容将无法使用。另一方面,解密将使内容恢复到原始大小
- 浏览器易于缓存。如果您提供不同文件的次数足够多(使用相同的文件名),您的浏览器可能只会确定它是具有相同内容的同一文件,而只提供文件的缓存版本。在您的例子中,您声明了对加密文件的引用,访问该文件,对其进行解密,然后将解密的内容写回到加密版本的同一文件句柄中
- 基于磁盘的I/O与RAM或CPU不是100%同步的。写入磁盘和从磁盘读取仍然以RAM等待磁盘的形式带来开销
修复
- 为操作中涉及的每个文件生成随机/不同的文件名。这意味着加密内容有一个单独的文件名,解密表单有一个单独的文件名
- 如上所述,使用不同的
File
access变量,将不同的输出流打开到不同的文件
相关:
具体是在什么点发生循环?showDocument
是否完成执行?返回浏览器的内容是什么?在浏览器的“网络”选项卡中查看响应代码、标题和响应正文package@kolossus,showDocument
未正确完成。在新选项卡中加载内容时,“网络”选项卡不会显示任何内容。当尝试在同一选项卡中加载时,它显示system.jsf(当前站点)。几秒钟后,这将导致错误net::ERR\u CONTENT\u LENGTH\u MISMATCH
。因此,您可以这样做:设置为CONTENT LENGTH的内容
!=现实中发生了什么。你能给我一个提示,这个值应该是多少吗?我真的不明白如果文件的长度变长,内容的长度应该是多少。首先,加密可能会增大文件的大小,而解密则会逆转这种效果。也就是说,您通常不希望为文件的两个变体重用相同的变量:缓存和一般I/O不可靠性可能会导致问题。因此,为了进行实验,对pdf的加密和解密形式使用单独的文件
s;不要同时重复使用文件