J'utilise la bibliothèque Jackson pour la sérialisation de mes objets pojo en représentation JSON
. Par exemple, j'ai la classe A et la classe B:
class A {
private int id;
private B b;
constructors...
getters and setters
}
class B {
private int ind;
private A a;
constructors...
getters and setters
}
Si je veux sérialiser un objet de la classe A, il y a une certaine possibilité d'obtenir une récursivité pendant qu'il est sérialisé. Je sais que je peux l'arrêter en utilisant @JsonIgnore
.
Est-il possible de limiter la sérialisation par niveau de profondeur?
Par exemple, si le niveau est 2, la sérialisation se fera de cette façon:
Merci d'avance.
J'ai récemment rencontré un problème similaire: Jackson - sérialisation d'entités avec des relations bidirectionnelles (évitant les cycles)
La solution consiste donc à mettre à niveau vers Jackson 2.0 et à ajouter aux classes l'annotation suivante:
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "@id")
public class SomeEntityClass ...
Cela fonctionne parfaitement.
Vérifiez les liens suivants, cela pourrait vous aider:
La seule option après cela serait de créer votre propre module personnalisé pour la sérialisation/désérialisation pour votre type d'objet. vois ici:
Cordialement.
Il n'y a pas de support pour les ignorants basés sur le niveau.
Mais vous pouvez demander à Jackson de gérer les références cycliques avec 2.0, voir par exemple " Jackson 2.0 publié " pour des explications sur l'utilisation de @JsonIdentityInfo
.
Pour une sérialisation en profondeur, vous pouvez vous référer à l'exemple ici https://github.com/abid-khan/depth-wise-json-serializer
Si vous voulez vous limiter à un seul niveau (c'est-à-dire: vous allez aux enfants de l'objet courant et pas plus loin), il existe une solution simple avec @JsonView.
Sur chaque champ qui est un lien vers un autre objet, annotez-le avec la classe actuelle comme vue:
class A {
private int id;
@JsonView(A.class) private B b;
constructors...
getters and setters
}
class B {
private int ind;
@JsonView(B.class) private A a;
constructors...
getters and setters
}
Ensuite, lors de la sérialisation, utilisez la classe d'objets comme vue. La sérialisation d'une instance de A rendrait quelque chose comme ça:
{
id: 42,
b: {
id: 813
}
}
Assurez-vous que DEFAULT_VIEW_INCLUSION est défini sur true, sinon les champs sans annotation @JsonView ne seront pas rendus. Vous pouvez également annoter tous les autres champs avec @JsonView à l'aide de la classe Object ou de toute super-classe courante:
class A {
@JsonView(Object.class) private int id;
@JsonView(A.class) private B b;
constructors...
getters and setters
}
Dans certains cas, vous pouvez limiter la profondeur de sérialisation à l'aide d'un entier local de thread contenant une profondeur maximale. Voir ceci réponse .
Après plusieurs mois et beaucoup de recherches, j'ai implémenté ma propre solution pour garder mon domaine à l'abri des dépendances jackson.
public class Parent {
private Child child;
public Child getChild(){return child;}
public void setChild(Child child){this.child=child;}
}
public class Child {
private Parent parent;
public Child getParent(){return parent;}
public void setParent(Parent parent){this.parent=parent;}
}
Tout d'abord, vous devez déclarer chacune de vos entités de la relation bidirectionnelle dans quelque chose comme ceci:
public interface BidirectionalDefinition {
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Parent.class)
public interface ParentDef{};
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Child.class)
public interface ChildDef{};
}
Après cela, le mappeur d'objets peut être configuré automatiquement:
ObjectMapper om = new ObjectMapper();
Class<?>[] definitions = BidirectionalDefinition.class.getDeclaredClasses();
for (Class<?> definition : definitions) {
om.addMixInAnnotations(definition.getAnnotation(JsonIdentityInfo.class).scope(), definition);
}