【问题标题】:Unstable Primefaces fileupload listener call不稳定的 Primefaces 文件上传监听器调用
【发布时间】:2023-03-15 16:59:01
【问题描述】:

有一个使用 JDK11、Primefaces 8.0、Spring Boot 2.3.0 的 Spring Boot 项目。 将其部署在 tomcat 9.0.35 上。在某些部署中,我的文件上传组件能够很好地触发侦听器方法。在其他一些情况下,它无法触发它,不会留下任何错误消息或日志。

我尝试了一些重新启动,每次使用相同的构建产生相同的结果(上传失败)。但是尽管没有触及源代码,但另一个构建可以使其工作。

在另一项测试中,我使用完全相同的源代码构建和部署了 4-5 次项目,看到上传在所有项目中都有效。对于最后一个测试,我只是在 java 语句的 ';' 之后添加了一个空格字符更改二进制文件并重建、重新部署并注意到文件上传不起作用。

我无法找出行为不稳定的原因。 我被卡住了,不知道如何调试它,找出问题所在。欢迎任何建议

在 pom.xml 有:

    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>


    <dependency>
       <groupId>com.sun.faces</groupId>
       <artifactId>jsf-api</artifactId>
       <version>2.2.20</version>
    </dependency>
    <dependency>
       <groupId>com.sun.faces</groupId>
       <artifactId>jsf-impl</artifactId>
       <version>2.2.20</version>
    </dependency>

    <dependency>
       <groupId>org.primefaces</groupId>
       <artifactId>primefaces</artifactId>
       <version>8.0</version>
    </dependency>

    <dependency>
        <groupId>com.google.code</groupId>
        <artifactId>kaptcha</artifactId>
        <version>2.3.0</version>
    </dependency>

页面上的文件上传组件:

<h:form id="bulkDataInsertForm" enctype="multipart/form-data">
  .
  .
    <p:fileUpload id="datafileuploader"
        listener="#{bulkDataInsertBean.handleFileUpload}"
        uploadLabel="upload file"
        cancelLabel="cancel"
        label="choose file"
        update=":bulkDataInsertForm:bulkDataInsertgrowl :bulkDataInsertForm:listFileUploadPanel :bulkDataInsertForm:errorText"
        allowTypes="/(\.|\/)(xlsx)$/"
        sizeLimit="10485760" 
        multiple="false"
        invalidFileMessage="file type error"
        mode="advanced" dragDropSupport="true"
        ajax="true">
    </p:fileUpload>
.
.
</h:form>

我在父页面中有 ,如下所示:How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null / throws an error / not usable

还有 ServletInitializer:

@EnableEncryptableProperties
@SpringBootApplication
@ComponentScan({ "com.myapp"  })
public class WebApplication extends SpringBootServletInitializer {  

  @Bean
  public ServletRegistrationBean kaptchaServletRegistration() {
    ServletRegistrationBean bean = new ServletRegistrationBean(new KaptchaServlet(), "/kaptcha.jpg");
    return bean;
  }

  @Bean
  public ServletRegistrationBean facesServletRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean<>(new FacesServlet(), "*.xhtml");
    registration.setLoadOnStartup(1);
    return registration;
  }

  @Bean
  public ServletContextInitializer servletContextInitializer() {
    return servletContext -> {
        servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
        servletContext.setInitParameter("primefaces.THEME", "blitzer");
        
        servletContext.setInitParameter("primefaces.CLIENT_SIDE_VALIDATION", Boolean.TRUE.toString());
        
        servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", Boolean.TRUE.toString());
         
        servletContext.setInitParameter("primefaces.FONT_AWESOME", Boolean.TRUE.toString());
        
        servletContext.setInitParameter("javax.faces.ENABLE_CDI_RESOLVER_CHAIN", Boolean.TRUE.toString());
      };


  @Bean
  public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
    return new ServletListenerRegistrationBean<>(new ConfigureListener()); 
  }


//for setting fileUploadFilter to in front of filterChain - so uploaded file not consumed by other filter
  @Bean
  public FilterRegistrationBean primeFacesFileUploadFilter() {

     FilterRegistrationBean registration = new FilterRegistrationBean(new org.primefaces.webapp.filter.FileUploadFilter(), facesServletRegistration());
    
     registration.addUrlPatterns("/*"); 
    
     registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD);
     registration.setName("primeFacesFileUploadFilter");
     registration.setOrder(1);
     return registration;
    }
  }

注意:在某些论坛上,我已经阅读了 fileupload 过滤器顺序可以更改,因此其他一些过滤器可能会消耗正在上传的文件流,从而使 fileupload 过滤器没有输入。 它还必须接受转发的请求。所以我添加了上面显示的“primeFacesFileUploadFilter”,但它没有帮助:

这是添加代码后 ServletContextInitializer 期间过滤器链的顺序:

FilterChain 中的过滤器名称按顺序:[requestContextFilter, Tomcat WebSocket (JSR356) Filter, errorPageFilter, primeFacesFileUploadFilter, characterEncodingFilter, springSecurityFilterChain, formContentFilter]

【问题讨论】:

    标签: spring-boot file-upload primefaces


    【解决方案1】:

    指定

    servletContext.setInitParameter("primefaces.UPLOADER", "native");    
    

    在 servletContextInitializer 导致有时成功有时失败(监听器未触发)文件上传。

    但是在指定之后:

    servletContext.setInitParameter("primefaces.UPLOADER", "commons"); 
    

    我进行了近 10 次构建、部署和测试,而不是“原生”,其中所有文件上传都正确触发。当然我仍然不能保证它是绝对的解决方案,但是 很有可能。

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      • 2011-09-02
      相关资源
      最近更新 更多