gpt4 book ai didi

jsf - 如何使用 PrimeFaces p :fileUpload? 从未调用监听器方法或 UploadedFile 为空/引发错误/不可用

转载 作者:行者123 更新时间:2023-12-03 04:51:21 26 4
gpt4 key购买 nike

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

这是 View :

<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>

还有 bean :
@ManagedBean
@RequestScoped
public class FileUploadController {

public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}

}

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

最佳答案

如何配置和故障排除 <p:fileUpload>取决于 PrimeFaces 和 JSF 版本。
所有 PrimeFaces 版本
以下要求适用于所有 PrimeFaces 版本:

  • enctype <h:form> 的属性需要设置为 multipart/form-data .如果不存在,ajax 上传可能会正常工作,但一般浏览器行为未指定并取决于表单组合和 webbrowser 制作/版本。只是总是指定它是安全的。
  • 使用时 mode="advanced" (即ajax上传,这是默认的),然后确保你有一个<h:head>在(主)模板中。这将确保正确包含必要的 JavaScript 文件。这对于 mode="simple" 不是必需的(非 ajax 上传),但这会破坏所有其他 PrimeFaces 组件的外观和功能,因此无论如何您都不想错过。
  • 使用时 mode="simple" (即非ajax上传),则必须通过ajax="false"在任何PrimeFaces命令按钮/链接上禁用ajax ,并且您必须使用 <p:fileUpload value><p:commandButton action>而不是 <p:fileUpload listener> .

  • 所以,如果你想要(自动)带有 ajax 支持的文件上传(请注意 <h:head> !):
    <h:form enctype="multipart/form-data">
    <p:fileUpload listener="#{bean.upload}" auto="true" /> // For PrimeFaces version older than 8.x this should be fileUploadListener instead of listener.
    </h:form>
    public void upload(FileUploadEvent event) {
    UploadedFile uploadedFile = event.getFile();
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    byte[] contents = uploadedFile.getContents(); // Or getInputStream()
    // ... Save it, now!
    }
    或者如果你想要非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>
    private transient UploadedFile uploadedFile; // +getter+setter

    public void upload() {
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    byte[] contents = uploadedFile.getContents(); // Or getInputStream()
    // ... Save it, now!
    }
    请注意与ajax相关的属性,例如 auto , allowTypes , update , onstart , oncomplete等是 忽略 mode="simple" .所以在这种情况下不需要指定它们。
    另请注意,您应该 立即读取文件内容 在上述方法中,而不是在稍后的 HTTP 请求调用的不同 bean 方法中。这是因为上传的文件内容是请求范围的,因此在以后/不同的 HTTP 请求中不可用。任何在以后的请求中读取它的尝试很可能以 java.io.FileNotFoundException 结束。在临时文件上。

    PrimeFaces 8.x
    配置与下面的5.x版本信息相同,但如果你的监听器没有被调用,检查method属性是否被调用 listener而不是(就像 8.x 之前的版本一样) fileUploadListener .

    PrimeFaces 5.x
    这是 不是 如果您使用的是 JSF 2.2 和您的 faces-config.xml,则需要任何额外的配置也声明符合 JSF 2.2 版本。你做 不是 完全需要 PrimeFaces 文件上传过滤器,您也可以这样做 不是 需要 primefaces.UPLOADER web.xml 中的上下文参数.如果您不清楚如何根据所使用的目标服务器正确安装和配置 JSF,请前往 How to properly install and configure JSF libraries via Maven?"Installing JSF" section of our JSF wiki page .
    但是,如果您还没有使用 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>
    <servlet-name> facesServlet 的值必须与 <servlet> 中的值完全匹配 javax.faces.webapp.FacesServlet的条目在同一 web.xml .所以如果它是例如 Faces Servlet ,那么您需要相应地编辑它以匹配。

    PrimeFaces 4.x
    与 PrimeFaces 5.x 相同的故事也适用于 4.x。
    通过 UploadedFile#getContents() 获取上传的文件内容只有一个潜在的问题.这将返回 null当使用 native API 而不是 Apache Commons FileUpload 时。您需要使用 UploadedFile#getInputStream()相反。另见 How to insert uploaded image from p:fileUpload as BLOB in MySQL?
    native API 的另一个潜在问题是当上传组件以不同的“常规”ajax 请求被触发的形式存在时,该请求不处理上传组件。另见 File upload doesn't work with AJAX in PrimeFaces 4.0/JSF 2.2.x - javax.servlet.ServletException: The request content-type is not a multipart/form-data .
    这两个问题也可以通过切换到 Apache Commons FileUpload 来解决。有关详细信息,请参阅 PrimeFaces 3.x 部分。

    PrimeFaces 3.x
    此版本不支持 JSF 2.2/Servlet 3.0 原生文件上传。您需要手动安装 Apache Commons FileUpload 并在 web.xml 中明确注册文件上传过滤器.
    您需要以下库:
  • commons-fileupload.jar
  • commons-io.jar

  • 这些必须存在于 webapp 的运行时类路径中。使用 Maven 时,请确保它们至少是运行时范围的(编译的默认范围也很好)。手动携带 JAR 时,请确保它们最终位于 /WEB-INF/lib文件夹。
    文件上传过滤器注册详细信息可以在上面的 PrimeFaces 5.x 部分找到。如果您使用 PrimeFaces 4+ 并且您想明确使用 Apache Commons FileUpload 而不是 JSF 2.2/Servlet 3.0 本地文件上传,那么您需要在提到的库旁边并过滤以下上下文参数 web.xml :
    <context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
    </context-param>

    故障排除
    如果它仍然不起作用,以下是与 PrimeFaces 配置无关的另一个可能原因:
  • 仅当您使用 PrimeFaces 文件上传过滤器时:还有另一个 Filter在您的 web 应用程序中,该应用程序在 PrimeFaces 文件上传过滤器之前运行并且已经通过例如消耗了请求正文调用 getParameter() , getParameterMap() , getReader()等。一个请求体只能被解析一次。当您在文件上传过滤器完成其工作之前调用这些方法之一时,文件上传过滤器将获得一个空的请求正文。
    要解决此问题,您需要输入 <filter-mapping> web.xml 中其他过滤器之前的文件上传过滤器.如果请求不是 multipart/form-data请求,然后文件上传过滤器将继续,好像什么也没发生。如果您使用自动添加的过滤器,因为它们使用注释(例如 PrettyFaces),您可能需要通过 web.xml 添加显式排序。见 How to define servlet filter order of execution using annotations in WAR
  • 仅当您使用 PrimeFaces 文件上传过滤器时:还有另一个 Filter在您的 webapp 中,它在 PrimeFaces 文件上传过滤器之前运行并执行了 RequestDispatcher#forward() 打电话。通常,URL 重写过滤器,例如 PrettyFaces这样做。这会触发 FORWARD调度程序,但过滤器默认监听 REQUEST仅调度员。
    要解决此问题,您需要将 PrimeFaces 文件上传过滤器置于转发过滤器之前,或者重新配置 PrimeFaces 文件上传过滤器以监听 FORWARD调度员也是:
     <filter-mapping>
    <filter-name>primeFacesFileUploadFilter</filter-name>
    <servlet-name>facesServlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
  • 有一个嵌套 <h:form> .这在 HTML 中是非法的,浏览器行为未指定。通常,浏览器不会在提交时发送预期的数据。确保您没有嵌套 <h:form> .这完全不考虑表单的 enctype .只是不要嵌套表单。

  • 如果您仍然遇到问题,那么请调试 HTTP 流量。打开网络浏览器的开发人员工具集(在 Chrome/Firebug23+/IE9+ 中按 F12)并检查网络/网络部分。如果 HTTP 部分看起来不错,那么调试 JSF 代码。在 FileUploadRenderer#decode() 上放置断点并从那里前进。

    保存上传的文件
    在你最终让它工作后,你的下一个问题可能类似于“我如何/在哪里保存上传的文件?”。好吧,继续在这里: How to save uploaded file in JSF .

    关于jsf - 如何使用 PrimeFaces p :fileUpload? 从未调用监听器方法或 UploadedFile 为空/引发错误/不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8875818/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com