Я использую Джексона для десериализации этого класса
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiSocieta.class, name = "datiSocieta"),
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "datiPersonaFisica") ,
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "datiDittaIndividuale") }
)
public interface Dati {
}
Проблема в том, что datiPersonaFisica и datiDittaIndividuale неоднозначны.
@Data
public
class DatiPersonaFisica implements Dati {
private String codiceFiscale;
private String sesso;
private String nome;
private String cognome;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dataNascita;
private String luogoNascita;
private String provinciaNascita;
private String nazioneNascita;
}
@Data
public
class DatiDittaIndividuale implements Dati {
private String denominazione;
private String codiceFiscale;
private String sesso;
private String nome;
private String cognome;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dataNascita;
private String luogoNascita;
private String provinciaNascita;
private String nazioneNascita;
private String numeroRea;
private String provinciaCCIA;
private String partitaIVA;
}
Поэтому это дает мне ошибку
Ошибка анализа JSON: не удалось разрешить подтип [простой тип, класс com.XXXX.cmp.cgw.webclient.bo.Dati]: невозможно определить уникальный подтип
com.xxxx.cmp.cgw.webclient.bo.Dati(соответствуют 2 кандидата); вложенный исключением является com.fasterxml.jackson.databind.exc.InvalidTypeIdException: не удалось разрешить подтип [простой тип, класс com.xxxx.cmp.cgw.webclient.bo.Dati]: невозможно определить уникальный подтипcom.xxxx.cmp.cgw.webclient.bo.Dati(соответствуют 2 кандидата)\n в [Источник: (org.springframework.util.StreamUtils$NonClosingInputStream); строка: 12, столбец: 5] (через цепочку ссылок: com.xxxx.cmp.cgw.webclient.dto.ClienteDTO["soggetto"]->com.xxxx.cmp.cgw.webclient.bo.Soggetto["anagrafica"])
Я хотел бы автоматически определить datiPersonaFisica, если определенные поля datiDittaIndividuale отсутствуют. Но я не могу найти как это сделать в документации.




Атрибуты вашего класса DatiPersonaFisica являются подмножеством атрибутов класса DatiDittaIndividuale. Если Джексон попытается десериализовать Json, содержащий только поля из DatiPersonaFisica, он не сможет определить, какой экземпляр создавать, поскольку Json соответствует отпечаткам обоих ваших классов. См. выпуск #3577 в официальном репозитории Jackson-databind.
Json, созданный только с полями из DatiPersonaFisica, может быть либо экземпляром DatiPersonaFisica, либо экземпляром DatiDittaIndividuale, чьи единственные сериализованные поля являются общими с DatiPersonaFisica; следовательно, сообщение об ошибке:
Невозможно определить уникальный подтип com.xxxx.cmp.cgw.webclient.bo.Dati (соответствуют 2 кандидата)
В вашем случае, поскольку невозможно определить, какой класс с помощью Json DatiPersonaFisica, вы можете либо использовать реализацию с JsonTypeInfo.As.PROPERTY, либо JsonTypeInfo.As.EXTERNAL_PROPERTY, как предложено в теме проблем.
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "datiType"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiSocieta.class, name = "datiSocieta"),
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "datiPersonaFisica"),
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "datiDittaIndividuale")
})
public interface Dati {
}
@Data
public class DatiSocieta implements Dati {
// fields...
}
@Data
public class DatiPersonaFisica implements Dati {
// fields...
}
@Data
public class DatiDittaIndividuale implements Dati {
// fields...
}
Вот демо-версия OneCompiler 1
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "DatiPersonaFisica"),
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "DatiDittaIndividuale")
})
public class Company {
protected Dati dati;
//constructors
//getters and setters
}
public class Dati {
private String nome;
private String cognome;
//constructors
//getters and setters
}
public class DatiPersonaFisica extends Company {
//constructors
//getters and setters
}
public class DatiDittaIndividuale extends Company {
private String denominazione;
//constructors
//getters and setters
}
Вот ссылка на вторую реализацию в OneCompiler 2
@Lore Deduction не может работать в вашем случае. DatiPersonaFisica всегда будет генерировать неоднозначный JSON, который соответствует отпечатку обоих ваших классов. Вот ссылка на проблему № 3577 официального репозитория Jackson-Databind, где пользователь проиллюстрировал вашу ту же проблему. Предлагаемые решения заключались в использовании JsonTypeInfo.As.PROPERTY (как в ответе) или JsonTypeInfo.As.EXTERNAL_PROPERTY. github.com/FasterXML/jackson-databind/issues/…
Что касается этого ответа, он кажется неразрешимым методом дедукции. Вместо этого я использовал альтернативную стратегию:
@Data
public class Soggetto {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "tipo")
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiSocieta.class, name = "SOCIETA"),
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "PERSONA_FISICA") ,
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "DITTA_INDIVIDUALE") }
)
private Dati anagrafica;
private Residenza residenza;
private String tipo;
}
Я предпочитаю не использовать этот метод и вместо этого использовать дедуцирование.