Comment puis-je dire à jackson d'ignorer une propriété pour laquelle je n'ai pas le contrôle du code source?

pour faire court, une de mes entités a un GeometryCollection qui jette une exception quand on appelle "get boundary" (le pourquoi de ce livre est un autre, pour l'instant disons que c'est la façon dont ça marche).

y a-t-il un moyen de dire à Jackson de ne pas inclure ce getter spécifique? Je sais que je peux utiliser @JacksonIgnore quand je possède / contrôle le code. Mais ce n'est pas le cas, jackson finit par atteindre ce point par la sérialisation continue de la les objets parents. J'ai vu une option de filtrage dans la documentation de jackson. Est-ce une solution plausible?

Merci!

89
demandé sur fabien7474 2011-09-14 22:52:10

8 réponses

Vous pouvez utiliser Jackson Mixin . Par exemple:

class YourClass {
  public int ignoreThis() { return 0; }    
}

avec ce mélange

abstract class MixIn {
  @JsonIgnore abstract int ignoreThis(); // we don't need it!  
}

avec ceci:

objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);

Edit:

Merci aux commentaires, avec Jackson 2.5+, L'API a changé et doit être appelé avec objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)

133
répondu Amir Raminfar 2015-05-12 15:31:56

Une autre possibilité est, si vous voulez ignorer toutes les propriétés inconnues, vous pouvez configurer le mapper comme suit:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
56
répondu laloumen 2013-09-17 13:10:42

Utilisant La Classe Java

new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Utilisant L'Annotation

@JsonIgnoreProperties(ignoreUnknown=true)
20
répondu Sireesh Yarlagadda 2017-09-05 15:14:01

Mix-in annotations fonctionnent assez bien ici comme déjà mentionné. Une autre possibilité au-delà de @JsonIgnore est d'utiliser @JsonIgnoreType si vous avez un type qui ne devrait jamais être inclus (i.e. si toutes les instances des propriétés de GeometryCollection devraient être ignorées). Vous pouvez alors soit l'ajouter directement (si vous contrôlez le type), ou en utilisant mix-in, comme:

@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule

cela peut être plus pratique si vous avez beaucoup de classes que tous ont un seul 'IgnoredType getContext()' accesseur ou (ce qui est le cas pour de nombreux cadres)

8
répondu StaxMan 2011-09-15 17:23:30
public @interface JsonIgnoreProperties

Annotation qui peut être utilisée pour supprimer la sérialisation des propriétés (pendant la sérialisation), ou ignorer le traitement des propriétés JSON lues (pendant la desérialisation).

pour éviter que certains champs ne soient sérialisés ou désérialisés, vous pouvez utiliser:

@JsonIgnoreProperties(ignoreUnknown=true)
8
répondu Yasir Shabbir Choudhary 2015-10-24 18:12:42

j'avais un problème similaire, mais il était lié aux relations bidirectionnelles D'hibernation. Je voulais montrer un côté de la relation et ignorer programmatiquement l'autre, en fonction de ce que je traitais avec. Si vous ne pouvez pas faire cela, vous vous retrouvez avec nasty StackOverflowException . Par exemple, si j'avais ces objets

public class A{
  Long id;
  String name;
  List<B> children;
}

public class B{
  Long id;
  A parent;
}

je voudrais ignorer programmatiquement le champ parent dans B si je regardais A, et ignorer le champ children dans A Si je regardais B.

j'ai commencé à utiliser mixins pour faire cela, mais cela devient très vite horrible; vous avez tellement de classes inutiles qui traînent autour qui existent uniquement pour formater des données. J'ai fini par écrire mon propre sérialiseur pour gérer cela d'une manière plus propre: https://github.com/monitorjbl/json-view .

il vous permet de spécifier par programmation les champs à ignorer:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

List<A> list = getListOfA();
String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(B.class, match()
        .exclude("parent")));

il permet aussi vous pouvez facilement spécifier des vues très simplifiées à l'aide de jokers:

String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(A.class, match()
        .exclude("*")
         .include("id", "name")));

dans mon premier cas, le besoin de simples vues comme celle-ci était de montrer le strict minimum Au sujet du parent/enfant, mais il est également devenu utile pour notre sécurité fondée sur le rôle. Des vues moins privilégiées des objets nécessaires pour retourner moins d'informations sur l'objet.

tout cela vient du serializer, mais j'ai utilisé MVC printemps dans mon application. Pour l'obtenir pour traiter correctement ces cas, j'ai écrit une intégration que vous pouvez déposer dans les classes de contrôleur de printemps existantes:

@Controller
public class JsonController {
  private JsonResult json = JsonResult.instance();
  @Autowired
  private TestObjectService service;

  @RequestMapping(method = RequestMethod.GET, value = "/bean")
  @ResponseBody
  public List<TestObject> getTestObject() {
    List<TestObject> list = service.list();

    return json.use(JsonView.with(list)
        .onClass(TestObject.class, Match.match()
            .exclude("int1")
            .include("ignoredDirect")))
        .returnValue();
  }
}

les deux sont disponibles sur Maven Central. J'espère que cela aide quelqu'un d'autre, c'est particulièrement laid problème avec Jackson qui n'ont pas une bonne solution pour mon cas.

5
répondu monitorjbl 2015-06-14 16:06:15

L'approche basée sur L'Annotation est meilleure. Mais parfois, l'opération manuelle est nécessaire. Pour ce faire, vous pouvez utiliser sans méthode de ObjectWriter .

ObjectMapper mapper   = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer   = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String       jsonText = writer.writeValueAsString(sourceObject);
4
répondu Fırat KÜÇÜK 2017-04-02 12:00:00

Un bon point ici est d'utiliser @JsonFilter . Quelques détails ici http://wiki.fasterxml.com/JacksonFeatureJsonFilter

0
répondu Vladimir Filipchenko 2015-09-01 13:04:10