【问题标题】:iText error while check pdf PDF/A-1A with java使用 java 检查 pdf PDF/A-1A 时出现 iText 错误
【发布时间】:2014-10-23 15:45:09
【问题描述】:

我写的是在使用 Java iText 库版本 5.5.3 签署具体的 pdf 文件时遇到的一个错误。

Adobe Pro 验证一致性并告诉我一致性已经验证,但 iText 告诉我“/Widget 类型的注释应该有 Contents 键”。

您可以在http://www.boe.es/boe/dias/2014/08/06/pdfs/BOE-A-2014-8500.pdf获取具体文件

我在我得到的跟踪下面发布:

Caused by: com.itextpdf.text.pdf.PdfAConformanceException: Annotation of type /Widget should have Contents key.
at com.itextpdf.text.pdf.internal.PdfA1Checker.checkAnnotation(PdfA1Checker.java:462)
at com.itextpdf.text.pdf.internal.PdfAChecker.checkPdfAConformance(PdfAChecker.java:219)
at com.itextpdf.text.pdf.internal.PdfAConformanceImp.checkPdfIsoConformance(PdfAConformanceImp.java:71)
at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3426)
at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3422)
at com.itextpdf.text.pdf.PdfAnnotation.toPdf(PdfAnnotation.java:999)
at com.itextpdf.text.pdf.PdfIndirectObject.writeTo(PdfIndirectObject.java:158)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.write(PdfWriter.java:420)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:398)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:373)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:369)
at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:843)
at com.itextpdf.text.pdf.PdfStamperImp.addAnnotation(PdfStamperImp.java:1389)
at com.itextpdf.text.pdf.PdfStamperImp.addAnnotation(PdfStamperImp.java:1401)
at com.itextpdf.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:1283)

提前感谢您的回复。

【问题讨论】:

    标签: java itext standards-compliance pdfa


    【解决方案1】:

    我已尝试将此处(http://itextpdf.com/book/digitalsignatures20130304.pdf,第 29 页)的示例应用到您的 PDF 文档,一切似乎都运行良好。 代码中唯一的例外是:

    1. 创建 PdfAStamper 而不是 PdfStamper:

      PdfAStamper stamper = PdfAStamper.createSignature(reader, os, '\0', PdfAConformanceLevel.PDF_A_1B);
      
    2. 将字体设置为 PdfSignatureAppearance 以便可以嵌入字体:

      appearance.setLayer2Font(FontFactory.getFont("FreeMonoBold.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, 12));
      
    3. 设置输出意图:

      ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream("sRGB Color Space Profile.icm"));
      stamper.getWriter().setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
      

    这是一个完整的代码:

    static public void sign(String src, String dest, Certificate[] chain, PrivateKey pk, String digestAlgorithm, String provider, MakeSignature.CryptoStandard subfilter, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
        // Creating the reader and the stamper
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        PdfAStamper stamper = PdfAStamper.createSignature(reader, os, '\0', PdfAConformanceLevel.PDF_A_1B);
        // Creating the appearance
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setLayer2Font(FontFactory.getFont("FreeMonoBold.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED, 12));
        appearance.setReason(reason);
        appearance.setLocation(location);
        appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
        ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream("sRGB Color Space Profile.icm"));
        stamper.getWriter().setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
        // Creating the signature
        ExternalDigest digest = new BouncyCastleDigest();
        ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider);
        MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);
    }
    

    但您的用例可能有点不同。也许您设置了特殊选项或其他东西...您能否提供失败的示例代码?

    【讨论】:

    • 嗨亚历山大!事实上,我的用例有点不同。我已经创建了我自己的基于 iText PDFAStamper 的 PDFAStamper 并添加了一些额外的功能,但是这里涉及的代码已经足够了。我使用 PDFSigantureAppearance 的 preClose() 方法存在问题。感谢 iText 邮件列表,我知道我需要在签名文件注释中添加人类可读的描述,这是 PDF/A 规范的建议,而不是要求。我现在正在研究如何实施。
    • 嗨何塞!因此,您要添加一些文本注释作为签名的人类可读描述,然后您会得到异常“/Widget 类型的注释应该具有 Contents 键。”。对?能否请您发送一部分代码您如何添加此类注释?
    • 不,在我没有添加此注释描述之前。现在我正在尝试添加它,但我需要扩展 PDFSiganutreAppearance 并覆盖 preClose() 方法并添加以下行:sigField.put(PdfName.CONTENTS, new PdfString("some text", PdfObject.TEXT_UNICODE));
    • 如果我要添加这一行,我不会收到错误“/Widget 类型的注释应该有 Contents 键。”
    • 还没有,如果我扩展 PDFSiganutreAppearance 并覆盖 preClose() 方法添加该注释,我会克服这个异常,但我得到一个错误的签名文件。
    猜你喜欢
    • 2015-09-21
    • 2016-07-18
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 2018-05-10
    相关资源
    最近更新 更多