拥有一个使用 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>
页面上的FileUpload组件:
<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 中过滤名称:[requestContextFilter、Tomcat WebSocket (JSR356) Filter、errorPageFilter、primeFacesFileUploadFilter、characterEncodingFilter、springSecurityFilterChain、formContentFilter]
指定
servletContext.setInitParameter("primefaces.UPLOADER", "native");
servletContextInitializer 导致文件上传有时成功有时失败(侦听器未触发)。
但是指定之后:
servletContext.setInitParameter("primefaces.UPLOADER", "commons");
我没有使用“原生”,而是进行了近 10 次构建、部署和测试,其中所有文件上传均正确触发。当然我仍然不能保证它是绝对的解决方案但是 可能性很大。
我还遇到了上传侦听器 bean 根本没有被调用的问题,即使在遵循此处的所有建议之后我也无法使其运行。我使用了 Primefaces 13 和 SpringBoot 3.2.3。
最后我使用了Joinfaces项目,并且fileUpload开始工作,可能还有一些针对Primefaces和Spring的额外设置。
我刚刚将其添加到 pom.xml 中:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.joinfaces</groupId>
<artifactId>joinfaces-bom</artifactId>
<version>5.2.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.joinfaces</groupId>
<artifactId>primefaces-spring-boot-starter</artifactId>
</dependency>