0

我看到我的表单中的 primeface p:graphicImage 导致在同一个浏览器选项卡中创建一个新的 windowId 。

我所有的 bean 都是窗口范围的。Myface CODI 的@WindowScoped。

由于我的业务逻辑与初始登录相关联,因此环境变量与 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>

这是我的豆子的一部分

@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

前两个“in Get Data”与对 getData 的 preRenderView 调用(此处代码中未显示)和 PostContruct 调用有关。

第三个显然是在 p:graphicImage 尝试使用新的 windowId 访问 photoStream 时创建新的 bean 实例时对 @PostConstruct 的调用。

我已通过从表单中删除 p:graphicImage 来尝试此操作,在这种情况下,永远不会进行第三次调用。

我必须使用 p:graphicImage 因为我需要从数据库中传输数据。而且我试图避免编写单独的 servlet 来流式传输图像。

此外,单独的 servlet 不是一个好的选择,因为我需要知道登录的员工才能显示图像。

请让我知道是否有任何好的解决方案来克服这个问题。

我的完整环境是 Tomcat 7 Openwebbeans Myfaces CODI Myfaces + Primefaces

4

1 回答 1

1

在stackoverflow中有很多关于使用p:graphicImage从数据库渲染图像的问题。为了使其工作,bean必须是@RequestScoped或@SessionScoped。我认为它不适用于 CODI 的特殊范围。

我建议您为此使用 servlet。如果您需要知道登录的员工,您可以将该信息放入会话映射中,然后从服务器读取。

以下解释来自 primefaces 用户指南:

动态图像显示的工作方式如下:
• 动态图像将其值表达式字符串放入具有唯一键的 http 会话中。
• 唯一会话密钥附加到指向 JSF 资源处理程序的图像 url。
• 自定义PrimeFaces ResourceHandler 从url 获取键,检索表达式字符串,如#{bean.streamedContentValue},评估它以从bean 获取StreamedContent 实例并将内容流式传输到客户端。

结果将有 2 个请求显示图像,第一个浏览器将发出加载页面的请求,然后另一个请求指向指向 JSF 资源处理程序的动态图像 url。请注意,您不能使用 viewscope bean,因为 viewscoped bean 在资源加载请求中不可用。

于 2012-09-04T15:13:01.207 回答