Skip to content

Instantly share code, notes, and snippets.

@sdorra
Created June 15, 2016 20:27
Show Gist options
  • Save sdorra/a59a7cb95c49afc84ed26211350c1321 to your computer and use it in GitHub Desktop.
Save sdorra/a59a7cb95c49afc84ed26211350c1321 to your computer and use it in GitHub Desktop.
Jackson sample with deep field filter
public class App {
public static void main(String[] args) {
Type type = new Type("hg", "Mercurial");
Repository repository = new Repository("42", "scm", type, "SCM-Manager", "SCM-Manager Repository Hosting");
System.out.println(JSON.asString(repository));
System.out.println(JSON.asString(repository, "id", "desc"));
System.out.println(JSON.asString(repository, "id", "name", "type", "type.name", "displayName"));
}
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Sample filtering fields durring json marshalling.
*
* @author Sebastian Sdorra
*/
public class JSON {
private static final String DEFAULT_FILTER = "__default";
private static final String DOT = ".";
private static final ObjectMapper MAPPER = new ObjectMapper().setAnnotationIntrospector(
new AnnotationIntrospectorPair(
new FilteringAnnotationInpector(), new JaxbAnnotationIntrospector(TypeFactory.defaultInstance())
)
);
public static String asString(Object object, String... fields) {
PropertyFilter filter = filter(fields);
SimpleFilterProvider provider = new SimpleFilterProvider();
provider.addFilter(DEFAULT_FILTER, filter);
try {
return MAPPER.writer(provider).writeValueAsString(object);
} catch (JsonProcessingException ex) {
throw new RuntimeException("failed to marshall", ex);
}
}
private static PropertyFilter filter(String[] fields) {
PropertyFilter filter;
if (fields.length > 0) {
Set<String> properties = new HashSet<>(fields.length);
Collections.addAll(properties, fields);
filter = new DeepFieldFilter(properties);
} else {
filter = SimpleBeanPropertyFilter.serializeAll();
}
return filter;
}
private static class FilteringAnnotationInpector extends JacksonAnnotationIntrospector {
private static final long serialVersionUID = -8722016441050379430L;
@Override
public String findFilterId(Annotated a) {
return DEFAULT_FILTER;
}
}
private static class DeepFieldFilter extends SimpleBeanPropertyFilter {
private final Set<String> includes;
private DeepFieldFilter(Set<String> includes) {
this.includes = includes;
}
private String createPath(PropertyWriter writer, JsonGenerator jgen) {
StringBuilder path = new StringBuilder();
path.append(writer.getName());
JsonStreamContext sc = jgen.getOutputContext();
if (sc != null) {
sc = sc.getParent();
}
while (sc != null) {
if (sc.getCurrentName() != null) {
if (path.length() > 0) {
path.insert(0, DOT);
}
path.insert(0, sc.getCurrentName());
}
sc = sc.getParent();
}
return path.toString();
}
@Override
public void serializeAsField(Object pojo, JsonGenerator gen, SerializerProvider provider, PropertyWriter writer)
throws Exception {
String path = createPath(writer, gen);
if (includes.contains(path)) {
writer.serializeAsField(pojo, gen, provider);
} else {
writer.serializeAsOmittedField(pojo, gen, provider);
}
}
}
}
@sdorra
Copy link
Author

sdorra commented Jul 21, 2021

@sdorra Under which license are you publishing these code snippets?
Are the snippets free to use (something like MIT license) or how should I attribute you, when I use your snippets?

Most of my OSS Code is published under the MIT License. Feel free to use this code for what ever you like. I don't know if i can set a license for a gist.

@ComanderKai77
Copy link

@sdorra Under which license are you publishing these code snippets?
Are the snippets free to use (something like MIT license) or how should I attribute you, when I use your snippets?

Most of my OSS Code is published under the MIT License. Feel free to use this code for what ever you like. I don't know if i can set a license for a gist.

Thank you.
I have seen a few gists where there is an additional field named LICENSE.
Or you can also create an extra gist like https://gist.github.com/martinbuberl/c0de29e623a1e34d1cda7e817d18bafe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment