2012-11-15 46 views
0

com.I具有SWF應用程序,用戶上傳圖像,並且該圖像必須以下一個流狀態顯示。該流程使用會話範圍的bean(實際上是一個JPA實體)來存儲所有用戶輸入的數據。我可以上傳圖像,將其存儲在bean中,但PrimeFaces graphicImage facelet不會呈現它。我做了一些研究,看起來在渲染過程中,PF GI組件存儲EL會話,並隨後調用ResourceHandler(由呈現的HTML中的IMG標記生成)讀取相同的EL表達式並實際評估它。問題是ResourceHandler無法訪問流變量,因爲我存儲了所有數據,因此無法呈現圖像。如何使Primefaces graphicImage與Spring Web Flow一起使用

我擴展了PF GI組件,用會話而不是EL表達式來存儲實際圖像,但是這具有明顯的性能影響:在Session中存儲二進制數據不是一個好主意。另外,出於安全原因,我寧願將所有數據保留在流/會話範圍內,而不是會話。

是否有任何干淨的方式讓PF GI組件訪問我的流變量?

<on-start> 
    <evaluate expression="new my.models.Customers()" result="conversationScope.customer"></evaluate> 
</on-start> 

<view-state id="scanImage" view="s1-scan.xhtml" model="customer" > 
    <secured attributes="ROLE_WEB" /> 
    <transition on="submit" to="verifyImage"></transition> 
    <transition on="cancel" to="canceled"></transition> 
</view-state> 

<view-state id="verifyImage" view="s2-verifyscan.xhtml" model="customer"> 
    <secured attributes="ROLE_WEB" /> 
    <transition on="submit" to="enterDetails"></transition> 
    <transition on="back" to="scanImage"></transition> 
    <transition on="cancel" to="canceled"></transition> 
</view-state> 

圖片渲染:

<p:graphicImage value="#{customer.getImageSC()}"></p:graphicImage> 

修補的GraphicImageRenderer.getImageSrc()

protected String getImageSrc(FacesContext context, GraphicImage image) { 
    String src = null; 
String name = image.getName(); 

if(name != null) { 
    String libName = image.getLibrary(); 
    ResourceHandler handler = context.getApplication().getResourceHandler(); 
    Resource res = handler.createResource(name, libName); 

    if(res == null) { 
     return "RES_NOT_FOUND"; 
    } 
    else { 
     String requestPath = res.getRequestPath(); 

     return context.getExternalContext().encodeResourceURL(requestPath); 
    } 
} 
else { 
    Object value = image.getValue(); 

    if(value == null) { 
     return ""; 
    } 
    else if(value instanceof String) { 
     src = getResourceURL(context, (String) value); 
    } 
    else if(value instanceof StreamedContent) { 
     StreamedContent streamedContent = (StreamedContent) value; 
     Resource resource = context.getApplication().getResourceHandler().createResource("dynamiccontent", "primefaces", streamedContent.getContentType()); 
     String resourcePath = resource.getRequestPath(); 
     String rid = createUniqueContentId(context); 
     StringBuilder builder = new StringBuilder(resourcePath); 

     builder.append("&").append(Constants.DYNAMIC_CONTENT_PARAM).append("=").append(rid); 

     for(UIComponent kid : image.getChildren()) { 
      if(kid instanceof UIParameter) { 
       UIParameter param = (UIParameter) kid; 

       builder.append("&").append(param.getName()).append("=").append(param.getValue()); 
      } 
     } 

     src = builder.toString(); 

     context.getExternalContext().getSessionMap().put(rid, value); 
     // context.getExternalContext().getSessionMap().put(rid, image.getValueExpression("value").getExpressionString()); 
    } 

    if(!image.isCache()) { 
     src += src.contains("?") ? "&" : "?"; 
     src += "primefaces_image=" + UUID.randomUUID().toString(); 
    } 

    src = context.getExternalContext().encodeResourceURL(src); 
} 

    return src; 
} 

處理程序:我的代碼如下

流動

片斷

public void handleResourceRequest(FacesContext context) throws IOException { 
Map<String,String> params = context.getExternalContext().getRequestParameterMap(); 
String library = params.get("ln"); 
String dynamicContentId = params.get(Constants.DYNAMIC_CONTENT_PARAM); 

if(dynamicContentId != null && library != null && library.equals("primefaces")) { 
    Map<String,Object> session = context.getExternalContext().getSessionMap(); 
    StreamedContent streamedContent = null; 

    try { 

     Object dynamicContentEL = (Object) session.get(dynamicContentId); 

     //String dynamicContentEL = (String) session.get(dynamicContentId); 
     //ELContext eLContext = context.getELContext(); 
     //ValueExpression ve = context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), dynamicContentEL, StreamedContent.class); 
     //streamedContent = (StreamedContent) ve.getValue(eLContext); 

     streamedContent = (StreamedContent) dynamicContentEL; 

     ExternalContext externalContext = context.getExternalContext(); 
     externalContext.setResponseStatus(200); 
     externalContext.setResponseContentType(streamedContent.getContentType()); 

     byte[] buffer = new byte[2048]; 

     int length; 
     InputStream inputStream = streamedContent.getStream(); 
     while ((length = (inputStream.read(buffer))) >= 0) { 
      externalContext.getResponseOutputStream().write(buffer, 0, length); 
     } 

     externalContext.responseFlushBuffer(); 
     context.responseComplete(); 

    } catch(Exception e) { 
     logger.log(Level.SEVERE, "Error in streaming dynamic resource. {0}", new Object[]{e.getMessage()}); 
    } 
    finally { 
     //cleanup 
     session.remove(dynamicContentId); 

     if(streamedContent != null) { 
      streamedContent.getStream().close(); 
     } 
    } 
} 
else { 
    super.handleResourceRequest(context); 
} 

}

的面孔,配置:

<application> 
     <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> 
     <resource-handler>com.my.PrimeResourceHandler</resource-handler> 
    </application> 

<render-kit>  
    <renderer> 
     <component-family>org.primefaces.component</component-family> 
     <renderer-type>org.primefaces.component.graphicimage.GraphicImageRenderer</renderer-type> 
     <renderer-class>com.my.GraphicImageRenderer</renderer-class> 
    </renderer> 
</render-kit> 

我懷疑這可能與EL在Session對象存儲在一起的Webflow背景下,使資源處理程序使用該上下文時評估EL ...

回答

0

您是否修改了primefaces代碼(即GraphicImageRenderer和PrimeResourceHandler類)還是擴展它們?如果你擴展它們,代碼如何知道使用/調用擴展類?

我使用的是請求範圍,並存儲在WEB-INF文件夾中的所有圖像,並使用以下檢索它們:

<p:graphicImage value="/images/{springBean.imageFileName}"> 

我沒有對primefaces代碼進行任何更改,因爲它們可能是這種修復在更高版本中。我想,雖然使用的流動範圍,還要使用bean像下面對它們進行檢索:

<p:graphicImage value="#{springBean.imageFile}"> 

我也嘗試了圖像保存到硬盤驅動器的位置不是在webapproot並不能顯示graphicImage的。希望我可以將所有請求映射到/ images/*到一些本地文件夾,而不使用控制器/託管bean,如websphere中的以下內容?

How I save and retrieve an image on my server in a java webapp

+0

不,我沒有修改PF代碼。編輯該問題以包含faces-config.xml的相關部分 – rootkit