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