PrimeFaces 10 p:graphicImage首次加载正常 跳转页面后图片消失问题
问题原因
- Primefaces 的
DefaultStreamedContent封装的InputStream是单向、仅支持单次读取的资源:首次加载图片时输入流会被完整读取消耗,流指针移动到末尾,后续再有读取请求时无法返回任何数据。 p:graphicImage组件每次渲染都会发起独立的HTTP请求获取图片内容,页面跳转后组件重新渲染,会再次请求Session中预存的StreamedContent,此时内部流已经被耗尽,自然无法加载出图片。你之前尝试的字节数组方案如果还是只预构建一次StreamedContent也会触发同样问题,本质都是流只能被消费一次。
解决方案
不要在 @PostConstruct 中预构建 StreamedContent 实例,改为存储原始图片二进制数据或文档对象,每次调用getter方法时动态构建新的 StreamedContent 实例即可。
修改后的代码示例:
SessionBean.java 调整
@Named @SessionScoped public class SessionBean implements Serializable { ... // 存储原始文档对象即可,不要直接存StreamedContent private Document userImageDoc; // 也可以提前把流读成字节数组存储,读取效率更高:private byte[] userImageBytes; // 同步存储文件元数据 private String imageContentType; private String imageFileName; @PostConstruct public void init() { ... Document d = getUsuari().getDocImatge(); this.userImageDoc = d; this.imageContentType = d.getTipus(); this.imageFileName = d.getFileName(); // 如果选择用字节数组存储,提前在这里读取: // try (InputStream is = d.getInputStream()) { // this.userImageBytes = is.readAllBytes(); // } catch (IOException e) { // 自行补充异常处理逻辑 // } ... } public StreamedContent getImgProfile() { // 每次请求都新建StreamedContent,返回全新的未读取输入流 return DefaultStreamedContent.builder() .stream(userImageDoc::getInputStream) // 字节数组版本把上面的stream替换为:.stream(() -> new ByteArrayInputStream(userImageBytes)) .contentType(imageContentType) .name(imageFileName) .build(); } ... }
index.xhtml 无需改动
原有代码可以直接正常使用:
<p:graphicImage id="img" value="#{sessionBean.imgProfile}"/>
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

