Десериализация JSON до полиморфных типов Spring boot - PullRequest
1 голос
/ 10 апреля 2019

Я работаю над проектом электронной политики, где мне нужно сохранять различные типы политик. Для простоты я рассматриваю только два типа "LifeInsurance" и "AutoInsurance". Чего я хочу добиться, так это если запрос JSON для создания политики содержит «type»: «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 из пользовательского интерфейса со свойством 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 в пост-отображении RESTController, я получаю объект класса PArent вместо объекта дочернего класса.

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

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

Я могу получить JSON в виде строки, autowire objectmapper и разобрать вручную, но я хочу понять, является ли это известной проблемой, и сталкивался ли кто-то еще с такой же загрузкой Spring. Я искал решения по этому вопросу, но получил решение о десериализации полиморфных классов, но ничего не касалось проблемы с загрузкой Spring.

1 Ответ

0 голосов
/ 10 апреля 2019

В вашем методе вы не аннотировали аргумент метода Policy с помощью @RequestBody. Что приводит к тому, что Spring создает только экземпляр Policy вместо использования Джексона для преобразования тела запроса.

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

Добавление @RequestBody сделает так, что Spring использует Джексона для десериализации тела запроса, и с этим ваши аннотации / конфигурация будут эффективными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...