Je veux sérialiser une classe POJO qui n'est pas sous mon contrôle, mais je veux éviter de sérialiser toutes les propriétés qui proviennent de la superclasse, et non de la classe finale. Exemple:
public class MyGeneratedRecord extends org.jooq.impl.UpdatableRecordImpl<...>,
example.generated.tables.interfaces.IMyGenerated {
public void setField1(...);
public Integer getField1();
public void setField2(...);
public Integer getField2();
...
}
Vous pouvez deviner à partir de l'exemple que cette classe est générée par JOOQ et hérite d'une classe de base complexe UpdatableRecordImpl qui a également des méthodes de type propriété de bean, qui causent des problèmes pendant la sérialisation. De plus, j'ai plusieurs classes similaires, il serait donc bon d'éviter de dupliquer la même solution pour tous mes POJO générés.
Jusqu'à présent, j'ai trouvé les solutions possibles suivantes:
ignorer les champs spécifiques provenant de la superclasse en utilisant la technique de mixage comme ceci: Comment puis-je dire à jackson d'ignorer une propriété dont je n'ai pas le contrôle sur le code source?
Le problème avec cela est que si la classe de base change (par exemple, une nouvelle méthode getAnything () y apparaît), elle peut casser mon implémentation.
implémentez un sérialiseur personnalisé et gérez-y le problème. Cela me semble un peu exagéré.
comme d'ailleurs j'ai une interface qui décrit exactement les propriétés que je veux sérialiser, peut-être que je peux mélanger une annotation @JsonSerialize (as = IMyGenerated.class) ...? Puis-je l'utiliser pour mon but?
Mais, du point de vue de la conception pure, le mieux serait de pouvoir dire à jackson que je veux sérialiser uniquement les propriétés de la classe finale et ignorer toutes les propriétés héritées. Y-a-t-il un moyen de faire ça?
Merci d'avance.
Vous pouvez enregistrer un intropecteur d'annotation Jackson personnalisé qui ignorerait toutes les propriétés provenant d'un certain super type. Voici un exemple:
public class JacksonIgnoreInherited {
public static class Base {
public final String field1;
public Base(final String field1) {
this.field1 = field1;
}
}
public static class Bean extends Base {
public final String field2;
public Bean(final String field1, final String field2) {
super(field1);
this.field2 = field2;
}
}
private static class IgnoreInheritedIntrospector extends JacksonAnnotationIntrospector {
@Override
public boolean hasIgnoreMarker(final AnnotatedMember m) {
return m.getDeclaringClass() == Base.class || super.hasIgnoreMarker(m);
}
}
public static void main(String[] args) throws JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new IgnoreInheritedIntrospector());
final Bean bean = new Bean("a", "b");
System.out.println(mapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(bean));
}
}
Production:
{"field2": "b"}
Vous pouvez remplacer les méthodes de la superclasse que vous souhaitez empêcher de sortir et les annoter avec @JsonIgnore. La substitution déplace le contrôle de la création de propriété vers la sous-classe tout en permettant sa capacité à la filtrer à partir de la sortie.
Par exemple:
public class SomeClass {
public void setField1(...);
public Integer getField1();
public void setField2(...);
public Integer getField2();
@Override
@JsonIgnore
public String superClassField1(...){
return super.superClassField1();
};
@Override
@JsonIgnore
public String superClassField2(...){
return super.superClassField2();
};
...
}
La bonne utilisation de l'héritage est que les classes enfants étendent ou ajoutent des fonctionnalités. La manière habituelle est donc de sérialiser les données.
Une solution de contournement consisterait à utiliser un objet de valeur (VO) ou un objet de transfert de données (DTO) avec les champs dont vous avez besoin pour sérialiser. Pas:
Vous pouvez également l'utiliser au lieu de remplacements inutiles
@JsonIgnoreProperties({ "aFieldFromSuperClass"})
public class Child extends Base {
private String id;
private String name;
private String category;
}