pdfbox - 登录 Apache PDFBox 2.0 时出现 "You did not close a PDF Document"

标签 pdfbox

在对 PDDocument 进行数字签名后,我已关闭 Apache PDFBox 中的 PDDocument。我收到警告:当我关闭我的实例时,You did not close PDF Document。只有一个地方创建了 PDDocument 并正确关闭了它。

代码:

private byte[] buildDocument(File pdfToSign, PDVisibleSigProperties visibleSigProperties) throws Exception
{
    FileOutputStream fos = null;
    PDDocument doc = null;
    try
    {
        String signedPdfName = pdfToSign.getName().substring(0, pdfToSign.getName().indexOf("."));
        File signedFile = File.createTempFile(signedPdfName + "_signed", null);
        signedFile.deleteOnExit();

        fos = new FileOutputStream(signedFile);
        doc = PDDocument.load(pdfToSign);

        // create signature dictionary
        PDSignature signature = new PDSignature();
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);

        // subfilter for basic and PAdES Part 2 signatures
        signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
        signature.setName(visibleSigProperties.getSignerName());
        signature.setLocation(visibleSigProperties.getSignerLocation());
        signature.setReason(visibleSigProperties.getSignatureReason());

        // the signing date, needed for valid signature
        signature.setSignDate(Calendar.getInstance());

        // register signature dictionary and sign interface
        SignatureOptions options = new SignatureOptions();
        options.setVisualSignature(visibleSigProperties);
        options.setPage(visibleSigProperties.getPage() - 1);
        doc.addSignature(signature, this, options);
        byte[] pdfInBytes = IOUtils.toByteArray(new FileInputStream(signedFile));
        return pdfInBytes;
    }
    finally
    {
        if(doc != null)
        {
            // write incremental (only for signing purpose)
            doc.saveIncremental(fos);
            doc.close();
        }
        if(fos != null)
        {
            fos.flush();
            fos.close();
        }
    }

}

签名接口(interface)实现

/**
 * Signature Interface implementation
 * This is called by pdf Box 
 */
public byte[] sign(InputStream content) throws IOException
{
    try
    {
        List<Certificate> certList = new ArrayList<Certificate>();
        certList.add(getCertificate());
        Store certs = new JcaCertStore(certList);
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(getCertificate().getEncoded()));
        ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(getPrivateKey());
        gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(sha1Signer, new X509CertificateHolder(cert)));
        gen.addCertificates(certs);
        CMSProcessableInputStream msg = new CMSProcessableInputStream(content);
        CMSSignedData signedData = gen.generate(msg, false);
        return signedData.getEncoded();
    }
    catch (GeneralSecurityException e)
    {
        throw new IOException(e);
    }
    catch (CMSException e)
    {
        throw new IOException(e);
    }
    catch (OperatorCreationException e)
    {
        throw new IOException(e);
    }
}

最佳答案

关闭文档后请关闭options:

    if(doc != null)
    {
        // write incremental (only for signing purpose)
        doc.saveIncremental(fos);
        doc.close();
        IOUtils.closeQuietly(options);
    }

原因是 options 包含一个视觉签名模板。

关于pdfbox - 登录 Apache PDFBox 2.0 时出现 "You did not close a PDF Document",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37410429/

相关文章:

java - PDFbox - 获取行或文本字体大小/格式

java - 用另一个 PDFBOX 2.0.3 替换 PDImageXObject

java - 使用pdfbox库java从PDF中提取图像

pdf - 裁剪 PDF 并添加边距

java - PDFBox IllegalArgumentException : No glyph in font Webdings

java - PDFBox设置A5页面大小

java - 使用 Gradle 将 PDFBox 添加到 Android 应用程序时遇到问题?

java - 由于某种原因,首页的背景颜色不正确

java - PDFBox 和 JPEG 2000 示例的图像类型未知

java - PDFBox 或 IText 文档?