Spring GET接口JSON参数映射异常:仅支持String字段问题排查
问题分析与解决方案
核心原因
- Spring参数绑定限制:
@RequestParam默认仅支持String、Integer这类简单类型的参数绑定,无法自动将URL参数中的JSON字符串反序列化为包含Set<Long>这类复杂类型的DTO对象。Spring没有默认配置对这种场景的解析逻辑,导致无法正确映射字段。 - 测试请求格式错误:你提供的Cucumber请求中,
filter参数值被额外包裹了一层双引号(filter="{\"shipper_ids\":[333444]}"),实际传递的是带外层引号的字符串,而非合法的JSON对象,进一步触发了解析失败。
解决方案
方案1:手动在控制器中解析JSON参数
修改控制器方法,先接收String类型的参数,再用Jackson手动解析为目标DTO:
@GetMapping(path = "v2/warehouses/limited") public List<WarehouseSimpleListDto> getRestrictedWarehouses( @RequestParam(required = false, defaultValue = "{}") String filterStr ) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); WarehouseSearchFilterSimpleDto filter = objectMapper.readValue(filterStr, WarehouseSearchFilterSimpleDto.class); // 后续业务逻辑处理 }
方案2:自定义Converter让Spring自动解析
创建一个类型转换组件,让Spring自动将String参数转换为目标DTO:
@Component public class StringToWarehouseFilterConverter implements Converter<String, WarehouseSearchFilterSimpleDto> { private final ObjectMapper objectMapper; // 注入Spring容器中的ObjectMapper实例 public StringToWarehouseFilterConverter(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } @Override public WarehouseSearchFilterSimpleDto convert(String source) { try { return objectMapper.readValue(source, WarehouseSearchFilterSimpleDto.class); } catch (JsonProcessingException e) { throw new IllegalArgumentException("Filter参数JSON格式错误", e); } } }
添加该Converter后,控制器方法可以保持原有写法不变,Spring会自动完成类型转换。
方案3:修正测试请求的参数格式
去掉filter参数值外层的多余双引号,正确的请求URL应为:
/api/rest/v2/warehouses/limited?filter={"shipper_ids":[333444]}
对应Cucumber步骤写法:
Given I request GET at endpoint: """ /api/rest/v2/warehouses/limited?filter={"shipper_ids":[333444]} """ Then the response status code should be 200
关于“同类接口正常工作”的说明
你提到的结构相似但能正常工作的接口,大概率其DTO仅包含String等简单类型——Spring可以直接完成字符串到简单类型的绑定,无需额外解析逻辑;而当前DTO包含Set<Long>这类复杂集合类型,必须显式配置JSON解析逻辑才能完成绑定。
内容的提问来源于stack exchange,提问作者Matexon
相关产品推荐
相关产品推荐

