JBoss EAP8+Undertow环境下如何为自动配置的JSP Servlet配置Multipart?
解决JBoss EAP8中自动生成的JSP Servlet缺少Multipart配置导致的UT010057异常
问题背景
从JBoss EAP7迁移至EAP8(同步完成javax到jakarta的API切换),JSP项目涉及带MultipartFile的文件上传请求。文件上传后控制器仅读取内容不写入磁盘,但multipart resolver执行清理操作时,触发UT010057: multipart config was not present on Servlet异常——原因是自动生成的JSP Servlet未配置multipart,而项目主Servlet配置正常。
触发异常的代码示例
JSP表单代码:
<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"; } }
已尝试的无效方案
- 尝试通过
standalone.xml的<jsp-config/>配置multipart,但查看org.wildfly.extension.undertow.JSPConfig源码发现该节点无相关字段,无法生效; - 移除
standalone.xml的<jsp-config/>,在web.xml中手动重写JSP Servlet并添加multipart配置,但该方式需额外调用io.undertow.jsp.JspServletBuilder#setupDeployment注册标签库,侵入性较强; - 发现
io.undertow.servlet.core.ManagedServlet初始化时会尝试读取默认multipart配置,但org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService初始化时未设置io.undertow.servlet.api.DeploymentInfo的默认参数。
可行解决方案
方案一:通过jboss-web.xml为默认JSP Servlet补充multipart配置
这是最简洁的方式,无需修改容器配置或编写自定义处理器:
在项目WEB-INF/jboss-web.xml中添加如下配置,直接为自动生成的JSP Servlet补充multipart参数:
<?xml version="1.0" encoding="UTF-8"?> <jboss-web xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_11_0.xsd" version="11.0"> <servlet> <servlet-name>jsp</servlet-name> <!-- 对应EAP8默认JSP Servlet名称 --> <multipart-config> <max-file-size>10485760</max-file-size> <!-- 单个文件最大限制:10MB --> <max-request-size>52428800</max-request-size> <!-- 请求总大小限制:50MB --> <file-size-threshold>0</file-size-threshold> <!-- 超过阈值则写入磁盘,0表示全部写入磁盘 --> </multipart-config> </servlet> </jboss-web>
原理:EAP8中自动生成的JSP Servlet默认名称为jsp,通过jboss-web.xml的servlet节点可直接为已存在的Servlet补充配置,无需重新定义Servlet,避免了标签库注册的额外工作。
方案二:自定义部署处理器设置全局默认Multipart配置
若需为所有Servlet统一设置默认multipart配置,可编写自定义DeploymentProcessor:
- 编写处理器类:
package com.yourpackage.deployment; import io.undertow.servlet.api.DeploymentInfo; import io.undertow.servlet.api.MultipartConfigElement; import org.jboss.as.server.deployment.DeploymentPhaseContext; import org.jboss.as.server.deployment.DeploymentUnit; import org.jboss.as.server.deployment.DeploymentUnitProcessor; import org.jboss.as.web.common.WarMetaData; import org.jboss.as.undertow.deployment.UndertowDeploymentInfoService; public class DefaultMultipartConfigProcessor implements DeploymentUnitProcessor { @Override public void deploy(DeploymentPhaseContext phaseContext) { DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); if (warMetaData == null) return; UndertowDeploymentInfoService deploymentInfoService = deploymentUnit.getAttachment(UndertowDeploymentInfoService.ATTACHMENT_KEY); if (deploymentInfoService != null) { DeploymentInfo deploymentInfo = deploymentInfoService.getDeploymentInfo(); MultipartConfigElement defaultConfig = new MultipartConfigElement( null, 10485760L, 52428800L, 0 ); deploymentInfo.setDefaultMultipartConfig(defaultConfig); } } @Override public void undeploy(DeploymentUnit deploymentUnit) {} }
- 打包为JAR并创建WildFly模块(
module.xml):
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.3" name="com.yourpackage.deployment"> <resources> <resource-root path="your-processor.jar"/> </resources> <dependencies> <module name="javax.servlet.api"/> <module name="org.jboss.as.server"/> <module name="org.jboss.as.web"/> <module name="org.jboss.as.undertow"/> <module name="io.undertow.servlet"/> </dependencies> </module>
- 在
standalone.xml中注册处理器:
<subsystem xmlns="urn:jboss:domain:undertow:12.0"> <!-- 其他配置 --> <deployment-processors> <processor name="com.yourpackage.deployment.DefaultMultipartConfigProcessor" module="com.yourpackage.deployment"/> </deployment-processors> </subsystem>
验证
部署项目后触发文件上传请求,multipart resolver清理时将找到JSP Servlet的multipart配置,不再抛出UT010057异常。
内容的提问来源于stack exchange,提问作者ebc149
相关产品推荐
相关产品推荐

