Spring Boot提交含复选框与多文件的表单时触发MultipartException问题求助
大家好,我遇到了一个特别诡异的问题,想请各位帮忙分析排查一下:
我正在做Spring Boot + Thymeleaf的联系人添加功能,表单里包含了常规输入字段、文件上传项,还有一个「Mark as Favourite」的复选框。奇怪的是,不勾选这个复选框时,表单提交(包括文件上传)完全正常;但只要勾选它再提交,直接就弹出500错误,错误页面提示:
Whitelabel Error Page stating: There was an unexpected error (type=Internal Server Error, status=500). Failed to parse multipart servlet request org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request
我反复确认后发现,请求根本没到达我的控制器方法,是在Spring解析multipart请求的阶段就失败了。而且我已经排除了文件上传的问题——因为不勾选复选框时,不管传多大的文件(在配置范围内)都能正常提交,所以肯定不是文件大小或者格式的锅。
下面是我用到的完整HTML表单代码(代码末尾可能有点截断,是粘贴时的问题):
<!doctype html> <html lang="en" th:replace="~{base::parent(~{::#content}, ~{:: title}, ~{:: script})}"> <head> <title th:text="${user.name + ' | Add Contacts'}">Add Contacts</title> </head> <body> <div id="content" class="pl-64 pt-24"> <div th:replace="~{user/sidebar::sidebar}"></div> <div class="pl-4 pr-4 md:pl-10"> <div class="grid grid-cols-1 md:grid-cols-12 gap-6"> <div class="md:col-span-3"> <div class="card block m-20 mt-0 p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 hover:shadow-md dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 transition-all duration-500 ease-in-out"> <div th:replace="~{message::messageBox}"></div> <h1 class="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Add New Contacts</h1> <p class="text-gray-900 dark:text-gray-300 mb-10">Fill in the details below to add new contacts. </p> <form th:action="@{/user/contacts/save}" method="post" th:object="${contactForm}" enctype="multipart/form-data" novalidate> <div class="grid gap-6 mb-6 md:grid-cols-2"> <!-- Name --> <div> <label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Full Name</label> <input type="text" id="name" name="name" th:field="*{name}" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Full Name" required/> <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-red-500 text-sm font-medium mt-1"></p> </div> <!-- Email --> <div> <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Email address</label> <input type="email" id="email" name="email" th:field="*{email}" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="name@company.com" required /> <p th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-red-500 text-sm font-medium mt-1"></p> </div> <!-- Phone --> <div> <label for="phoneNumber" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Phone Number</label> <input type="tel" id="phoneNumber" name="phoneNumber" th:field="*{phoneNumber}" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="XXXXXXXXXX" pattern="[0-9]{10}" required /> <p th:if="${#fields.hasErrors('phoneNumber')}" th:errors="*{phoneNumber}" class="text-red-500 text-sm font-medium mt-1"></p> </div> <!-- Address --> <div> <label for="address" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Address</label> <input type="text" id="address" name="address" th:field="*{address}" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-w
我已经检查了spring.servlet.multipart相关的配置(比如max-file-size、max-request-size)都是合理值,而且不勾选复选框时所有功能都正常。现在实在搞不懂,一个简单的布尔值复选框,为什么会导致multipart请求解析失败?有没有人遇到过类似的问题,或者能给我一些排查方向?
内容来源于stack exchange

