Reputation: 44
I am migrating from eap7 to 8 (also from javax to jakarta), and have a request with MultipartFile
. My app is using jsp. File gets to the server, in controller it is processed (not written) then multipart resolver tries to clean up multipart, during which it expects (with jsp servlet) the multipart configuration to be present. This config is present on my declared servlet but not on the auto generated jsp servlet.
This is jsp framgent that triggers my controller:
<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>
Controller:
@RequestMapping(value = "/addStuff", method = RequestMethod.POST)
public String addStuff(Model model, @RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
doSomeReadLogicWithFile(file);
return "myJspPage";
}
}
When return "myJspPage"
is reached, the org.springframework.web.multipart.support.StandardServletMultipartResolver
kicks in with method cleanupMultipart
and it does so for each servlet. My main servlet (declared in web.xml) goes through like a charm (I added xml config for multipart), but then, auto-generated jsp servlet reaches the code io.undertow.servlet.spec.HttpServletRequestImpl
verifyMultipartServlet
, tries to get multipart config from servlet, gets null, and raises throw UndertowServletMessages.MESSAGES.multipartConfigNotPresent()
exception
The stack then looks like this:
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)
I checked if I can pass multipart config through standalone.xml via <jsp-config/>
but looked into the code, and org.wildfly.extension.undertow.JSPConfig
class does not has such fields.
Then tried to override jsp servlet with <jsp-config/>
removed from standalone.xml
and inside web.xml
with such entries
<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>
But such config does not work, as I should at least call io.undertow.jsp.JspServletBuilder#setupDeployment
during server startup to register tag libs, which I would rather not do.
Last (and my biggest disapointment) was this part of servlets configuration:
class io.undertow.servlet.core.ManagedServlet#ManagedServlet
in constructor calls method setupMultipart
. When multipart config is not present on servlet that is being initialized it tries to get it from some defaults
if(multipartConfig == null) {
multipartConfig = servletContext.getDeployment().getDeploymentInfo().getDefaultMultipartConfig();
}
Unfortunately a setter to this field in class io.undertow.servlet.api.DeploymentInfo
is not called when object is being initialized in org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService
To pass multipart configuration to auto generated jsp servlet.
Upvotes: 1
Views: 264