2016-07-28 16 views
2

einzuführen Ich entwickle eine Anwendung, die auf diese Weise architectured ist.
A Baseobject enthält folgende Felder:Verhindern Jackson @JsonIgnore, um die Duplizierung

public class BaseObject { 
    private String id; 
    private Instant creationDate; 
    private String createdBy; 
    private Instant lastEditionDate; 
    private String lastEditBy; 
    private Instant deletionDate; 
    private String deletedBy; 
} 

Jede Klasse erweitert diese Baseobject so dass ich mit zwei POJOs am ​​Ende wie folgt:

public class Pojo1 extends BaseObject { 
    private SubPojo1 subPojo1; 
    private SubPojo2 subPojo2; 
} 

public class Pojo2 extends BaseObject { 
    private SubPojo3 subPojo3; 
    private SubPojo4 subPojo4; 
} 

Diese beiden POJOs keine funktionelle Beziehung haben. Sie bestehen aus SubPojo, die auf funktionelle Weise Gruppenfelder bilden.

Hier kommt mein Problem. Meine Anwendung sendet Daten per JSON an eine BI-App. Die BI-App muss das POJO in ein "flaches" Format bringen, und ich möchte die BaseObject-Felder ausschließen.

So kam ich mit auf den Punkt:

public class FlatPojo1 extends Pojo1 { 
    @Override 
    @JsonIgnore 
    public String getId() { 
     return super.getId(); 
    } 
    /* Override every getter of BaseObjet */ 

    @Override 
    @JsonUnwrapped 
    public SubPojo1 getSubPojo1 { 
     return super.getSubPojo1(); 
    } 
    /* Override every getter of Pojo1 */ 
} 

Meine Lösung arbeitet, die BI-App die Daten im richtigen Format erhalten und ich kann immer noch meine Objekte mit Unterobjekte behandeln.

Die Sache, die mich stören, ist die Code-Duplizierung. Für jedes flache Objekt muss ich jeden Getter meines BaseObject überschreiben. Ich möchte nicht.

Java erlaubt nicht mehrere Erbe, also kann ich keine abstrakte Klasse, dass @ JsonIgnore jedes BaseObject-Feld und auch meine Pojo1 erweitern.

Ich habe versucht, mit einer Schnittstelle so zu kommen:

public interface BaseObjectInterface { 
    String getId(); 
    Instant getCreationDate(); 
    // etc 
} 

My Baseobject jetzt implementiert BaseObjectInterface, ist alles ok.Then der Plan eine FlatData Schnittstelle zu schaffen, die die Felder und Baseobject jedes FlatPojo wird @JsonIgnore wird diese Schnittstelle implementieren. Ich kam mit diesem:

public interface FlatData extends BaseObjectInterface { 
    @Override 
    @JsonIgnore 
    default String getId() { 
     BaseObjectInterface.super.getId(); // Error 
    } 

Ich bekomme eine Fehlermeldung, die mir sagt, dass ich eine abstrakte Methode nicht aufrufen kann. Und ich kann keine getId() - Standardmethode in meinem BaseObjectInterface erstellen, da dies ein ID-Feld erfordern würde und jedes Feld in einer Schnittstelle statisch wäre.

Ich kann keinen Weg finden, alle Thesen @JsonIgnore zu vermeiden. Gibt es einen Weg, es zu tun?
Vielen Dank für Ihre Hilfe.

Antwort

2

Sie können Mixin Annotationen verwenden, wobei in der Schnittstelle Sie die Anmerkungen hinzufügen:

public interface BaseObjectMixIn { 
     @JsonIgnore 
     String getId(); 

     ... rest of annotations for superclass 
    } 

diese Weise müssen Sie nichts hinzufügen, aber die mixin zu den Mapper hinzufügen:

ObjectMapper mapper = new ObjectMapper(); 
mapper.addMixInAnnotations(Pojo1.class, BaseObjectMixIn.class); 

String json = mapper.writer().writeValueAsString(pojo1); 

Wenn Sie es für jede Baseobject-Unterklasse wollen:

ObjectMapper mapper = new ObjectMapper(); 
mapper.addMixInAnnotations(BaseObject.class, BaseObjectMixIn.class); 

aber eine einfachere Lösung, ohne mixin und nur eine Schnittstelle zur Unterklasse ist das Hinzufügen:

public interface BaseOjectInterface { 
     @JsonIgnore 
     String getId(); 
    } 

public static class Pojo1 extends BaseObject implements BaseOjectInterface { 
     private String subPojo1; 
     private String subPojo2; 

Dadurch wird vermieden, die ID von Baseobject zu senden, wenn die Serialisierung Pojo1

+0

Funktioniert prima, vielen Dank! :) – Berhthun