OpenHtmlToPdf无外网加载外部资源致转换卡住如何配置忽略
OpenHtmlToPdf 外链资源加载失败跳过方案
OpenHtmlToPdf 没有提供一键跳过所有外部资源的配置开关,但可以通过自定义URI解析器实现外链加载超时自动降级、不阻塞PDF生成的需求,最终可以正常输出存在资源缺失的PDF文件,不会出现进程挂起问题。
问题根因
默认配置下,OpenHtmlToPdf 加载HTTP/HTTPS外链资源时没有设置连接、读取超时,当服务器防火墙拦截网络请求、TCP连接无响应时,加载线程会一直阻塞等待响应,直到系统级TCP超时触发,表现为转换进程挂起。
实现代码
通过重写FSUriResolver自定义资源加载逻辑,给外链请求设置短超时,加载失败时返回空流让渲染流程继续:
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder; import com.openhtmltopdf.extend.FSStream; import com.openhtmltopdf.extend.FSUriResolver; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URI; public class PdfConvertConfig { public static void configUriResolver(PdfRendererBuilder builder) { builder.useUriResolver(new FSUriResolver() { // 外链加载超时时间设为3秒,可根据实际环境调整 private static final int RESOURCE_TIMEOUT_MS = 3000; @Override public FSStream resolveUri(String baseUri, String resourceUri) { // 仅对HTTP/HTTPS外链做特殊处理 if (resourceUri.startsWith("http://") || resourceUri.startsWith("https://")) { HttpURLConnection connection = null; try { URI targetUri = URI.create(resourceUri); connection = (HttpURLConnection) targetUri.toURL().openConnection(); connection.setConnectTimeout(RESOURCE_TIMEOUT_MS); connection.setReadTimeout(RESOURCE_TIMEOUT_MS); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("GET"); connection.connect(); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream resourceStream = connection.getInputStream(); return new FSStream() { @Override public InputStream getStream() { return resourceStream; } @Override public String getReader() { return null; } }; } } catch (Exception ignored) { // 所有网络异常(拦截、超时、资源不存在等)直接走降级逻辑 } finally { if (connection != null) { connection.disconnect(); } } // 外链加载失败返回空流,渲染时自动跳过该资源,不会中断转换 return new FSStream() { @Override public InputStream getStream() { return new ByteArrayInputStream(new byte[0]); } @Override public String getReader() { return null; } }; } // 本地类路径、文件系统资源走默认加载逻辑 return null; } }); } }
调用时只需要在创建PdfRendererBuilder实例后,传入该方法配置解析器,后续正常绑定HTML源、输出流执行转换即可。
优化建议
- 如果业务场景完全不需要加载任何外网资源,可以直接在外链判断分支返回空流,跳过所有网络请求,彻底避免网络相关阻塞,转换效率更高。
- 需要提示资源缺失的场景,可以将返回的空流替换为本地预置的占位图输入流,PDF中对应资源位置会显示占位提示。
- 不要修改本地资源的加载逻辑,避免影响正常的本地图片、样式表、字体文件加载。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

