com。我有一个用户上传图像的SWF应用程序,该图像必须在下一个流状态下显示。该流使用会话范围的bean(实际上是JPA实体)来存储所有用户输入的数据。我可以上传图像,将其存储在bean中,但PrimeFaces的graphicImage facelet不会渲染它。我做了一些研究,似乎在渲染过程中,PF GI组件存储了要用会话评估的EL表达式,随后对ResourceHandler的调用(由呈现的HTML中的IMG标记构成)获取相同的EL表达式并实际对其进行求值。问题是ResourceHandler无法访问我存储所有数据的流量变量,因此无法呈现图像。
我将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>
Patched 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>
我怀疑可以将Webflow上下文与EL一起存储在Session对象中,并使资源处理程序在评估EL时使用该上下文...
答案 0 :(得分:0)
您是否修改了primefaces代码(即GraphicImageRenderer和PrimeResourceHandler类)或扩展它们?如果你扩展了它们,代码如何知道使用/调用扩展类?
我正在使用请求范围并将所有图像存储在WEB-INF文件夹中并使用以下内容检索它们:
<p:graphicImage value="/images/{springBean.imageFileName}">
我没有对primefaces代码进行任何更改,因为它们可能会在以后的版本中对此进行修复。我喜欢使用流量范围,也想使用下面的bean检索它们:
<p:graphicImage value="#{springBean.imageFile}">
我还尝试将图像保存到不在webapproot中的硬盘驱动器位置,并且无法显示graphicImage。希望我可以将所有请求映射到/ images / *到某个本地文件夹而不使用websphere中的控制器/托管bean,如下所示?
How I save and retrieve an image on my server in a java webapp