向Spring MVC传递字符串数组遇400错误,该用何种参数类型?
解决AJAX提交数组到Spring MVC的400错误问题
我之前也碰到过一模一样的问题!问题出在jQuery序列化数组的方式和Spring MVC期望的参数格式不匹配上,导致后端无法识别你提交的testCaseNames数组参数。给你几个简单可行的解决方案:
方案1:修改AJAX请求,使用传统序列化方式
jQuery默认会对数组进行"深度序列化",把数组参数名变成testCaseNames[],但你的后端参数名是testCaseNames,所以匹配不上。只需要在AJAX配置里加上traditional: true,让它用传统方式序列化数组(参数名不带[],重复传递同一个参数名),后端就能直接识别String[]或List<String>类型的参数了。
修改后的前端代码:
var flowName = $('#flowName').val(); var testCaseNames = []; $('.icons-right .action-icon:first-of-type').each(function() { testCaseNames.push($(this).attr('name')) }); console.log(testCaseNames); $.ajax({ type: 'post', url: '/create-flow/save', data: { flowName: flowName, testCaseNames: testCaseNames }, traditional: true, // 关键配置:启用传统序列化 success: function (result) { } });
后端代码不需要修改,保持原来的String[]或者改成List<String>都可以:
@RequestMapping(value = "/create-flow/save" , method = RequestMethod.POST) public @ResponseBody String saveFlow(HttpSession session, @RequestParam("flowName") String flowName, @RequestParam("testCaseNames") String[] testCaseNames) { String user = session.getAttribute("loggedUser").toString(); return TestFlow.addFlow(flowName,testCaseNames,user); }
方案2:修改后端参数名,匹配jQuery的默认序列化格式
如果你不想改前端代码,也可以直接修改后端的参数名,让它匹配jQuery默认发送的testCaseNames[]:
@RequestMapping(value = "/create-flow/save" , method = RequestMethod.POST) public @ResponseBody String saveFlow(HttpSession session, @RequestParam("flowName") String flowName, @RequestParam("testCaseNames[]") String[] testCaseNames) { String user = session.getAttribute("loggedUser").toString(); return TestFlow.addFlow(flowName,testCaseNames,user); }
换成List<String>类型同样有效:
@RequestParam("testCaseNames[]") List<String> testCaseNames
方案3:用JSON格式提交(适合复杂参数结构)
如果你的参数结构以后可能更复杂,推荐用JSON格式提交,这种方式更清晰,也避免序列化格式的问题。
前端修改:
设置contentType: "application/json",并把数据转成JSON字符串:
$.ajax({ type: 'post', url: '/create-flow/save', contentType: "application/json", // 指定JSON格式 data: JSON.stringify({ flowName: flowName, testCaseNames: testCaseNames }), // 转成JSON字符串 success: function (result) { } });
后端修改:
首先创建一个DTO类来接收参数:
public class FlowSaveRequest { private String flowName; private List<String> testCaseNames; // 必须添加getter和setter方法 public String getFlowName() { return flowName; } public void setFlowName(String flowName) { this.flowName = flowName; } public List<String> getTestCaseNames() { return testCaseNames; } public void setTestCaseNames(List<String> testCaseNames) { this.testCaseNames = testCaseNames; } }
然后控制器方法用@RequestBody接收这个DTO:
@RequestMapping(value = "/create-flow/save" , method = RequestMethod.POST) public @ResponseBody String saveFlow(HttpSession session, @RequestBody FlowSaveRequest request) { String user = session.getAttribute("loggedUser").toString(); // 把List转成数组(如果你的TestFlow.addFlow需要数组的话) String[] testCaseArray = request.getTestCaseNames().toArray(new String[0]); return TestFlow.addFlow(request.getFlowName(), testCaseArray, user); }
这三种方案都能解决你的400错误,根据你的实际场景选就行,我个人常用方案1或者方案3,看参数复杂度~
内容的提问来源于stack exchange,提问作者user9176898
相关产品推荐
相关产品推荐

