¿Cómo excluyo campos con Jackson sin usar anotaciones?

Necesito excluir algunos campos por nombres antes de la representación. La lista de campos es dinámica, por lo que no puedo usar anotaciones.

Intenté crear un serializador personalizado pero no puedo obtener el nombre del campo allí.

En GSON he usado ExclusionStrategy , pero Jackson no tiene esa funcionalidad. ¿Hay un equivalente?

El siguiente ejemplo de exclusión de campos por nombre es de mi publicación de blog, Gson v Jackson – Parte 4 . (Busque el PropertyFilterMixIn .) Este ejemplo demuestra el uso de un FilterProvider con un SimpleBeanPropertyFilter para serializeAllExcept SimpleBeanPropertyFilter una lista de nombres de campo especificada por el usuario.

 @JsonFilter("filter properties by name") class PropertyFilterMixIn {} class Bar { public String id = "42"; public String name = "Fred"; public String color = "blue"; public Foo foo = new Foo(); } class Foo { public String id = "99"; public String size = "big"; public String height = "tall"; } public class JacksonFoo { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.getSerializationConfig().addMixInAnnotations( Object.class, PropertyFilterMixIn.class); String[] ignorableFieldNames = { "id", "color" }; FilterProvider filters = new SimpleFilterProvider() .addFilter("filter properties by name", SimpleBeanPropertyFilter.serializeAllExcept( ignorableFieldNames)); ObjectWriter writer = mapper.writer(filters); System.out.println(writer.writeValueAsString(new Bar())); // output: // {"name":"James","foo":{"size":"big","height":"tall"}} } } 

(Nota: la API relevante puede haber cambiado ligeramente con una versión reciente de Jackson.)

Si bien el ejemplo sí utiliza una anotación aparentemente innecesaria, la anotación no se aplica a los campos que se excluirán. (Para ayudar a que se modifique la API para simplificar un poco la configuración necesaria, no dude en votar para implementar el problema JACKSON-274 .

Escribí una biblioteca para tratar un caso de uso similar. Necesitaba ignorar los campos por progtwigción según el usuario que solicitara los datos. Las opciones normales de Jackson eran demasiado duras, y odiaba la forma en que mi código se veía.

La biblioteca hace que esto sea mucho más fácil de entender. Te permite simplemente hacer esto:

 import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.monitorjbl.json.JsonView; import com.monitorjbl.json.JsonViewSerializer; import static com.monitorjbl.json.Match.match; //initialize jackson ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(JsonView.class, new JsonViewSerializer()); mapper.registerModule(module); //get a list of the objects List list = myObjectService.list(); String json; if(user.getRole().equals('ADMIN')){ json = mapper.writeValueAsString(list); } else { json = mapper.writeValueAsString(JsonView.with(list) .onClass(MyObject.class, match() .exclude("*") .include("name"))); } System.out.println(json); 

El código está disponible en GitHub , ¡espero que ayude!

Jackson se basa en anotaciones para la mayoría de las cosas como esta; pero no tiene que anotar directamente las clases de valores. También puede usar “anotaciones mixtas” (vea http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html ).

Y luego hay algunas opciones que puede usar más allá de @JsonIgnore básico (por propiedad) o @JsonIgnoreProperties (por clase), vea http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html

Si tiene filtros definidos en dos o más pojo, puede intentar esto:

 @JsonFilter("filterAClass") class AClass { public String id = "42"; public String name = "Fred"; public String color = "blue"; public int sal = 56; public BClass bclass = new BClass(); } //@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) @JsonFilter("filterBClass") class BClass { public String id = "99"; public String size = "90"; public String height = "tall"; public String nulcheck =null; } public class MultipleFilterConcept { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); // Exclude Null Fields mapper.setSerializationInclusion(Inclusion.NON_NULL); String[] ignorableFieldNames = { "id", "color" }; String[] ignorableFieldNames1 = { "height","size" }; FilterProvider filters = new SimpleFilterProvider() .addFilter("filterAClass",SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)) .addFilter("filterBClass", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames1)); ObjectWriter writer = mapper.writer(filters); System.out.println(writer.writeValueAsString(new AClass())); } } 

Escribí una biblioteca llamada Squiggly Filter , que selecciona los campos basados ​​en un subconjunto de la syntax de la API Graph de Facebook. Por ejemplo, para seleccionar el código postal del campo de dirección del objeto del usuario, usaría la cadena de consulta ?fields=address{zipCode} . Una de las ventajas de Squiggly Filter es que, siempre que tenga acceso al ObjectMapper que representa el json, no tendrá que modificar el código de ninguno de sus métodos de controlador.

Suponiendo que está utilizando la API de servlet, puede hacer lo siguiente:

1) Registre un filtro

  squigglyFilter com.github.bohnman.squiggly.web.SquigglyRequestFilter   squigglyFilter /**  

2) Inicializar el ObjectMapper

 Squiggly.init(objectMapper, new RequestSquigglyContextProvider()); 

3) Ahora puede filtrar su json

 curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2} 

Más información sobre Squiggly Filter está disponible en github .