Spring Boot控制器仅支持JSON,Thymeleaf表单提交报415不支持媒体类型错误
这个问题我太熟悉了!核心原因就是后端接口只接受JSON格式的请求体,但Thymeleaf表单默认会以application/x-www-form-urlencoded格式提交数据,两者不匹配就抛出了415 Unsupported Media Type错误。Postman能正常工作是因为你手动指定了Content-Type为application/json,刚好符合后端的要求。
下面给你两种最常用的解决方案,按需选择:
方案一:修改后端接口,支持表单编码格式
如果你的后端Controller方法用了@RequestBody注解(这是关键!),比如:
@PostMapping("/your-submit-url") public String handleSubmit(@RequestBody YourEntity entity) { // 业务逻辑 return "success-page"; }
@RequestBody会强制要求请求体是JSON格式,所以表单提交的编码格式就不被支持了。你只需要把@RequestBody换成@ModelAttribute(或者直接去掉,Spring会自动默认用@ModelAttribute处理表单参数):
@PostMapping("/your-submit-url") public String handleSubmit(@ModelAttribute YourEntity entity) { // 业务逻辑不变 return "success-page"; }
这样后端就能正常解析表单提交的application/x-www-form-urlencoded数据了,不需要改前端代码。
方案二:修改前端表单,提交JSON格式
如果你想保持后端接口只接受JSON的逻辑,那需要用JavaScript拦截表单的默认提交行为,把表单数据转换成JSON再发送:
首先,在HTML里添加CSRF令牌的meta标签(Spring Boot默认开启CSRF保护,必须带上这个才能正常提交):
<meta name="_csrf" th:content="${_csrf.token}"/> <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
然后修改你的Thymeleaf表单,用JS处理提交:
<form id="submitForm" th:object="${yourEntity}"> <input type="text" th:field="*{username}" placeholder="用户名"/> <input type="email" th:field="*{email}" placeholder="邮箱"/> <button type="submit">提交</button> </form> <script> document.getElementById('submitForm').addEventListener('submit', function(e) { // 阻止表单默认的提交行为 e.preventDefault(); // 把表单数据转换成JSON对象 const formData = new FormData(this); const jsonPayload = {}; formData.forEach((value, key) => { jsonPayload[key] = value; }); // 获取CSRF令牌 const csrfToken = document.querySelector('meta[name="_csrf"]').content; const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content; // 发送JSON格式的POST请求 fetch(this.action || '/your-submit-url', { method: 'POST', headers: { 'Content-Type': 'application/json', [csrfHeader]: csrfToken }, body: JSON.stringify(jsonPayload) }) .then(response => { if (response.ok) { // 提交成功后跳转页面 window.location.href = '/success-page'; } else { throw new Error('请求失败'); } }) .catch(err => { console.error('提交出错:', err); alert('提交失败,请稍后重试'); }); }); </script>
两种方案各有优劣:方案一简单快捷,适合不需要JSON格式的场景;方案二保留了后端的JSON接口规范,适合前后端分离或者需要统一请求格式的场景。
内容的提问来源于stack exchange,提问作者1istbesser

