【问题标题】:<p:graphicImage> not rendering image<p:graphicImage> 不渲染图像
【发布时间】:2012-07-11 14:09:27
【问题描述】:

我有一个 JSF 页面,我想在其中显示图像。图像作为 blob 存储在数据库中。 实体如下所示:

@Entity
public class Player
{
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long            id;
    @Lob
    private byte[]          pictureData;
    @Transient
    private StreamedContent streamedPicture;

    public StreamedContent getStreamedPicture()
    {
        if (streamedPicture == null && pictureData != null)
        {
            try
            {
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                os.write(pictureData);
                streamedPicture = new DefaultStreamedContent(
                                                    new ByteArrayInputStream(
                                                                                os.toByteArray()),
                                                    "image/png");
            }
            catch (FileNotFoundException e)
            {}
            catch (IOException e)
            {}
        }
        return streamedPicture;
    }
}

JSF 页面是这样的:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

<h:head></h:head>
<body>
    <ui:repeat var="player" value="#{playerbean.cachedPlayers}">
        <h:outputText value="#{player.id}" />
        <p:graphicImage value="#{player.streamedPicture}" rendered="#{player.streamedPicture != null}"/>
    </ui:repeat>
</body>
</html>

我调用的 bean 看起来像这样:

@ManagedBean(name = "playerbean")
@SessionScoped
public class PlayerBean
        implements Serializable
{
    @EJB
    private PlayerManager   playerManager;
    private List<Player>    cachedPlayers;

    public List<Player> getCachedPlayers()
    {
        if (cachedPlayers == null)
        {
            cachedPlayers = playerManager.getAll();
        }
        return cachedPlayers;
    }
}

在调试时,我在方法handleResourceRequest() 中在PrimeResourceHandler 中设置了一个断点。我正在查看的PrimeResourceHandler 的代码包含以下内容:

try {
    String dynamicContentEL = (String) session.get(dynamicContentId);
    ELContext eLContext = context.getELContext();
    ValueExpression ve = context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), dynamicContentEL, StreamedContent.class);
    StreamedContent content = (StreamedContent) ve.getValue(eLContext);
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

    response.setContentType(content.getContentType());

    byte[] buffer = new byte[2048];

    int length;
    InputStream inputStream = content.getStream();
    while ((length = (inputStream.read(buffer))) >= 0) {
        response.getOutputStream().write(buffer, 0, length);
    }

    response.setStatus(200);
    response.getOutputStream().flush();
    context.responseComplete();

} catch(Exception e) {
    logger.log(Level.SEVERE, "Error in streaming dynamic resource.");
} finally {
    session.remove(dynamicContentId);
}

当通过StreamedContent content = (StreamedContent) ve.getValue(eLContext); 行时,content 似乎为空。这当然会导致 NullPointerException。但是在 JSF 页面中,我告诉元素如果值为 null 则不要渲染。

【问题讨论】:

标签: jsf-2 primefaces


【解决方案1】:

&lt;p:graphicImage&gt; 组件不能具有指向 SessionScoped bean 中托管属性的 value 属性。该值必须设置为 RequestScoped bean。

这是因为对 image/jpeg 内容类型 HTTP 响应的 HTTP 请求本质上是无状态的。浏览器将对 JSF 页面内容发出初始请求,然后对于呈现的每个 HTML &lt;img&gt; 标记,它将向每个 &lt;img&gt; 标记的动态生成的 url 发出单独的请求以获取这些内容。在有状态的上下文中获取图像并没有什么意义。

【讨论】:

  • 这在没有&lt;ui:repeat&gt; 的情况下有效。但是在&lt;ui:repeat&gt; 中使用&lt;p:graphicImage&gt; 是一个单独的问题,所以我接受你的回答。谢谢;-)
猜你喜欢
  • 2017-09-17
  • 2022-12-21
  • 2013-07-06
  • 2020-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多