我正在从 eap7 迁移到 8(也从 javax 迁移到 jakarta),并向
MultipartFile
提出请求。我的应用程序使用jsp。文件到达服务器,在控制器中对其进行处理(而不是写入),然后多部分解析器尝试清理多部分,在此期间它期望(使用 jsp servlet)存在多部分配置。此配置存在于我声明的 servlet 上,但不存在于自动生成的 jsp servlet 上。
这是触发我的控制器的 jsp framgent:
<form:form id="myFancyForm${myEntity.id}" method="POST"
action="addStuff?${_csrf.parameterName}=${_csrf.token}"
enctype="multipart/form-data" class="skip">
<input id="someId" type="hidden" name="someId" class="myIdClass"
value="${myEntity.id}"/>
<div class="my_fancy_button" id="SomeButtonId${myEntity.id}">
<input id="file" name="file" type="file" class="some_class_css"
onchange="checkFileSizeAndSubmit(this, '#myFancyForm${myEntity.id}');"/>
</div>
</form:form>
控制器:
@RequestMapping(value = "/addStuff", method = RequestMethod.POST)
public String addStuff(Model model, @RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
doSomeReadLogicWithFile(file);
return "myJspPage";
}
}
当达到
return "myJspPage"
时,org.springframework.web.multipart.support.StandardServletMultipartResolver
将使用方法 cleanupMultipart
启动,并对每个 servlet 执行此操作。我的主 servlet(在 web.xml 中声明)就像一个魅力(我为多部分添加了 xml 配置),但是随后,自动生成的 jsp servlet 到达代码 io.undertow.servlet.spec.HttpServletRequestImpl
verifyMultipartServlet
,尝试从 servlet 获取多部分配置,获取 null,并引发 throw UndertowServletMessages.MESSAGES.multipartConfigNotPresent()
异常
堆栈看起来像这样:
2024-07-17 12:15:05,436 WARN [org.springframework.web.multipart.support.StandardServletMultipartResolver] (default task-53) Failed to perform cleanup of multipart items: java.lang.IllegalStateException: UT010057: multipart config was not present on Servlet
at [email protected]//io.undertow.servlet.spec.HttpServletRequestImpl.verifyMultipartServlet(HttpServletRequestImpl.java:567)
at [email protected]//io.undertow.servlet.spec.HttpServletRequestImpl.getParts(HttpServletRequestImpl.java:556)
at [email protected]//jakarta.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:306)
at [email protected]//jakarta.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:306)
at [email protected]//jakarta.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:306)
at [email protected]//jakarta.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:306)
at deployment.my-app-web.war//org.springframework.web.multipart.support.StandardServletMultipartResolver.cleanupMultipart(StandardServletMultipartResolver.java:122)
at deployment.my-app-web.war//org.springframework.web.servlet.DispatcherServlet.cleanupMultipart(DispatcherServlet.java:1268)
at deployment.my-app-web.war//org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1125)
at deployment.my-app-web.war//org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at deployment.my-app-web.war//org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at deployment.my-app-web.war//org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
at [email protected]//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547)
at deployment.my-app-web.war//org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at [email protected]//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at [email protected]//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at [email protected]//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at deployment.my-app-web.war//my.app.packaging.filters.HttpHeadFilter.doFilter(HttpHeadFilter.java:43)
at [email protected]//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at [email protected]//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at deployment.my-app-web.war//my.app.packaging.filters.MyAppSecurityFilter.doFilter(MyAppSecurityFilter.java:28)
at [email protected]//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at [email protected]//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365)
at deployment.my-app-web.war//org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
at deployment.my-app-web.war//org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131)
at deployment.my-app-web.war//org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:181)
at deployment.my-app-web.war//org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227)
at deployment.my-app-web.war//org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
at deployment.my-app-web.war//org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:131)
at deployment.my-app-web.war//org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at deployment.my-app-web.war//org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at deployment.my-app-web.war//org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
at deployment.my-app-web.war//org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:151)
at deployment.my-app-web.war//org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:129)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82)
at deployment.my-app-web.war//org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
at deployment.my-app-web.war//org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233)
at deployment.my-app-web.war//org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
at deployment.my-app-web.war//org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352)
at deployment.my-app-web.war//org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268)
at [email protected]//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at [email protected]//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at deployment.my-app-web.war//org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at deployment.my-app-web.war//org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at [email protected]//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at [email protected]//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at [email protected]//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at [email protected]//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at [email protected]//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at [email protected]//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.security.elytron-web.undertow-server@4.0.1.Final-redhat-00001//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68)
at [email protected]//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103)
at [email protected]//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161)
at [email protected]//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73)
at org.wildfly.security.elytron-web.undertow-server@4.0.1.Final-redhat-00001//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67)
at [email protected]//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at [email protected]//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
at [email protected]//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at [email protected]//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at [email protected]//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at [email protected]//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at org.wildfly.security.elytron-web.undertow-server-servlet@4.0.1.Final-redhat-00001//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at [email protected]//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at [email protected]//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at [email protected]//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276)
at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132)
at [email protected]//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at [email protected]//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1430)
at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1430)
at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1430)
at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1430)
at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1430)
at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256)
at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101)
at [email protected]//io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
at [email protected]//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
at [email protected]//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at [email protected]//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at [email protected]//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
at java.base/java.lang.Thread.run(Thread.java:840)
我检查了是否可以通过standalone.xml通过
<jsp-config/>
传递多部分配置,但查看了代码,org.wildfly.extension.undertow.JSPConfig
类没有这样的字段。
然后尝试使用从
<jsp-config/>
中删除的 standalone.xml
并在 web.xml
内使用此类条目来覆盖 jsp servlet
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>20971520</max-request-size>
<file-size-threshold>5242880</file-size-threshold>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
但是这样的配置不起作用,因为我应该至少在服务器启动期间调用
io.undertow.jsp.JspServletBuilder#setupDeployment
来注册标签库,但我宁愿不这样做。
最后(也是我最大的失望)是 servlet 配置的这一部分: 构造函数中的类
io.undertow.servlet.core.ManagedServlet#ManagedServlet
调用方法setupMultipart
。当正在初始化的 servlet 上不存在多部分配置时,它会尝试从某些默认值中获取它
if(multipartConfig == null) {
multipartConfig = servletContext.getDeployment().getDeploymentInfo().getDefaultMultipartConfig();
}
不幸的是,当在
io.undertow.servlet.api.DeploymentInfo
中初始化对象时,不会调用类
org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService
中该字段的设置器
将多部分配置传递给自动生成的 jsp servlet。
我遇到了同样的问题。我很好奇你是否成功解决了这个问题。