我看到表单中的primeface p:graphicImage导致在同一个浏览器选项卡中创建一个新的windowId。
我所有的bean都是窗口范围的。 @WindowScoped of Myface CODI。
由于我的业务逻辑与初始登录相关联,因此环境变量与windowContext相关联。
当p:graphicImage尝试使用新的windowId / windowContext访问bean时,应用程序失败。
有没有办法避免这种情况?
这是我的视图文件
<h:form enctype="multipart/form-data">
<p:messages />
<p:panelGrid style="width:75%;margin:5px auto;">
<f:facet name="header">
<p:row>
<p:column colspan="3">
<h:outputText value="#{title.update}" />
</p:column>
</p:row>
</f:facet>
<p:row>
<p:column>
<p:graphicImage alt="Your Photograph" id="photo" value="#{employeeUpdateBean.photoStream}" width="80" height="80" />
</p:column>
<p:column colspan="2">
<p:fileUpload mode="advanced"
fileUploadListener="#{employeeUpdateBean.addPhotoFile}"
allowTypes="/(\.|\/)(gif|jpe?g)$/" sizeLimit="100000"
invalidSizeMessage="Please limit photo size to 100Kb"
/>
</p:column>
</p:row>
<f:facet name="footer">
<p:row>
<p:column colspan="3">
<p:commandButton value="Update" action="#{employeeUpdateBean.employeeUpdate}" ajax="false"
style="margin-left:5px;margin-right:5px;" />
</p:column>
</p:row>
</f:facet>
</p:panelGrid>
</h:form>
这是我的bean的一部分
@Named
@WindowScoped
public class EmployeeUpdateBean implements Serializable{
static final long serialVersionUID = 7l;
private static final Log log = LogFactory.getLog(EmployeeUpdateBean.class);
@Inject
private HibernateUtil hibernateUtil;
@Inject
securityHelper secHelper;
@Inject
WindowContext windowContext;
public EmployeeUpdateBean() {
}
@PostConstruct
public void getData() {
System.out.println("In Get Data");
System.out.println("windowId: "+this.windowContext.getId());
//Thread.dumpStack();
Integer id= secHelper.getEmployeeId();
System.out.println("ID"+id);
}
以下是我看到的输出。
In Get Data
windowId: f75
ID11117
In Get Data
windowId: f75
ID11117
In Get Data
windowId: 1f9
IDnull
Get Data中的前两个'与对getData的preRenderView调用(此处未在代码中显示)和PostContruct调用有关。
当p:graphicImage尝试使用新的windowId访问photoStream时,第三个显然来自对@PostConstruct的调用,当创建一个新的bean实例时。
我通过从表单中删除p:graphicImage来尝试这个,在这种情况下,永远不会进行第三次调用。
我必须使用p:graphicImage因为我需要从数据库中传输数据。我试图避免编写一个单独的servlet来流图像。
此外,单独的servlet不是一个好选择,因为我需要知道登录的员工才能显示图像。
如果有任何好的解决方案可以解决这个问题,请告诉我。
我的完整环境是 雄猫7 的OpenWebBeans Myfaces CODI Myfaces + Primefaces
答案 0 :(得分:1)
stackoverflow中有很多关于使用p:graphicImage
从数据库渲染图像的问题。
为了使它工作,bean必须是@RequestScoped或@SessionScoped。我不认为它适用于CODI的特殊范围。
我建议你使用servlet来解决这个问题。如果您需要知道登录的员工,可以将该信息放在会话映射中,然后从服务器中读取。
以下说明来自primefaces用户指南:
动态图像显示的工作原理如下:
•动态图像赋予其价值 使用唯一键将表达式字符串转换为http会话。
• 独特 会话密钥附加到指向JSF资源的图像URL 处理程序。
•自定义PrimeFaces ResourceHandler从URL获取密钥, 检索表达式字符串,如 #{bean.streamedContentValue},对其进行求值以从bean获取StreamedContent实例并将内容流式传输到客户端。
结果是 将有2个显示图像的请求,第一个浏览器将生成 请求加载页面,然后另一个加载到动态图像 url指向JSF资源处理程序。请注意,你不能 使用viewscope bean作为viewcoped bean在资源中不可用 加载请求。