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

Primefaces 13.0.5 p:media组件加载数据库PDF失败求助

PrimeFaces p:media/pe:documentViewer 无法显示数据库加载的PDF排查

问题现象

使用PrimeFaces 13.0.5的p:media组件,从数据库读取byte[]构建StreamedContent后无法显示PDF,但静态资源路径的PDF可以正常显示;测试PrimeFaces Extensions 13.0.13的pe:documentViewer也出现相同问题,浏览器控制台有报错。

现有代码

后台Bean代码

public StreamedContent getMedia() {
    StreamedContent result;
    if (this.selectedRow == null) {
        return null;
    }
    result = DefaultStreamedContent.builder()
            .contentType("application/pdf")
            .stream(() -> {
                try {
                    return new ByteArrayInputStream(this.getSelectedDokument().getDocumentAsByte());
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            })
            .build();
    return result;
}

XHTML代码

<div class="card">
    <h5>PDF</h5>
    <p:media value="#{controller.getMedia()}" width="100%" height="590px" id="media" cache="false"
           player="pdf"/>
</div>

排查步骤与修复方案

  • 确认PDF内容有效性
    将getSelectedDokument().getDocumentAsByte()返回的byte[]写入本地文件,验证是否能正常打开,排除数据库中PDF本身损坏的可能。

  • 修复StreamedContent构建逻辑
    现有代码存在两处关键问题:异常时静默返回null导致流为空、缺少必要的显示参数。修改后的代码如下:

    public StreamedContent getMedia() {
        if (this.selectedRow == null) {
            throw new FacesException("未选中文档");
        }
        byte[] pdfBytes = this.getSelectedDokument().getDocumentAsByte();
        if (pdfBytes == null || pdfBytes.length == 0) {
            throw new FacesException("文档内容为空");
        }
        return DefaultStreamedContent.builder()
                .contentType("application/pdf")
                .contentDisposition(ContentDisposition.INLINE)
                .filename("document.pdf")
                .stream(() -> new ByteArrayInputStream(pdfBytes))
                .build();
    }
    
  • 检查视图状态与请求生命周期
    确保selectedRow在请求阶段未丢失:若通过AJAX加载组件,需确认selectedRow未因视图状态失效变为null,否则会返回空的StreamedContent。同时,数据库查询等耗时操作建议提前完成,避免在getMedia()中执行导致请求超时断流。

  • 分析浏览器控制台报错
    查看控制台具体错误:若为404/500错误,说明流请求接口存在问题;若为PDF解析错误,大概率是流内容损坏或ContentType配置不正确。

  • XHTML代码优化(可选)
    将EL表达式中的getMedia()改为属性访问media,符合JSF最佳实践,避免方法被重复调用:

    <div class="card">
        <h5>PDF</h5>
        <p:media value="#{controller.media}" width="100%" height="590px" id="media" cache="false" player="pdf"/>
    </div>
    

内容的提问来源于stack exchange,提问作者Jürgen Hochköppler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:03:16