Spring Boot如何定义接收超类子类实例列表的REST API接口
修复方案
1. 配置抽象父类的Jackson多态反序列化规则
SuperObject是抽象类,默认情况下Jackson无法判断反序列化时应该实例化哪个子类,需要通过注解明确多态识别规则:
@Data @SuperBuilder @NoArgsConstructor @Validated // 配置多态识别字段:每个JSON对象通过type字段区分子类类型 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") // 配置子类和type取值的映射关系 @JsonSubTypes({ @JsonSubTypes.Type(value = SubType1OfSuperObject.class, name = "sub1"), @JsonSubTypes.Type(value = SubType2OfSuperObject.class, name = "sub2") }) public abstract class SuperObject { private Integer prop1; private String prop2; }
每个请求体中的JSON对象必须携带type字段,取值对应注解中配置的name值,Jackson会自动根据该字段反序列化为对应子类实例
2. 修正接口参数错误
你当前接口的参数名拼写有误,先修正:
@PostMapping(path = "store", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.OK) @ResponseBody public String store(@RequestBody List<? extends SuperObject> objects, @RequestParam Technology technology) { theService.saveObjectsByTechnology(objects, technology); return "Perfect!"; }
3. 调整Postman请求格式
你当前接口直接接收List类型的请求体,不需要外层包裹对象,请求体直接传数组即可:
[ { "type": "sub1", "prop1": 4, "prop2": "foo", "prop3": "xxx" }, { "type": "sub1", "prop1": 7, "prop2": "Bar", "prop3": "zzz" }, { "type": "sub2", "prop1": 10, "prop2": "test", "prop4": "SubType2专属字段" } ]
如果确实需要保留外层包裹对象的请求格式,需要单独定义封装类:
@Data public class SuperObjectRequest { private List<? extends SuperObject> subtype1OfSuperObjects; }
再将接口的@RequestBody参数类型改为SuperObjectRequest即可。
内容的提问来源于stack exchange,提问作者du-it
相关产品推荐
相关产品推荐

