AJAX请求数据未传入RequestBody及Spring 400错误求助
看起来你遇到了两个关联的问题,我来帮你一步步解决:
问题根源分析
- 前端GET请求的特性:jQuery的
$.ajax默认是GET请求,而GET请求本身没有请求体(Request Body),所以你传入的JSON.stringify(sample)会被自动拼接到URL参数里,这就是为什么你看到URL里带了JSON字符串的原因。 - 后端@RequestBody的使用场景:Spring的
@RequestBody注解是用来从请求体中读取JSON数据并绑定到DTO的,但GET请求没有请求体,所以后端会抛出“Required request body is missing”的400错误。
解决方案(两种可选)
方案一:改用POST请求(推荐,符合REST规范,适合传递JSON体)
这是最标准的做法,因为POST请求支持请求体,能正确传递JSON数据。
前端代码修改:
给$.ajax加上method: "POST"(jQuery 1.9+版本)或者type: "POST"(旧版本),确保请求方式是POST:
var sample = { query: "kakao", x: "127.06283102249932", y: "37.514322572335935", radius: "20000" }; $('#search').click(function (e) { $.ajax({ url: "/map/search", method: "POST", // 新增这一行,指定POST请求 contentType: 'application/json; charset=utf-8', dataType: "text", data: JSON.stringify(sample), success: function(data) { console.log(data); }, error: function(error) { console.log(error); } }) });
后端代码修改:
把@RequestMapping的请求方法改成RequestMethod.POST:
@RestController @RequestMapping("/map") public class MapSearchController { @Autowired private RestApiAccessor restApiAccessor; // 修改method为POST @RequestMapping(method = RequestMethod.POST, value = "/search") public MapSearchResponseDTO mapSearchRequest(@RequestBody MapSearchRequestDTO mapSearchRequestDTO) throws Exception { if (Objects.isNull(mapSearchRequestDTO.getQuery())) throw new IllegalAccessException("There is no Query parameter."); return restApiAccessor.mapSearchRequestGet(mapSearchRequestDTO); } }
方案二:坚持使用GET请求(不推荐,但如果业务需要)
如果必须用GET请求,那么后端不能用@RequestBody,而是要通过URL参数接收数据,前端也不需要JSON.stringify。
前端代码修改:
去掉JSON.stringify,直接传递sample对象,jQuery会自动把它转成URL查询参数:
var sample = { query: "kakao", x: "127.06283102249932", y: "37.514322572335935", radius: "20000" }; $('#search').click(function (e) { $.ajax({ url: "/map/search", contentType: 'application/json; charset=utf-8', dataType: "text", data: sample, // 直接传对象,不用JSON.stringify success: function(data) { console.log(data); }, error: function(error) { console.log(error); } }) });
后端代码修改:
去掉@RequestBody,改用@ModelAttribute来自动绑定URL参数到DTO,或者用@RequestParam逐个接收(但DTO的方式更简洁):
@RestController @RequestMapping("/map") public class MapSearchController { @Autowired private RestApiAccessor restApiAccessor; @RequestMapping(method = RequestMethod.GET, value = "/search") // 用@ModelAttribute代替@RequestBody public MapSearchResponseDTO mapSearchRequest(@ModelAttribute MapSearchRequestDTO mapSearchRequestDTO) throws Exception { if (Objects.isNull(mapSearchRequestDTO.getQuery())) throw new IllegalAccessException("There is no Query parameter."); return restApiAccessor.mapSearchRequestGet(mapSearchRequestDTO); } }
注意:你的
MapSearchRequestDTO里radius是Integer类型,前端传的是字符串"20000",Spring会自动帮你转换成Integer,没问题。
内容的提问来源于stack exchange,提问作者윤현구
相关产品推荐
相关产品推荐

