You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XSL-FO生成PDF时图片无法显示的服务器部署问题

问题分析与解决方案

你遇到的核心问题是:本地环境下FOP能正常加载Logo生成PDF,但部署到服务器后,FOP无法通过HTTP URL获取图片资源——本地时FOP和Tomcat在同一环境,localhost可直接访问;但服务器端的FOP进程访问localhost可能存在网络隔离、权限限制,或Batik引擎的资源加载配置问题。

以下是针对性的解决办法:

1. 替换为服务器可访问的外部URL

把localhost改成服务器的公网IP/域名,确保FOP能通过网络请求获取图片:

<xsl:attribute name="src">
  url('http://服务器IP:<xsl:value-of select="/endOfProjectReport/contextPort" /><xsl:value-of select="/endOfProjectReport/contextPath" />/resources/images/Logo.png')
</xsl:attribute>

注意要开放服务器对应端口的防火墙,且Tomcat允许外部访问该资源路径。

2. 直接使用文件系统绝对路径(推荐)

跳过HTTP请求,让FOP直接读取服务器本地文件,稳定性更高:

  • 在Java代码中通过ServletContext获取资源真实路径,传递给XSLT:
String logoRealPath = servletContext.getRealPath("/resources/images/Logo.png");
transformer.setParameter("logoAbsolutePath", logoRealPath);
  • 修改XSL中的图片引用:
<fo:external-graphic content-width="scale-to-fit" width="50%" scaling="uniform"
  src="url('file:<xsl:value-of select="$logoAbsolutePath" />')" />

3. 配置FOP允许加载外部资源

FOP的Batik引擎默认可能限制了外部资源读取,需在fop.xconf中添加配置:

<fop version="1.0">
  <security>
    <allow-read-from-file-system>true</allow-read-from-file-system>
    <allow-read-from-http>true</allow-read-from-http>
  </security>
</fop>

若通过代码创建FOP实例,可直接通过API配置:

FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
fopFactory.getConfParser().getSecurityHandlers().setAllowReadFromHTTP(true);
fopFactory.getConfParser().getSecurityHandlers().setAllowReadFromFileSystem(true);

4. 排查服务器本地访问权限

  • 在服务器上执行curl http://localhost:端口/contextPath/resources/images/Logo.png,确认Tomcat进程能自身访问该资源
  • 检查WAR包解压后的图片文件权限,确保Tomcat运行用户有读取权限(通常路径为Tomcat/webapps/项目名/resources/images/Logo.png)

补充说明:PDF超链接能正常显示是因为仅写入URL字符串,无需FOP渲染时加载资源;而fo:external-graphic需要FOP主动获取并嵌入图片,两者处理逻辑完全不同。

内容的提问来源于stack exchange,提问作者Boz1311

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:15:11