You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:08:09