我被一些傑克遜多態問題困住了。Jakson多態枚舉case
我在Web JDR Character Editor個人項目上工作。我使用Springboot並試圖堅持哲學。此外,我嘗試製作一些獨立的軟件包,因爲我的實際工作(另一個springboot項目)的研究案例。
沒有傑克遜配置,我沒有問題的序列化能力。但是當我試圖取回網頁編輯器的任何修改時,所以當傑克遜對權限進行反序列化時,「依賴」屬性會出現問題。
這裏是我的課:
一個我試圖序列化/解:
public class Competence implements Composante, ComposanteTemplate { public enum Categorie { APPRENTI, COMPAGNON } private String nom; private String description; private Categorie categorie; private Chapitre chapitre; private AttributTemplate dependance; private List sousCompetences = new ArrayList(); public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Competence getTemplate() { return this; } public Categorie getCategorie() { return categorie; } public void setCategorie(Categorie categorie) { this.categorie = categorie; } public Chapitre getChapitre() { return chapitre; } public void setChapitre(Chapitre chapitre) { this.chapitre = chapitre; } public AttributTemplate getDependance() { return dependance; } public void setDependance(AttributTemplate dependance) { this.dependance = dependance; } public List getSousCompetences() { return sousCompetences; } public void setSousCompetences(List sousCompetences) { this.sousCompetences = sousCompetences; } public boolean isOuverte() { return !sousCompetences.isEmpty(); } }
屬性的超我有一個問題:
public interface AttributTemplate extends ComposanteTemplate {}
兩個子類可用於能力#依賴屬性:
public enum Carac implements AttributTemplate, Attribut { FORT(Type.PHYSIQUE), AGILE(Type.PHYSIQUE), RESISTANT(Type.PHYSIQUE), OBSERVATEUR(Type.PHYSIQUE), SAVANT(Type.MENTALE), RUSE(Type.MENTALE), TALENTUEUX(Type.MENTALE), CHARMEUR(Type.MENTALE); public enum Type { PHYSIQUE, MENTALE } public final Type type; public final String nom = name().toLowerCase(); private String description; Carac(Type type) { this.type = type; } @Override public String getNom() { return nom; } @Override public String getDescription() { return description; } @Override public Carac getTemplate() { return this; } public void setDescription(String description) { this.description = description; } }
public enum ArtTemplate implements AttributTemplate { ART_GUERRIER(2, 1), ART_ETRANGE(1, 2), ART_GUILDIEN(1, 1); public static final String ART_PREFIX = "ART"; public final String nom = name().toLowerCase().replace("_", " "); public final int nbCaracsPhysiques; public final int nbCaracsMentales; private String description; ArtTemplate(int nbCaracsPhysiques, int nbCaracsMentales) { this.nbCaracsMentales = nbCaracsMentales; this.nbCaracsPhysiques = nbCaracsPhysiques; } @Override public String getNom() { return nom; } @Override public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getNbCaracs() { return nbCaracsPhysiques + nbCaracsMentales; } }
結果JSON(然後我發送JSON)是:
{"nom":"Comp_1489746646510","description":"ezbuixnwrclfvmgwdviubcauenzytpzzvumnohwyhpuynxaqhkjdbqygtrmbtlschthovuyoiolkauucwokkfjnaujnufshrjboykuqce","categorie":"APPRENTI","chapitre":"GUERRE","dependance":"ART_ETRANGE","ouverte":false,"sousCompetences":[]}
問題: 據我所知,我的問題是由抽象的關係AttributTemplate引起的,然後當傑克遜嘗試反序列化,他不知道要使用哪個Carac或ArtTemplate類。 我試圖保持不變能力(能力來自外部的jar),所以這個類沒有註釋是可能的。
我試過很多我找到的解決(Jackson 1.5: Polymorphic Type Handling, first steps),只有已工作的一個是定義DeserializationProblemHandler
mapper.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleMissingInstantiator(DeserializationContext ctxt, Class<?> instClass, JsonParser p, String msg) throws IOException {
if (instClass == AttributTemplate.class) {
String name = p.getText();
return !name.startsWith(ArtTemplate.ART_PREFIX) ? Carac.valueOf(name) : ArtTemplate.valueOf(name);
}
return super.handleMissingInstantiator(ctxt, instClass, p, msg);
}
});
但是我對這個解決方案感到不滿,因爲我確信還有另外一個漂亮的解決方案。
那麼是否可以配置映射器,以便他能夠確定他必須使用哪個Carac或ArtTemplate才能獲得AttributTemplate?
編輯: 我設法有這樣的:通過這樣的配置映射器
abstract class CompetenceMixIn { private AttributTemplate dependance; @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.EXISTING_PROPERTY, property="dependance") @JsonSubTypes({ @JsonSubTypes.Type(value = Carac.class, name = "carac"), @JsonSubTypes.Type(value = ArtTemplate.class, name = "artTemplate") }) public void setDependance(AttributTemplate dependance) { this.dependance = dependance; } }
ObjectMapper mapper = jsonConverter.getObjectMapper(); mapper.addMixIn(Competence.class, CompetenceMixIn.class);
{"nom":"Comp_1489756873433","description":"kruzueemlwisibshlkotasayfkhdqkqolvhlqgsnntndkpvbmmgklqysabiakaolempmupeyiqaztdcrhwimdksgzybbdzttwnwqjxhfo","categorie":"COMPAGNON","chapitre":"GUERRE","dependance":["mova.ged.perso.inne.Carac","AGILE"],"ouverte":true,"sousCompetences":[...]}
正如你可以看到,我仍然與包裹的陣列一起寄生值。我會(...)"dependance": "AGILE", (...)
不是(...)"dependance":["mova.ged.perso.inne.Carac", "AGILE"], (...)
而我不知道要改變這個。
我已經回答過類似的問題。傑克遜允許這是可配置的。我不想爲你的具體情況重塑這個,所以請看看這裏:http://stackoverflow.com/questions/38501574/rules-for-jersey-to-parse-json-jackson-subtype-deserialisation/ 38523801#38523801這裏的例子非常簡單。 Params類有2個實現,我告訴傑克遜什麼屬性來查找如何反序列化它 – pandaadb
我嘗試你的例子,但仍然無法找到真正的解決方案。我通過解決方案的開始修改了我的帖子,我感謝你。 – Mohicane
仍然有問題....我無法想象有這樣的問題,對我來說這麼簡單的事情? – Mohicane