RestTemplate调接口报422:request期望列表但实际得到dict
SpringBoot RestTemplate调用POST接口返回422错误修复方案
核心错误原因
request字段类型不匹配:接口要求request参数为数组(列表)类型,但代码中QuoteRequest实体将该字段定义为单个QRequest对象,JSON序列化后该字段输出为对象结构(即报错中的dict类型),直接触发接口参数校验失败。
对比Postman正常请求的结构,request字段即使只有1个元素,也必须用数组包裹:
"request": [ { "policy_type": "comprehensive_travel_insurance", // 其余字段省略 } ]
代码中存在的具体问题
- 根因问题:
QuoteRequest类的request属性类型声明错误,且fillQuoteRequest()方法直接给request赋值单个QRequest对象,未包装为列表 - 附带字段赋值错误(修复根因后会继续触发校验失败,需一并修改):
fillLegs()方法中出发国、到达国赋值颠倒,且航司IATA码错填为航班号fillFlights()方法中到达时间赋值错误,和出发时间完全一致
修复步骤
- 修改
QuoteRequest实体类,调整request字段类型
// 原错误声明 // private QRequest request; // 修正为列表类型 private List<QRequest> request; // 对应get/set方法也要同步修改参数/返回值类型
- 修改
fillQuoteRequest()方法的赋值逻辑,将请求对象包装为列表
private QuoteRequest fillQuoteRequest(){ QuoteRequest qr = new QuoteRequest(); // 原错误写法:qr.setRequest(fillQrequest()); // 修正:将单条请求放入列表后赋值 List<QRequest> reqList = new ArrayList<>(); reqList.add(fillQrequest()); qr.setRequest(reqList); qr.setPartnerMetadata(fillPartnerMeta()); qr.setCurrency("EUR"); qr.setCustomerCountry("NL"); qr.setCustomerLanguage("en"); return qr; }
- 修正其余字段赋值错误
- 调整
fillLegs()方法的国家、航司码赋值:
legs.setOperatingAirlineIataCode("BT"); legs.setMarketingAirlineIataCode("BT"); legs.setDepartureCountry("LT"); legs.setArrivalCountry("EE");- 调整
fillFlights()方法的到达时间赋值:
flights.setArrivalDateTime("2022-06-13T20:55:00+02:00"); - 调整
排查建议
后续遇到这类参数格式不匹配问题,可配置RestTemplate打印全量请求日志,将实际发出的JSON串和Postman正常请求的报文逐字段对比,可快速定位差异点,无需逐行查代码。
内容的提问来源于stack exchange,提问作者Halil Sahin
相关产品推荐
相关产品推荐

