Basically, when you are using Gson and you need to exclude specific fields from Serialization WITHOUT annotations on the target object, you will use ExclusionStrategy
. But I didn't find an similar way to do that in Jackson. So this repo provides an easy way to determine filters dynamically, and it also well integration with Spring MVC/Spring Boot.
For Spring Boot: jackson-dynamic-filter-spring-boot-starter
- Java 8
- Supported Spring IO Platform:
To add a dependency using Maven, use the following:
<dependency>
<groupId>com.github.shihyuho</groupId>
<artifactId>jackson-dynamic-filter</artifactId>
<version>1.0.1</version>
</dependency>
To add a dependency using Gradle:
compile 'com.github.shihyuho:jackson-dynamic-filter:1.0.1'
To download directly: Releases
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Object.class, DynamicFilterMixIn.class);
mapper.setFilterProvider(new DynamicFilterProvider());
String jsonWithAllFields = mapper.writeValueAsString(someObject);
PropertyFilter someFilter = SimpleBeanPropertyFilter.serializeAllExcept("someField");
String jsonWithoutSomeField = mapper
.writer(new DynamicFilterProvider(someFilter)) // determine custom filter
.writeValueAsString(someObject);
All you need to do is to wire DynamicFilterResponseBodyAdvice
into your application. DynamicFilterResponseBodyAdvice
implements Spring'sAbstractMappingJacksonResponseBodyAdvice
and can be plugged in as follows:
@EnableWebMvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Object.class, DynamicFilterMixIn.class);
mapper.setFilterProvider(new DynamicFilterProvider());
converters.add(new MappingJackson2HttpMessageConverter(mapper));
}
@Bean
public DynamicFilterResponseBodyAdvice dynamicFilterResponseBodyAdvice() {
return new DynamicFilterResponseBodyAdvice();
}
}
If you're using Spring Boot, take a look on jackson-dynamic-filter-spring-boot-starter
@SerializeAllExcept
- Same asSimpleBeanPropertyFilter.serializeAllExcept(...)
@FilterOutAllExcept
- Same asSimpleBeanPropertyFilter.filterOutAllExcept(...)
@RestController
public class SomeController {
@SerializeAllExcept({"someField", "anotherField"})
@RequestMapping(value = "/without/some-fields", method = RequestMethod.GET)
public SomeObject withoutSomeFields() {
return someObject;
}
@FilterOutAllExcept({"someField", "anotherField"})
@RequestMapping(value = "/only/some-fields", method = RequestMethod.GET)
public SomeObject onlySomeFields() {
return someObject;
}
}
You can annotate a custom annotation:
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface WithoutAuditingFields {
}
public class WithoutAuditingFieldsResolver extends DynamicFilterProvider<WithoutAuditingFields> {
@Override
public PropertyFilter apply(WithoutAuditingFields annotation) {
return SimpleBeanPropertyFilter.serializeAllExcept("id", "createdBy", "createdTime",
"modifiedBy", "modifiedTime");
}
}
register into DynamicFilterResponseBodyAdvice
@Bean
public DynamicFilterResponseBodyAdvice dynamicFilterResponseBodyAdvice() {
DynamicFilterResponseBodyAdvice advice = new DynamicFilterResponseBodyAdvice();
advice.addResolvers(new WithoutAuditingFieldsResolver());
return advice;
}
and then use it for you controller as follows:
@RestController
public class SomeController {
@WithoutAuditingFields
@RequestMapping(value = "/some-path", method = RequestMethod.GET)
public SomeObject getSomeObject() {
return someObject;
}
}