【问题标题】:Multiple call PreDestroy method by omnifaces ViewScoped通过omnifaces ViewScoped多次调用PreDestroy方法
【发布时间】:2014-01-21 04:50:00
【问题描述】:

Initial requests 调用PostConstruct 方法。但是,当我上传图片时,有多个调用PreDestroy 方法。 这意味着,ImageActionBean 的视图 ID 已针对每个 FileUploadEvent 进行了更改。正如我认为ViewID 在重定向到另一个页面之前没有改变, 我试图清除上传文件的临时存储空间。

如果我上传三张图片,第四次调用PreDestroy 方法。这就是为什么,我至少得到一个文件。

我的环境

- JBoss 7.1.1 Final
- primefaces-4.0-20130910.075046-7
- omnifaces-1.7.jar
- jboss-jsf-api_2.1_spec-2.0.5.Final.jar

堆栈跟踪:

>>>>> Initialization Finished
>>>>> Destroy Finished
>>>>> Destroy Finished
>>>>> Destroy Finished
>>>>> Destroy Finished


<h:form id="attachmentForm" enctype="multipart/form-data">
    <p:fileUpload fileUploadListener="#{ImageActionBean.handleProposalAttachment}"  
                mode="advanced" multiple="true" sizeLimit="3000000" update="attachmentTable"
                allowTypes="/(\.|\/)(gif|jpe?g|png)$/" id="proposalAttachment"/>

</h:form>

@ManagedBean(name = "ImageActionBean")
@ViewScoped <-- org.omnifaces.cdi.ViewScoped
public class ImageActionBean implements Serializable {
    private List<String> fileList;

    @PostConstruct
    public void init() {
        fileList = new ArrayList<String>();
        System.out.println("Initialization Finished");
    }

    @PreDestroy
    public void destory() {
        // clear uploaded file from temp storage
        System.out.println("Destroy Finished");
    }

    public List<String> getFileList() {
        return fileList;
    }

    public void handleProposalAttachment(FileUploadEvent event) {
        UploadedFile uploadedFile = event.getFile();
        String fileName = uploadedFile.getFileName().replaceAll("\\s", "_");
        fileList.add(fileName);
        //save uploadedFile to temp storage
    }
}

【问题讨论】:

    标签: java jsf primefaces omnifaces


    【解决方案1】:

    The OmniFaces CDI @ViewScoped 旨在与 CDI 托管 bean 一起使用,而不是与 JSF 托管 bean 一起使用。 @ManagedBean 创建一个 JSF 托管 bean,而不是 CDI 托管 bean。 JSF 托管 bean 工具不支持 CDI 托管 bean 范围,但仅支持 JSF 托管 bean 范围。当没有显式声明任何人时,将实际使用默认范围@RequestScoped

    实际上,您的 bean 是一个请求范围的 bean,这完全解释了您观察到的症状。

    为了正确使用 OmniFaces CDI @ViewScoped,请将 @ManagedBean 替换为 @Named,使您的 bean 成为真正的 CDI 托管 bean。

    @Named
    @ViewScoped
    public class ImageActionBean implements Serializable {
    

    与具体问题无关,以大写开头的实例变量名称完全违反Java naming conventions。你实际上基本上是这样做的:

    ImageActionBean ImageActionBean = new ImageActionBean();
    

    这是绝对不推荐的。相反,您应该有效地做

    ImageActionBean imageActionBean = ImageActionBean();
    

    将 EL 变量相应地更改为 #{imageActionBean}

    【讨论】:

    • 我按照你的建议使用@NamedPostConstruct 方法可以,但是当我导航到另一个页面时它不会调用PreDestroy 方法,即使我使用h:commandLink 导航。
    • 为我工作(和展示)。 SSCCE 以及有关环境的所有详细信息会很有帮助。
    • 是的,这对我有帮助,但我很难将 CDI 与我的 jsf 版本和 JBoss 7 集成。太赫兹
    猜你喜欢
    • 2017-03-26
    • 2011-09-16
    • 2019-04-10
    • 2012-12-26
    • 2015-05-01
    • 1970-01-01
    • 2011-10-07
    • 2014-02-09
    • 1970-01-01
    相关资源
    最近更新 更多