JSF/Prime(FileUpload 组件)multipart-form 不加载托管 bean 类参数

Posted

技术标签:

【中文标题】JSF/Prime(FileUpload 组件)multipart-form 不加载托管 bean 类参数【英文标题】:JSF/Prime (FileUpload component) multipart-form doesn't load managed-bean class param 【发布时间】:2013-01-12 11:51:32 【问题描述】:

我正在使用在 glassfifh 3.1 上运行的 NB 7.2.1 来开发 JSF/Primefaces 3.4 Web 应用程序。因此,当提交 multipart-form enctype 时,由“FileUploadListener”触发的事件不允许加载另一个类属性(如其他 JSF inputText 中的名称或年龄)。为什么?

这是视图:

  <h:form enctype="multipart/form-data">
    <p:outputLabel value="Nome" for="nome" />
    <p:inputText value="#controller.nome" id="nome" />
    <br />
    <p:fileUpload mode="advanced" multiple="true" fileUploadListener="#controller.doSubmit" />
  </h:form>

这是豆子:

@ManagedBean
@SessionScoped
public class Controller 

  private String nome;

  public String getNome() 
    return nome;
  
  public void setNome(String nome) 
    this.nome = nome;
  

  public Controller() 
  

  public void doSubmit(FileUploadEvent event) 
    System.out.println(getNome());
  

在之前的“getName()”调用中,返回了 null。因此,一切都是相同的形式。为什么我可以检索 event.getFile() 而不能检索 getNome() ?

【问题讨论】:

【参考方案1】:

我能够使用 partialSubmit="true"process 解决类似的情况。 partialSubmit 部分处理的组件到 ajax 请求帖子。

<h:outputLabel for="saType" value="Sa Type"/>
                <p:selectOneMenu id="saType" required="true" value="#saUploadController.saDetails.listType">
                    <p:ajax event="change" partialSubmit="true"/>
                    <f:selectItem itemLabel="--select Type--"  itemValue=""/>
                    <f:selectItems value="#saUploadController.saTypes"/>
                </p:selectOneMenu>
                <h:outputLabel value="*select a file :"/> 
                <p:fileUpload id="uploadedFile1" value="#saUploadController.uploadedFile" mode="advanced" fileUploadListener="#saUploadController.handleFileUpload" allowTypes="/(\.|\/)(xml)$/" update="add:msgsAdd add:saType" process="saType"/>                      
                <p:message for="uploadedFile1" display="icon"/>

使用&lt;p:ajax event="change" partialSubmit="true"/&gt; 我们可以部分提交下拉值,通过process="saType"它将获得handleFileUpload方法的下拉项值

【讨论】:

【参考方案2】:

我能够通过使用 PrimeFaces fileupload 元素的 process 属性来解决类似的情况。我在表格中列出了文件上传后想要“提交”的所有组件,并且没有单独的按钮,只有三个。请注意,此解决方案“提交”过程中列出的组件值文件上传之后,并按照它们列出的顺序。同样,我在文件上传完成后使用 update 属性更新组件。在这种情况下,添加 process="name" 它应该做你需要的事情。

  <h:form enctype="multipart/form-data">
    <p:outputLabel value="Name" for="name" />
    <p:inputText value="#controller.name" id="name" />
    <br />
    <p:fileUpload process="name" mode="advanced" multiple="true" fileUploadListener="#controller.handleUpload" />
  </h:form>

您的托管 bean 将类似于:

    @ManagedBean
    @ViewScoped
    public class Controller 

        private String name;
        private List<File> files; // Whatever you need to get hold of all files.

        @PostConstruct
        public void init() 
            files = new ArrayList<File>();
        

        public void handleUpload(FileUploadEvent event) 
            File file = save(event.getUploadedFile()); // Do your thing to save it.
            files.add(file);
        

        public void setName(String name) 
            this.name = name;

            if(!files.isEmpty()) 
               // ... do something with name and files ...
            
        
   

【讨论】:

【参考方案3】:

“上传”按钮不会提交整个表单。它只会上传文件。 为了提交整个表单,您需要一个普通的提交按钮。

在文件上传侦听器方法中,您只需将文件作为变量保存在视图范围的 bean 中,以便您可以在与普通提交按钮关联的操作方法中对其执行必要的业务逻辑,以及所有其他输入值。

例如

<h:form enctype="multipart/form-data">
    <p:outputLabel value="Nome" for="nome" />
    <p:inputText value="#controller.nome" id="nome" />
    <br />
    <p:fileUpload mode="advanced" multiple="true" fileUploadListener="#controller.handleUpload" />
    <p:commandButton value="submit" action="#controller.doSubmit" />
</h:form>

@ManagedBean
@ViewScoped
public class Controller 

    private String nome;
    private List<File> files; // Whatever you need to get hold of all files.

    @PostConstruct
    public void init() 
        files = new ArrayList<File>();
    

    public void handleUpload(FileUploadEvent event) 
        File file = save(event.getUploadedFile()); // Do your thing to save it.
        files.add(file);
    

    public void doSubmit() 
        // Look, here you do the business job.
        System.out.println("Entered name: " + nome);
        System.out.println("Saved files: " + files);
    

    // ...

【讨论】:

谢谢,所以我将有两个发送操作:一个用于“文件上传”,另一个用于整个表单的其余部分? 是的。请注意,文件上传侦听器方法是 listener 方法,而不是操作方法(侦听器方法不支持导航并吞下任何抛出的异常)。另请注意,当您使用&lt;p:fileUpload mode="simple"&gt; 时,您显然不需要监听器:) 再次感谢@BalusC,在日常工作环境中,一些简单的事情看起来像是奇怪而黑暗的答案! @BalusC:在选择多个文件的高级模式下,用户需要单击上传组件上的上传按钮,否则将不会调用 'fileuploadlistener'。所以是否有表单提交时调用上传按钮点击事件的方式。

以上是关于JSF/Prime(FileUpload 组件)multipart-form 不加载托管 bean 类参数的主要内容,如果未能解决你的问题,请参考以下文章

java文件上传-使用apache-fileupload组件

fileupload组件的有关问题

用Commons-FileUpload组件实现文件上传

配置fileupload(文件上传组件)

使用apache的fileupload组件上传文件怎么解决编码问题?

如何使用 PrimeReact FileUpload 组件上传文件