Jsf 如何使用PrimeFaces p:fileUpload?侦听器方法从未被调用或上载文件为null/引发错误/不可用

Jsf 如何使用PrimeFaces p:fileUpload?侦听器方法从未被调用或上载文件为null/引发错误/不可用,jsf,file-upload,jsf-2,primefaces,Jsf,File Upload,Jsf 2,Primefaces,我正在尝试使用PrimeFaces上载文件,但上载完成后不会调用fileUploadListener方法 以下是视图: <h:form> <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}" mode="advanced" update="messages" sizeLimit="100000" allow

我正在尝试使用PrimeFaces上载文件,但上载完成后不会调用fileUploadListener方法

以下是视图:

<h:form>
    <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}"
        mode="advanced" 
        update="messages"
        sizeLimit="100000" 
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>

    <p:growl id="messages" showDetail="true"/>
</h:form>

我在方法上放置了一个断点,但从未调用它。当使用mode=simple和ajax=false时,会调用它,但我希望它在高级模式下工作。我正在使用Netbeans和Glassfish 3.1。

如何配置和排除故障取决于PrimeFaces和JSF版本

所有PrimeFaces版本 以下要求适用于所有PrimeFaces版本:

需要将的enctype属性设置为multipart/form data。如果没有这种功能,ajax上传可能会正常工作,但是一般的浏览器行为是未指定的,并且取决于表单组成和webbrowser make/version。只要始终指定它是安全的

当使用mode=advanced,即ajax上传时,这是默认设置,然后确保主模板中有一个。这将确保正确包含必要的JavaScript文件。mode=simple非ajax上传不需要这样做,但这会破坏所有其他PrimeFaces组件的外观和功能,所以无论如何,您都不想错过这一点

当使用mode=simple,即非ajax上传时,必须通过ajax=false在任何PrimeFaces命令按钮/链接上禁用ajax,并且必须使用with而不是

因此,如果您希望使用ajax支持自动上传文件,请注意!:

或者,如果您想要非ajax文件上载:

<h:form enctype="multipart/form-data">
    <p:fileUpload mode="simple" value="#{bean.uploadedFile}" />
    <p:commandButton value="Upload" action="#{bean.upload}" ajax="false" />
</h:form>
请注意,在mode=simple中会忽略与ajax相关的属性,如auto、allowTypes、update、onstart、oncomplete等。因此,在这种情况下,无需指定它们

还要注意,您应该立即在上述方法中读取文件内容,而不是在稍后HTTP请求调用的其他bean方法中读取。这是因为上传的文件内容属于请求范围,因此在以后的/不同的HTTP请求中不可用。在以后的请求中读取它的任何尝试都很可能在临时文件上以java.io.FileNotFoundException结束

PrimeFaces 8.x 配置与下面的5.x版本信息相同,但如果未调用侦听器,请检查method属性是否为listener,是否与8.x版本之前的fileUploadListener不同

PrimeFaces 5.x 如果您使用的是JSF2.2,并且您的faces-config.xml也声明为符合JSF2.2版本,那么这不需要任何额外的配置。您根本不需要PrimeFaces文件上载筛选器,也不需要web.xml中的PrimeFaces.UPLOADER上下文参数。如果您不清楚如何根据所使用的目标服务器正确安装和配置JSF,请转到和

但是,如果您还没有使用JSF 2.2,并且无法升级它,那么在Servlet 3.0兼容的容器上就应该可以轻松升级,然后,您需要在web.xml中手动注册以下PrimeFaces文件上载筛选器,它将解析多部分请求并填充常规请求参数映射,以便FacesServlet可以继续正常工作:

<filter>
    <filter-name>primeFacesFileUploadFilter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>primeFacesFileUploadFilter</filter-name>
    <servlet-name>facesServlet</servlet-name>
</filter-mapping>
故障排除 如果仍然不起作用,以下是与PrimeFaces配置无关的其他可能原因:

仅当您使用PrimeFaces文件上载筛选器时:您的Web应用程序中有另一个筛选器在PrimeFaces文件上载筛选器之前运行,并且已经通过调用getParameter、getParameterMap、getReader等方式使用了请求正文。请求正文只能解析一次。当您在文件上载筛选器完成其工作之前调用其中一个方法时,文件上载筛选器将获得一个空的请求正文

要解决这个问题,您需要在web.xml中将文件上载过滤器的名称放在另一个过滤器之前。如果请求不是一个多部分/表单数据请求,那么文件上传过滤器将继续,就像什么都没有发生一样。如果您使用自动添加的过滤器,因为它们使用注释,例如PrettyFaces,那么您可能需要通过web.xml添加显式排序。看

仅当您使用PrimeFaces文件上载筛选器时:您的Web应用程序中还有另一个筛选器,它在PrimeFaces文件上载筛选器之前运行,并已执行调用。通常情况下,URL重写筛选器(如)会执行此操作。这将触发转发调度程序,但过滤器默认情况下仅在请求调度程序上侦听

要解决此问题,您需要将PrimeFaces文件上载筛选器放在转发筛选器之前,或者重新配置PrimeFaces文件上载筛选器以侦听转发调度器:

primeFacesFileUploadFilter 小脸蛋 要求 向前地 有一个嵌套的。这在HTML中是非法的,并且浏览器行为未指定。通常情况下,浏览器在提交时不会发送预期的数据。确保你没有筑巢。这完全与表单的e无关 nctype。只是完全不要嵌套表单

如果仍然存在问题,那么就调试HTTP通信。打开webbrowser的开发者工具集,在Chrome/Firebug23+/IE9+中按F12键,然后检查网络/网络部分。如果HTTP部分看起来不错,那么调试JSF代码。在上面放置一个断点并从那里前进

保存上传的文件
在你最终让它工作后,你的下一个问题可能是如何/在哪里保存上传的文件?。好的,继续这里:。

你也在用漂亮的脸?然后将dispatcher设置为FORWARD:

<filter-mapping>
   <filter-name>PrimeFaces FileUpload Filter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
   <dispatcher>FORWARD</dispatcher>
</filter-mapping>

我在Primefaces 3.4和Netbeans 7.2中注意到一点:

删除函数handleFileUpload的Netbeans自动填充参数,即事件,否则事件可能为null

<h:form>
    <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload(event)}"
        mode="advanced" 
        update="messages"
        sizeLimit="100000" 
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>

    <p:growl id="messages" showDetail="true"/>
</h:form>

看起来javax.faces.SEPARATOR_CHAR不能等于

我对primefaces 5.3也有同样的问题,我通过了BalusC描述的所有要点,但没有结果。我按照他的建议调试FileUploadRenderDecode,发现我的web.xml设置不正确

<context-param>
  <param-name>primefaces.UPLOADER</param-name>
  <param-value>auto|native|commons</param-value>
</context-param>
参数值必须是这3个值中的1个,但不是全部!!可以删除整个上下文参数部分,默认值为auto

bean.xhtml

    <h:form enctype="multipart/form-data">    
<p:outputLabel value="Choose your file" for="submissionFile" />
                <p:fileUpload id="submissionFile"
                    value="#{bean.file}"
                    fileUploadListener="#{bean.uploadFile}" mode="advanced"
                    auto="true" dragDropSupport="false" update="messages"
                    sizeLimit="100000" fileLimit="1" allowTypes="/(\.|\/)(pdf)$/" />

</h:form>
@视域 公共类提交实现了可序列化{

private UploadedFile file;

//Gets
//Sets

public void uploadFasta(FileUploadEvent event) throws FileNotFoundException, IOException, InterruptedException {

    String content = IOUtils.toString(event.getFile().getInputstream(), "UTF-8");

    String filePath = PATH + "resources/submissions/" + nameOfMyFile + ".pdf";

    MyFileWriter.writeFile(filePath, content);

    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
            event.getFile().getFileName() + " is uploaded.", null);
    FacesContext.getCurrentInstance().addMessage(null, message);

}
}

web.xml

    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

这里的建议对我都没有帮助。所以我不得不调试primefaces,发现问题的原因是:

java.lang.IllegalStateException: No multipart config for servlet fileUpload
然后,我将节添加到web.xml中的Facesservlet中。这就解决了问题:

<servlet>
    <servlet-name>main</servlet-name>

        <servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <location>/tmp</location>
            <max-file-size>20848820</max-file-size>
            <max-request-size>418018841</max-request-size>
            <file-size-threshold>1048576</file-size-threshold>
        </multipart-config>
    </servlet>

我也有同样的问题,因为我有这篇文章中描述的所有配置,但在我的例子中是因为我有两个jquery导入,其中一个是primefaces的查询,这导致上传文件时发生冲突


对于使用Tomee或Tomcat但无法使其工作的用户,请尝试在META-INF中创建context.xml并添加allowCasualMultipartParsing=true


对于JBoss 7.2Undertow和PrimeFaces 6.0 org.PrimeFaces.webapp.filter.FileUploadFilter,应将其从web.xml中删除,并将context param file uploader设置为native:

<context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>native</param-value>
</context-param>

将p:fileUpload上传到h:form解决了我的问题。

您能详细说明一下吗?!当与OCP重写一起使用时,这仍然是一个问题。我欠你一杯啤酒:你能解释一下为什么这是一个答案吗?这只是代码,不是解释或任何{bean.uploadFile}vs{bean.uploadFasta},remove update=messages,它只对我有效!你没有在浏览器开发者控制台中看到一个特定的错误吗?@Kukeltje这是控制台显示的:未捕获类型错误:对象[Object Object]没有方法“fileupload”。这是一个错误的过滤器配置/排序的解决方法。嗨@BalusC,你能给我们更多解释吗?有没有比这更好的解决方法?请看我在这个问题上的答案。应该吗?如果没有,您是否会收到特定错误?是的,如果没有此更改,my FileUploadEvent不会调用。这不是一个显式错误,这是意外行为
@ManagedBean
private UploadedFile file;

//Gets
//Sets

public void uploadFasta(FileUploadEvent event) throws FileNotFoundException, IOException, InterruptedException {

    String content = IOUtils.toString(event.getFile().getInputstream(), "UTF-8");

    String filePath = PATH + "resources/submissions/" + nameOfMyFile + ".pdf";

    MyFileWriter.writeFile(filePath, content);

    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
            event.getFile().getFileName() + " is uploaded.", null);
    FacesContext.getCurrentInstance().addMessage(null, message);

}
    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
java.lang.IllegalStateException: No multipart config for servlet fileUpload
<servlet>
    <servlet-name>main</servlet-name>

        <servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <location>/tmp</location>
            <max-file-size>20848820</max-file-size>
            <max-request-size>418018841</max-request-size>
            <file-size-threshold>1048576</file-size-threshold>
        </multipart-config>
    </servlet>
<?xml version="1.0" encoding="UTF-8"?>
<Context allowCasualMultipartParsing="true">
  <!-- empty or not depending your project -->
</Context>
<context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>native</param-value>
</context-param>