我正在使用Spring Boot和FOP生成PDF并发送回UI组件。当我使用“mvn spring-boot:run”运行Spring Boot应用程序时,一切正常(PDF会即时生成并在UI中呈现),但是,如果我将此Spring Boot应用程序打包在jar中并通过“java -jar xxx.jar”,我遇到了FOP引发的以下错误:

java.lang.IllegalArgumentException: URI is not absolute
at java.net.URI.toURL(URI.java:1088)
at org.apache.fop.fonts.FontDetectorFactory$DefaultFontDetector.detect(FontDetectorFactory.java:94)
at org.apache.fop.fonts.FontManager.autoDetectFonts(FontManager.java:229)
at org.apache.fop.fonts.DefaultFontConfigurator.configure(DefaultFontConfigurator.java:82)
at org.apache.fop.render.PrintRendererConfigurator.getCustomFontCollection(PrintRendererConfigurator.java:147)
at org.apache.fop.render.PrintRendererConfigurator.setupFontInfo(PrintRendererConfigurator.java:127)
at org.apache.fop.render.intermediate.IFUtil.setupFonts(IFUtil.java:170)
at org.apache.fop.render.intermediate.IFRenderer.setupFontInfo(IFRenderer.java:187)
at org.apache.fop.area.RenderPagesModel.<init>(RenderPagesModel.java:75)
at org.apache.fop.area.AreaTreeHandler.setupModel(AreaTreeHandler.java:135)
at org.apache.fop.area.AreaTreeHandler.<init>(AreaTreeHandler.java:105)
at org.apache.fop.render.RendererFactory.createFOEventHandler(RendererFactory.java:350)
at org.apache.fop.fo.FOTreeBuilder.<init>(FOTreeBuilder.java:107)
at org.apache.fop.apps.Fop.createDefaultHandler(Fop.java:104)
at org.apache.fop.apps.Fop.<init>(Fop.java:78)
at org.apache.fop.apps.FOUserAgent.newFop(FOUserAgent.java:182)
at org.apache.fop.apps.FopFactory.newFop(FopFactory.java:240)

...

FopFactory是使用一行配置文件(fop.xconf)的InputStream创建的:
fopFactory = FopFactory.newInstance(fopConfig.getURI(),fopConfig.getInputStream());
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

我怀疑该异常与fop.xconf中的Font配置有关,在其中我添加了两行以添加中文字体支持:
    <font kerning="yes" embed-url="/Users/matrix/Library/Fonts/msyh.ttf" embedding-mode="subset">
      <font-triplet name="MicrosoftYaHei" style="normal" weight="normal"/>
    </font>
    <font kerning="yes" embed-url="/Users/matrix/Library/Fonts/msyhbd.ttf" embedding-mode="subset">
      <font-triplet name="MicrosoftYaHei" style="normal" weight="bold"/>
    </font>

我的问题是:
1)这真的与fop.xconf文件中的字体配置有关吗?

2)如果是,该如何解决?

3)FOP是否有更好的方法来支持中文字体,例如利用主机上安装的系统字体,而不是对每个字体系列进行硬编码的字体配置。

非常感谢您的帮助。

最佳答案

经过一番挖掘,问题得以解决。这是因为在以不同模式运行Spring Boot应用程序(例如以jar或Web应用程序运行)时,Spring Boot使用不同的类加载器。以下是我为解决此问题所做的更改:

<font kerning="yes" embed-url="file:/Users/matrix/Library/Fonts/msyh.ttf" embedding-mode="subset">
  <font-triplet name="MicrosoftYaHei" style="normal" weight="normal"/>
</font>
<font kerning="yes" embed-url="file:/Users/matrix/Library/Fonts/msyhbd.ttf" embedding-mode="subset">
  <font-triplet name="MicrosoftYaHei" style="normal" weight="bold"/>
</font>

请注意嵌入网址中使用的“文件:”。那是解决这个问题的关键。

由于类加载器的不同,在xslt样式表中使用时遇到了相同的问题。根据使用的类加载器,fop可能找不到带有相对路径的外部镜像。因此,我必须使用以“http”开头的绝对URL,并将我的图像作为 public 资源,这对我来说是可以的,因为它们是徽标和图标。

关于spring-boot - 在 jar 中运行时FOP抛出“IllegalArgumentException: URI is not absolute”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36914369/

10-16 18:02