Я работаю над проектом электронной политики, где мне нужно сохранять разные типы политик. Для простоты я рассматриваю только два вида «LifeInsurance» и «AutoInsurance». Чего я хочу добиться, так это того, что если запрос JSON на создание политики содержит «тип»: «AUTO_INSURANCE», тогда запрос должен быть сопоставлен с AutoInsurance.class аналогично для LifeInsurance, но в настоящее время в весеннем загрузочном приложении запрос сопоставляется с родительским классом. Политика устраняет специальные поля запроса для автострахования/страхования жизни. Модель домена, которую я создал, приведена ниже.
@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;
}
Ниже приведен дочерний класс типа LifeInsurance.
@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;
}
Чтобы сохранить детали полиса, я отправляю запрос JSON из пользовательского интерфейса со свойством «тип», указывающим тип страхования в запросе.
Когда я запускаю приведенный ниже тестовый метод, запрос 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 в постмэппинге RESTController, я получаю объект класса PArent вместо объекта дочернего класса.
@RestController
@RequestMapping("/policy")
public class PolicyController {
@PostMapping
public void savePolicy(Policy policy) {
System.out.println(policy.getClass());
}
}
Я могу получить JSON в виде строки, автоматически связать объект-сопоставитель и проанализировать вручную, но я хочу понять, является ли это известной проблемой, и сталкивался ли кто-нибудь с тем же с загрузкой Spring. Я искал решения по этому вопросу, но я нашел решение для десериализации полиморфных классов, но ничего не имело отношения к проблеме с загрузкой Spring.
Большое спасибо :). Это решило проблему. Я просто проверял имя класса, но не проверял данные, отображаются они или нет. После добавления заработало
Вы можете добавить это как ответ, я приму это.
В вашем методе вы не аннотировали аргумент метода Policy
с помощью @RequestBody
. Это приводит к тому, что Spring создает только экземпляр Policy
вместо использования Джексона для преобразования тела запроса.
@PostMapping
public void savePolicy(@RequestBody Policy policy) {
System.out.println(policy.getClass());
}
Добавление @RequestBody
приведет к тому, что Spring будет использовать Джексона для десериализации тела запроса, и при этом ваши аннотации/конфигурация будут эффективными.
У вас отсутствует аннотация
@RequestBody
в объекте запроса, поэтому ничего не будет десериализовано.