Displaying a BLOB image using <p:graphicImage>
as follows.
使用
<p:graphicImage value="#{categoryBean.image}">
<f:param name="id" value="7"/>
</p:graphicImage>
Where CategoryBean
has been defined as follows.
分类bean的定义如下。
@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));
}
}
}
Regarding the above approach, the following custom tag should work flawlessly but it fails to display the image on <p:graphicImage>
with no error / exception.
对于上面的方法,下面的自定义标记应该可以正常工作,但是它不能在
<my:image bean="#{categoryBean}" property="image" paramName="id" paramValue="7"/>
The tag file is located under /WEB-INF/tags/image.xhtml
.
标签文件位于/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>
The generated <img>
tag seems to look fine :
生成的标签看起来很好:
<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=""/>
It only returns a HTTP 404 error.
它只返回HTTP 404错误。
Is there any flaw in the definition of the custom tag given?
自定义标签的定义有什么瑕疵吗?
1 个解决方案
#1
1
It's caused by the way how PrimeFaces <p:graphicImage>
identifies image requests. Basically, it converts the exact value expression #{bean[property]}
to string, encrypts it and then passes it as pfdrid
value. When the webbrowser needs to download the image by a brand new HTTP request, that value expression is decrypted and evaluated in the "current" EL context. However, during that moment, there's nowhere a #{bean}
nor #{property}
available anywhere in the EL context because there's no means of a JSF view with tagfiles and all. Only request, session and application scoped beans are available in EL context.
这是由于图像的原始状态
There's nothing to do against this other than reporting an issue at PrimeFaces guys.
除了在黄金时段报道一个问题之外,没有什么可做的。
As to alternate solutions, OmniFaces <o:graphicImage>
does a better job in this by inspecting the target bean/method during render response already instead of during streaming the image. It immediately inspects #{bean[property]}
, discovers that it actually represents #{categoryBean.image}
, and then succeeds. Just to be sure I tested it in a tagfile like you have and it works fine for me whereas the PF one indeed fails as described.
至于其他的解决方案,OmniFaces
<o:graphicImage value="#{bean[property](paramValue)}" />
public byte[] getImage(Long id) throws IOException {
return service.findImageById(id);
}
#1
1
It's caused by the way how PrimeFaces <p:graphicImage>
identifies image requests. Basically, it converts the exact value expression #{bean[property]}
to string, encrypts it and then passes it as pfdrid
value. When the webbrowser needs to download the image by a brand new HTTP request, that value expression is decrypted and evaluated in the "current" EL context. However, during that moment, there's nowhere a #{bean}
nor #{property}
available anywhere in the EL context because there's no means of a JSF view with tagfiles and all. Only request, session and application scoped beans are available in EL context.
这是由于图像的原始状态
There's nothing to do against this other than reporting an issue at PrimeFaces guys.
除了在黄金时段报道一个问题之外,没有什么可做的。
As to alternate solutions, OmniFaces <o:graphicImage>
does a better job in this by inspecting the target bean/method during render response already instead of during streaming the image. It immediately inspects #{bean[property]}
, discovers that it actually represents #{categoryBean.image}
, and then succeeds. Just to be sure I tested it in a tagfile like you have and it works fine for me whereas the PF one indeed fails as described.
至于其他的解决方案,OmniFaces
<o:graphicImage value="#{bean[property](paramValue)}" />
public byte[] getImage(Long id) throws IOException {
return service.findImageById(id);
}