不稳定的 Primefaces 文件上传侦听器调用
Unstable Primefaces fileupload listener call
有一个使用 JDK11、Primefaces 8.0、Spring Boot 2.3.0 的 Spring Boot 项目。
在 tomcat 9.0.35 上部署它。在某些部署中,我的文件上传组件能够很好地触发侦听器方法。在其他一些情况下,它无法触发它,不会留下任何错误消息或日志。
我已经尝试过一些重新启动,每次都使用相同的构建生成相同的结果(上传失败)。但是尽管没有触及源代码,另一个构建可以使它工作。
在另一项测试中,我使用完全相同的源代码构建和部署了 4-5 次项目,看到上传在所有项目中都有效。对于最后一个测试,我只是在 java 语句的 ';' 之后添加了一个 space 字符更改二进制文件并重建、重新部署并注意到文件上传不起作用。
我找不到行为不稳定的原因。
我被卡住了,不知道如何调试它,找出问题所在。欢迎任何建议
在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的顺序:
按顺序在 FilterChain 中过滤名称:[requestContextFilter,Tomcat WebSocket (JSR356) Filter,errorPageFilter,primeFacesFileUploadFilter,characterEncodingFilter,springSecurityFilterChain,formContentFilter]
指定
servletContext.setInitParameter("primefaces.UPLOADER", "native");
在 servletContextInitializer 中导致文件上传有时成功有时失败(未触发侦听器)。
但是在指定之后:
servletContext.setInitParameter("primefaces.UPLOADER", "commons");
我没有进行“本地”,而是进行了将近 10 次构建、部署和测试,其中所有文件上传都正确触发。当然我仍然不能保证它是绝对的解决方案但是
很有可能。
有一个使用 JDK11、Primefaces 8.0、Spring Boot 2.3.0 的 Spring Boot 项目。 在 tomcat 9.0.35 上部署它。在某些部署中,我的文件上传组件能够很好地触发侦听器方法。在其他一些情况下,它无法触发它,不会留下任何错误消息或日志。
我已经尝试过一些重新启动,每次都使用相同的构建生成相同的结果(上传失败)。但是尽管没有触及源代码,另一个构建可以使它工作。
在另一项测试中,我使用完全相同的源代码构建和部署了 4-5 次项目,看到上传在所有项目中都有效。对于最后一个测试,我只是在 java 语句的 ';' 之后添加了一个 space 字符更改二进制文件并重建、重新部署并注意到文件上传不起作用。
我找不到行为不稳定的原因。 我被卡住了,不知道如何调试它,找出问题所在。欢迎任何建议
在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>
我在父页面中有
和 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的顺序:
按顺序在 FilterChain 中过滤名称:[requestContextFilter,Tomcat WebSocket (JSR356) Filter,errorPageFilter,primeFacesFileUploadFilter,characterEncodingFilter,springSecurityFilterChain,formContentFilter]
指定
servletContext.setInitParameter("primefaces.UPLOADER", "native");
在 servletContextInitializer 中导致文件上传有时成功有时失败(未触发侦听器)。
但是在指定之后:
servletContext.setInitParameter("primefaces.UPLOADER", "commons");
我没有进行“本地”,而是进行了将近 10 次构建、部署和测试,其中所有文件上传都正确触发。当然我仍然不能保证它是绝对的解决方案但是 很有可能。