¿Cómo puedo decirle a Jackson que ignore una propiedad para la que no tengo control sobre el código fuente?

Para abreviar, una de mis entidades tiene una GeometryCollection que arroja una excepción cuando llamas “getBoundary” (el porqué de este es otro libro, por ahora digamos que así es como funciona).

¿Hay alguna manera en que pueda decirle a Jackson que no incluya ese getter específico? Sé que puedo usar @JacksonIgnore cuando poseo / controlo el código. Pero este no es el caso, Jackson termina llegando a este punto a través de la serialización continua de los objetos principales. Vi una opción de filtrado en la documentación de Jackson. ¿Es esa una solución plausible?

¡Gracias!

Puedes usar Jackson Mixins . Por ejemplo:

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

Con este Mixin

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

Con este:

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

Editar:

Gracias a los comentarios, con Jackson 2.5+, la API ha cambiado y debe llamarse con objectMapper.addMixIn(Class target, Class mixinSource)

Otra posibilidad es que, si desea ignorar todas las propiedades desconocidas, puede configurar el asignador de la siguiente manera:

 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

Usando la clase de Java

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

Usando la anotación

 @JsonIgnoreProperties(ignoreUnknown=true) 

Las anotaciones mixtas funcionan bastante bien aquí como ya se mencionó. Otra posibilidad más allá de la propiedad @JsonIgnore es usar @JsonIgnoreType si tiene un tipo que nunca debería incluirse (es decir, si se deben ignorar todas las instancias de las propiedades de GeometryCollection). A continuación, puede agregarlo directamente (si controla el tipo) o usar mezcla, como:

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

Esto puede ser más conveniente si tiene muchas clases que tienen un único accesoador ‘IgnoredType getContext ()’ o similar (que es el caso de muchos frameworks)

 public @interface JsonIgnoreProperties 

Anotación que puede utilizarse para suprimir la serialización de propiedades (durante la serialización) o ignorar el procesamiento de las propiedades de JSON leídas (durante la deserialización).

para evitar que los campos especificados sean serializados o deserializados, puede usar:

 @JsonIgnoreProperties(ignoreUnknown=true) 

Tenía un problema similar, pero estaba relacionado con las relaciones bidireccionales de Hibernate. Quería mostrar un lado de la relación e ignorar el otro por progtwigción, según la visión con la que estuviese tratando. Si no puedes hacer eso, terminas con desagradables StackOverflowException . Por ejemplo, si tuviera estos objetos

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

Me gustaría ignorar programáticamente el campo parent en B si estuviera mirando A, e ignorar el campo secundario en A si estuviera mirando a B.

Empecé usando mixins para hacer esto, pero eso rápidamente se vuelve horrible; tienes tantas clases inútiles por ahí que existen únicamente para formatear datos. Terminé escribiendo mi propio serializador para manejar esto de una manera más limpia: https://github.com/monitorjbl/json-view .

Le permite especificar mediante progtwigción qué campos ignorar:

 ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(JsonView.class, new JsonViewSerializer()); mapper.registerModule(module); List list = getListOfA(); String json = mapper.writeValueAsString(JsonView.with(list) .onClass(B.class, match() .exclude("parent"))); 

También le permite especificar fácilmente vistas muy simplificadas a través de comodines comodín:

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

En mi caso original, la necesidad de vistas simples como esta era mostrar el mínimo indispensable sobre el padre / hijo, pero también se volvió útil para nuestra seguridad basada en roles. Vistas menos privilegiadas de los objetos necesarios para devolver menos información sobre el objeto.

Todo esto proviene del serializador, pero estaba usando Spring MVC en mi aplicación. Para que maneje adecuadamente estos casos, escribí una integración que puede incluir en las clases de controlador Spring existentes:

 @Controller public class JsonController { private JsonResult json = JsonResult.instance(); @Autowired private TestObjectService service; @RequestMapping(method = RequestMethod.GET, value = "/bean") @ResponseBody public List getTestObject() { List list = service.list(); return json.use(JsonView.with(list) .onClass(TestObject.class, Match.match() .exclude("int1") .include("ignoredDirect"))) .returnValue(); } } 

Ambos están disponibles en Maven Central. Espero que ayude a alguien más, este es un problema particularmente feo con Jackson que no tenía una buena solución para mi caso.

El enfoque basado en anotaciones es mejor. Pero a veces se necesita una operación manual. Para este propósito puede usar sin método 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 buen punto más aquí es usar @JsonFilter . Algunos detalles aquí http://wiki.fasterxml.com/JacksonFeatureJsonFilter