在标记文件中使用 p:graphicImage 显示 BLOB 图像
Display a BLOB image using p:graphicImage in a tagfile
正在使用 <p:graphicImage>
显示 BLOB 图像,如下所示。
<p:graphicImage value="#{categoryBean.image}">
<f:param name="id" value="7"/>
</p:graphicImage>
其中CategoryBean
定义如下。
@Named
@ApplicationScoped
public class CategoryBean {
@Inject
private CategoryService service;
public CategoryBean() {}
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
byte[] bytes = Utils.isNumber(id) ? service.findImageById(Long.parseLong(id)) : null;
return bytes == null ? null : new DefaultStreamedContent(new ByteArrayInputStream(bytes));
}
}
}
关于上述方法,以下自定义标签应该可以完美地工作,但它无法在 <p:graphicImage>
上显示图像,没有错误/异常。
<my:image bean="#{categoryBean}" property="image" paramName="id" paramValue="7"/>
标签文件位于 /WEB-INF/tags/image.xhtml
.
下
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<p:graphicImage value="#{bean[property]}">
<f:param name="#{paramName}" value="#{paramValue}"/>
</p:graphicImage>
</ui:composition>
生成的 <img>
标签看起来不错:
<img id="form:j_idt4"
src="/ContextPath/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=5.3&pfdrid=IA0%2F7ZuBnGS%2BSzeb%2BHyPOTo4Pxp4hjI6&pfdrt=sc&id=7&pfdrid_c=true"
alt=""/>
它只是 returns 一个 HTTP 404 错误。
给定的自定义标签的定义是否有缺陷?
这是由 PrimeFaces <p:graphicImage>
识别图像请求的方式造成的。基本上,它将精确值表达式 #{bean[property]}
转换为字符串,对其进行加密,然后将其作为 pfdrid
值传递。当网络浏览器需要通过全新的 HTTP 请求下载图像时,该值表达式在 "current" EL 上下文中被解密和评估。然而,在那一刻,EL 上下文中的任何地方都没有可用的 #{bean}
或 #{property}
,因为没有带有标记文件和所有内容的 JSF 视图。在 EL 上下文中只有请求、会话和应用程序范围的 beans 可用。
除了向 PrimeFaces 人员报告问题外,别无他法。
至于替代解决方案,OmniFaces <o:graphicImage>
通过在渲染响应期间而不是在流式传输图像期间检查目标 bean/method 在这方面做得更好。它立即检查 #{bean[property]}
,发现它实际上代表 #{categoryBean.image}
,然后成功。只是为了确保我像您一样在标记文件中测试了它,它对我来说工作正常,而 PF 确实如描述的那样失败了。
<o:graphicImage value="#{bean[property](paramValue)}" />
public byte[] getImage(Long id) throws IOException {
return service.findImageById(id);
}
正在使用 <p:graphicImage>
显示 BLOB 图像,如下所示。
<p:graphicImage value="#{categoryBean.image}">
<f:param name="id" value="7"/>
</p:graphicImage>
其中CategoryBean
定义如下。
@Named
@ApplicationScoped
public class CategoryBean {
@Inject
private CategoryService service;
public CategoryBean() {}
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
byte[] bytes = Utils.isNumber(id) ? service.findImageById(Long.parseLong(id)) : null;
return bytes == null ? null : new DefaultStreamedContent(new ByteArrayInputStream(bytes));
}
}
}
关于上述方法,以下自定义标签应该可以完美地工作,但它无法在 <p:graphicImage>
上显示图像,没有错误/异常。
<my:image bean="#{categoryBean}" property="image" paramName="id" paramValue="7"/>
标签文件位于 /WEB-INF/tags/image.xhtml
.
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<p:graphicImage value="#{bean[property]}">
<f:param name="#{paramName}" value="#{paramValue}"/>
</p:graphicImage>
</ui:composition>
生成的 <img>
标签看起来不错:
<img id="form:j_idt4"
src="/ContextPath/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=5.3&pfdrid=IA0%2F7ZuBnGS%2BSzeb%2BHyPOTo4Pxp4hjI6&pfdrt=sc&id=7&pfdrid_c=true"
alt=""/>
它只是 returns 一个 HTTP 404 错误。
给定的自定义标签的定义是否有缺陷?
这是由 PrimeFaces <p:graphicImage>
识别图像请求的方式造成的。基本上,它将精确值表达式 #{bean[property]}
转换为字符串,对其进行加密,然后将其作为 pfdrid
值传递。当网络浏览器需要通过全新的 HTTP 请求下载图像时,该值表达式在 "current" EL 上下文中被解密和评估。然而,在那一刻,EL 上下文中的任何地方都没有可用的 #{bean}
或 #{property}
,因为没有带有标记文件和所有内容的 JSF 视图。在 EL 上下文中只有请求、会话和应用程序范围的 beans 可用。
除了向 PrimeFaces 人员报告问题外,别无他法。
至于替代解决方案,OmniFaces <o:graphicImage>
通过在渲染响应期间而不是在流式传输图像期间检查目标 bean/method 在这方面做得更好。它立即检查 #{bean[property]}
,发现它实际上代表 #{categoryBean.image}
,然后成功。只是为了确保我像您一样在标记文件中测试了它,它对我来说工作正常,而 PF 确实如描述的那样失败了。
<o:graphicImage value="#{bean[property](paramValue)}" />
public byte[] getImage(Long id) throws IOException {
return service.findImageById(id);
}