首次提交表单后无法维护上传的文件

时间:2017-07-13 10:07:42

标签: jsf primefaces jsf-2.2

我有一个p:uploadFile组件,以便上传文件。此外,我有一个上传按钮,上传文件,并在一些变量中设置文件名。文件已正确上载,并在相应的变量中也正确设置。

问题是当我最终提交整个表单以保存我的所有更改时。此时保存上传文件的变量不再为null,但似乎我的变量中没有文件,因为文件名是空的及其内容。

详细说明。

我的xhtml页面:

<h:form name="myUploadForm" enctype="multipart/form-data">
    <p:commandButton  action="#{controller.saveAllChanges}" value="Save" ajax="false" />


    <p:dataTable....>
        <p:column ... var="currentTableRow">
            <p:commandButton value="Upload" ajax="false" title="#{msg.upload}"
                action="#{controller.uploadFile(currentTableRow)}"
                update=":table" />

            <p:fileUpload id="upload" value="#{currentTableRow.myUploadedFile}" mode="simple"
                skinSimple="true" label="Browse" auto="true" />
        </column>
    </p:dataTable>
</h:form>

我的控制器:

@ManagedBean
@ViewScoped
public class Controller implements Serializable {
    ...
    public void uploadFile(TempDTO selectedDTO) {
        FacesContext context = FacesContext.getCurrentInstance();

        if (selectedDTO.getMyUploadedFile() != null && selectedDTO.getMyUploadedFile().getSize() > 0) {
            ... 
        } 
    }

    public saveAllChanges(){
        ....
    }

}

我的TempDTO包含一个UploadedFile,如下所示。在我的表单中看到的数据表显示了一个TempDTO列表:

public class TempDTO {
    ...
    ...


    private UploadedFile myUploadedFile;


    public UploadedFile getMyUploadedFile() {
        return myUploadedFile;
    }

    public void setMyUploadedFile(UploadedFile myUploadedFile) {
        this.myUploadedFile = myUploadedFile;
    }
}

在以下情况下会发现问题:

  1. 我选择一个文件,然后按表格特定行中​​的上传按钮。
  2. 按下上传按钮时,在我的控制器中调试 uploadFile 方法会显示一切正确并且文件已正确设置。在那个阶段,我可以看到它的文件大小,文件名等。
  3. 现在没有执行任何其他操作,请按&#34;保存&#34;按钮保存表单中的所有更改。
  4. 在此阶段,除文件外,所有更改都已正确提交。 TempDTO中的myUploadedFile没有文件名,因为它的大小也是零。
  5. 我在这个阶段的想法是,当我提交整个表单以保存所有更改时, 值=&#34;#{currentTableRow.myUploadedFile}&#34; 我在上传组件中替换了每个表条目的文件。

    更新

    我做了以下更改,但我仍然没有运气。

    我在控制器中添加了一个UploadedFile,以便在我的TempDTO中手动设置上传的文件:

    @ManagedBean
    @ViewScoped
    
        public class Controller implements Serializable {
    
            private UploadedFile myUploadedFile;
    
            public UploadedFile getMyUploadedFile() {
                return myUploadedFile;
            }
    
            public void setMyTemplateFile(UploadedFile myUploadedFile) {
                this.myUploadedFile = myUploadedFile;
            }
    
            public void uploadFile(TempDTO selectedDTO) {
                FacesContext context = FacesContext.getCurrentInstance();
                selectedDTO.setTemplateFile(myUploadedFile);
                if (selectedDTO.getMyUploadedFile() != null && selectedDTO.getMyUploadedFile().getSize() > 0) {
                    ... 
                } 
            }
    
            public saveAllChanges(){
                ....
            }
        }
    

    同时更新我的​​uploadFile组件以指向我控制器内的UploadedFile而不是我的DTO:

    <p:fileUpload id="upload" value="#{controller.myUploadedFile}" mode="simple"
                        skinSimple="true" label="Browse" auto="true" />
    

    当我按下&#34; Save&#34;按钮并再次提交整个表单并调用saveAllChanges(),myUploadedFile确实有一个文件名,但 getContents() getSize()等方法返回 java。 nio.file.NoSuchFileException 所以我仍然没有文件的内容。

1 个答案:

答案 0 :(得分:0)

看起来答案如下:https://stackoverflow.com/a/8880083/1918516

&#34; 另请注意,您应该在上述方法中立即读取文件内容,而不是在稍后的HTTP请求调用的其他bean方法中读取。这是因为上载的文件内容是请求范围的,因此在稍后/不同的HTTP请求中不可用。在稍后的请求中读取它的任何尝试很可能最终都会在临时文件上出现java.io.FileNotFoundException。&#34;

所以我必须在我的实现中使用解决方法