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!
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)
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);
Utilisant La Classe Java
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
Utilisant L'Annotation
@JsonIgnoreProperties(ignoreUnknown=true)
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)
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)
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.
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);
Un bon point ici est d'utiliser @JsonFilter
.
Quelques détails ici http://wiki.fasterxml.com/JacksonFeatureJsonFilter