p:graphicImage在Myface CODI中打开一个新的WindowId

时间:2012-09-04 12:59:27

标签: primefaces codi

我看到表单中的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

1 个答案:

答案 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在资源中不可用   加载请求。