gpt4 book ai didi

java - Spring boot 将 JSON 反序列化为多态类型

转载 作者:太空宇宙 更新时间:2023-11-04 09:44:18 26 4
gpt4 key购买 nike

我正在开发一个电子保单项目,我需要保存不同类型的保单。为简单起见,我只考虑两种类型“人寿保险”和“汽车保险”。我想要实现的是,如果创建保单的 JSON 请求包含“type”:“AUTO_INSURANCE”,那么该请求应该映射到 AutoInsurance.class,同样适用于 LifeInsurance,但目前在 Spring Boot 应用程序中,该请求被映射到父类 Policy,消除了汽车/人寿保险的特定请求字段。我创建的域模型如下。

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@NoArgsConstructor
@Getter
@Setter
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =
JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @Type(value = AutoInsurance.class, name = "AUTO_INSURANCE"),
@Type(value = LifeInsurance.class) })
public class Policy {

@Id
@GeneratedValue
private Long id;
private String policyNumber;
@Enumerated(EnumType.STRING)
private PolicyType policyType;
private String name;

}

我的汽车保险类别如下。

@Entity
@NoArgsConstructor
@Getter
@Setter
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonTypeName(value = "AUTO_INSURANCE")
public class AutoInsurance extends Policy {

@Id
@GeneratedValue
private Long id;
private String vehicleNumber;
private String model;
private String vehicleType;
private String vehicleName;

}

下面是人寿保险类型的子类

@Entity
@NoArgsConstructor
@Getter
@Setter
@JsonTypeName(value = "LIFE_INSURANCE")
public class LifeInsurance extends Policy {

@OneToMany(mappedBy = "policy")
private List<Dependents> dependents;
private String medicalIssues;
private String medication;
private String treatments;

}

为了保存保单详细信息,我从 UI 发送 JSON 请求,其中包含一个“type”属性,指示请求中的保险类型。

当我运行下面的测试方法时,JSON 请求会根据需要映射到正确的子类。

public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException  {
ObjectMapper map = new ObjectMapper();
String s = "{\"id\": 1,\"policyNumber\": \"Aut-123\",\"type\": \"AUTO_INSURANCE\",\"policyType\": \"AUTO_INSURANCE\",\"name\": null,\"address\": null,\"contact\": null,\"agentNumber\": null,\"agentName\": null,\"issuedOn\": null,\"startDate\": null,\"endDate\": null,\"vehicleNumber\": \"HR\",\"model\": null,\"vehicleType\": \"SUV\",\"vehicleName\": null}";
Policy p = map.readValue(s, Policy.class);
System.out.println(p.getClass());
//SpringApplication.run(EPolicyApplication.class, args);
}

但是当我在 Spring boot 中的 RESTController 后映射中运行相同的操作时,我得到的是 PArent 类对象而不是子类对象。

@RestController
@RequestMapping("/policy")
public class PolicyController {

@PostMapping
public void savePolicy(Policy policy) {
System.out.println(policy.getClass());
}
}

我可以将 JSON 作为字符串获取, Autowiring 对象映射器并手动解析,但我想了解这是否是一个已知问题以及其他人是否在 Spring boot 中遇到过同样的问题。我已经搜索了这方面的解决方案,但我得到了反序列化为多态类的解决方案,但与 Spring boot 的问题没有任何关系。

最佳答案

在您的方法中,您尚未使用 @RequestBody 注释 Policy 方法参数。这导致 Spring 仅创建一个 Policy 实例,而不是使用 Jackson 来转换请求正文。

@PostMapping
public void savePolicy(@RequestBody Policy policy) {
System.out.println(policy.getClass());
}

添加@RequestBody将使Spring使用Jackson反序列化请求主体,这样你的注释/配置就会生效。

关于java - Spring boot 将 JSON 反序列化为多态类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55611341/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com