在标签文件中显示一个使用p:graphicImage的BLOB图像。

时间:2022-10-07 01:23:40

Displaying a BLOB image using <p:graphicImage> as follows.

使用 显示一个BLOB图像,如下所示。

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

生成的在标签文件中显示一个使用p:graphicImage的BLOB图像。标签看起来很好:

<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=""/>

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.

这是由于图像的原始状态 识别图像请求的方式造成的。基本上,它将正确的值表达式#{bean[属性]}转换为字符串,对其进行加密,然后将其作为pfdrid值传递。当webbrowser需要通过一个全新的HTTP请求下载图像时,该值表达式在“当前”EL上下文中被解密和评估。然而,在这一时刻,在EL上下文中的任何地方都没有一个#{bean}或#{属性},因为没有带有标记文件的JSF视图。只有请求、会话和应用程序范围bean在EL上下文中可用。

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 在这方面做得更好,它检查了在呈现响应过程中,而不是在传输图像时对目标bean/方法进行检查。它立即检查#{bean[属性]},发现它实际上代表#{categoryBean。图像},然后成功。只是为了确保我在一个标记文件中测试了它,它对我来说很好,而PF确实是失败的。

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

这是由于图像的原始状态 识别图像请求的方式造成的。基本上,它将正确的值表达式#{bean[属性]}转换为字符串,对其进行加密,然后将其作为pfdrid值传递。当webbrowser需要通过一个全新的HTTP请求下载图像时,该值表达式在“当前”EL上下文中被解密和评估。然而,在这一时刻,在EL上下文中的任何地方都没有一个#{bean}或#{属性},因为没有带有标记文件的JSF视图。只有请求、会话和应用程序范围bean在EL上下文中可用。

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 在这方面做得更好,它检查了在呈现响应过程中,而不是在传输图像时对目标bean/方法进行检查。它立即检查#{bean[属性]},发现它实际上代表#{categoryBean。图像},然后成功。只是为了确保我在一个标记文件中测试了它,它对我来说很好,而PF确实是失败的。

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

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