通过omnifaces ViewScoped多次调用PreDestroy方法

时间:2014-01-21 04:50:00

标签: java jsf primefaces omnifaces

PostConstruct调用Initial requests方法。但是,当我上传图片时,有多种调用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
    }
}

1 个答案:

答案 0 :(得分: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}