2012-07-11 119 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