在tagfile中使用p:graphicImage显示BLOB图像

时间:2016-02-11 12:43:49

标签: jsf primefaces http-status-code-404 graphicimage 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&amp;v=5.3&amp;pfdrid=IA0%2F7ZuBnGS%2BSzeb%2BHyPOTo4Pxp4hjI6&amp;pfdrt=sc&amp;id=7&amp;pfdrid_c=true"
     alt=""/>

它只返回HTTP 404错误。

自定义标签的定义是否有任何缺陷?

1 个答案:

答案 0 :(得分:1)

这是由PrimeFaces <p:graphicImage>识别图像请求的方式引起的。基本上,它将精确值表达式#{bean[property]}转换为字符串,对其进行加密,然后将其作为pfdrid值传递。当webbrowser需要通过全新的HTTP请求下载图像时,该值表达式在“当前”EL上下文中被解密和评估。但是,在那一刻,EL上下文中的任何地方都没有#{bean}#{property},因为没有带有标记文件和所有标记文件的JSF视图。 EL上下文中只有请求,会话和应用程序范围的bean可用。

除了在PrimeFaces报道问题之外,没有什么可以做的。

对于替代解决方案,OmniFaces <o:graphicImage>通过在呈现响应期间检查目标bean /方法而不是在流式传输图像期间,在此方面做得更好。它立即检查#{bean[property]},发现它实际上代表#{categoryBean.image},然后成功。只是为了确保我在你喜欢的标签文件中测试它并且它对我来说很好,而PF确实失败了。

<o:graphicImage value="#{bean[property](paramValue)}" />

public byte[] getImage(Long id) throws IOException {
    return service.findImageById(id);
}