【问题标题】:Display a BLOB image using p:graphicImage in a tagfile在标记文件中使用 p:graphicImage 显示 BLOB 图像
【发布时间】:2016-05-22 06:01:23
【问题描述】:

使用<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));
        }
    }
}

关于上述方法,以下自定义标签应该可以正常工作,但它无法在&lt;p:graphicImage&gt; 上显示图像,没有错误/异常。

<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>

生成的&lt;img&gt; 标签看起来不错:

<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 错误。

给定的自定义标签的定义有什么缺陷吗?

【问题讨论】:

  • 我并没有感到难过,但是当我发布一个发现长期存在的错误的问题时,是否有一些伪装的 PrimeFaces 不喜欢公开暴露他们的软件中的错误并不断投反对票?

标签: jsf primefaces http-status-code-404 graphicimage tagfile


【解决方案1】:

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

除了向 PrimeFaces 人员报告问题外,没有什么可做的。

至于替代解决方案,OmniFaces &lt;o:graphicImage&gt; 通过在渲染响应期间而不是在流式传输图像期间检查目标 bean/方法,在这方面做得更好。它立即检查#{bean[property]},发现它实际上代表#{categoryBean.image},然后成功。只是为了确保我像您一样在标记文件中对其进行了测试,并且对我来说效果很好,而 PF 确实如所描述的那样失败了。

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

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

【讨论】:

  • 有一个 java.lang.NullPointerException 直接使用 &lt;o:graphicImage value="#{categoryBean.image(7)}"/&gt; (OmniFaces 2.2 / Mojarra 2.2.12) - java.lang.NullPointerException at org.omnifaces.el.MethodReference.&lt;init&gt;(MethodReference.java:45)
  • 属性当然必须是getImage。 NPE 至少是不对的,代码必须在这里抛出一个MethodNotFoundException
  • 原因报告为java.lang.NullPointerException
  • 我的意思是说,OmniFaces 不应该在这里抛出 NPE。我在一秒钟前修复了它:github.com/omnifaces/omnifaces/commit/…
  • So tiny 在一个问题中发现 PrimeFaces 和 OmniFaces 中的一个错误 ;-)
猜你喜欢
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 2019-07-05
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多