2012-07-11 116 views
3

我有一个JSF页面,我想要显示图像。图像作为blob存储在数据库中。 实体看起来是这样的:<p:graphicImage> not rendering image

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

我叫豆看起来是这样的:

@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则不呈现。

+1

[如何使用在ui:repeat?中使用DefaultStreamedContent](http://stackoverflow.com/questions/10944673/how-to-use-pgraphicimage-with-defaultstreamedcontent-in -an-uirepeat) – BalusC 2012-07-13 03:28:19

回答

3

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

这是因为对image/jpeg内容类型HTTP响应的HTTP请求本质上是无状态的。浏览器将对JSF页面内容进行初始请求,然后针对呈现的每个HTML <img>标记,它将分别请求每个<img>标记的动态生成url以获取这些标记。在有状态的环境中获取图像并不合理。

+0

这个工作没有''。然而,在''内使用''是一个单独的问题,所以我接受你的答案。谢谢 ;-) – siebz0r 2012-07-12 13:55:13