JQuery Ajax POST请求Spring MVC控制器失败,媒体类型不支持
问题与解决方案
报错信息
2022-10-23 11:40:29.971 WARN 3123 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported]
尝试通过jQuery阻止HTML表单默认提交,改用Ajax发送JSON数据到Spring MVC控制器,期望数据被对应DTO接收,但请求失败,核心原因是前端并未以application/json格式发送数据。
相关代码
HTML表单
<form action="/account/username" id="change-username-form" method="post"> <p> <label class="sr-only mb-1" for="current-username">Current Username</label> <input autofocus class="form-control" id="current-username" name="current-username" placeholder="Current Username" required type="text"> </p> <p> <label class="sr-only mb-1" for="new-username">New Username</label> <input autofocus class="form-control" id="new-username" name="new-username" placeholder="New Username" required type="text"> </p> <button class="btn btn-dark btn-block" type="submit">Submit</button> </form>
原jQuery Ajax代码
$("#change-username-form").submit(function (event) { event.preventDefault() const form = $(this) const url = form.attr("action") $.ajax(url, { dataType: JSON, type: "Post", data: { changeUsernameDTO: { currentUsername: $("#current-username").val(), newUsername: $("#new-username").val() } } }) })
DTO类
import lombok.Data; @Data public class ChangeUsernameDTO { private String currentUsername, newUsername; }
Spring MVC控制器
@RestController @RequestMapping("/account") @AllArgsConstructor public class AccountController { private final AccountService accountService; @PostMapping( path = "/username", consumes = "application/json" ) public void changeUsername(Authentication authentication, @RequestBody ChangeUsernameDTO dto) { accountService.changeUsername(authentication, dto); } }
解决步骤
1. 修正jQuery Ajax配置问题
原代码存在三个关键错误:
dataType应该是字符串"json",而非JSON对象;- jQuery默认会将
data中的对象序列化为application/x-www-form-urlencoded格式,需要手动指定contentType: "application/json"; - 无需将数据包装在
changeUsernameDTO对象中,控制器通过@RequestBody直接接收ChangeUsernameDTO实例,直接传递字段匹配的对象即可。
2. 修改后的jQuery代码
$("#change-username-form").submit(function (event) { event.preventDefault() const form = $(this) const url = form.attr("action") const requestData = { currentUsername: $("#current-username").val(), newUsername: $("#new-username").val() } $.ajax(url, { dataType: "json", type: "POST", contentType: "application/json", data: JSON.stringify(requestData) }) })
3. 验证控制器配置
控制器的@PostMapping(consumes = "application/json")和@RequestBody ChangeUsernameDTO dto配置正确,不需要修改。Lombok的@Data注解会自动生成字段的setter方法,确保Spring能正确解析JSON数据到DTO对象中。
内容的提问来源于stack exchange,提问作者Davide
相关产品推荐
相关产品推荐

