Reputation: 7244
With Jackson, it's easy to disable all annotations for a given ObjectMapper
.
Is there a way to only disable one given annotation?
// disable all
ObjectMapper mapper = new ObjectMapper()
mapper.disable(MapperFeature.USE_ANNOTATIONS);
// disable one?
ObjectMapper mapper = new ObjectMapper()
mapper.disable(@JsonIgnore);
Using @JacksonAnnotationsInside
, I've defined a custom Jackson annotation and I only want it to be used in certain circumstances.
Upvotes: 7
Views: 10878
Reputation: 549
Here is a simpler way (August 2022) to do it in Kotlin (you can translate to Java if you really want to):
(I use this in a Ktor/KMongo project to prevent Transient
attributes from being persisted because KMongo requires @JsonIgnore
, which then also prevents my other mappers from serializing those properties!)
@Target(PROPERTY_GETTER)
annotation class Transient
private val TransientIntrospector: JacksonAnnotationIntrospector = object : JacksonAnnotationIntrospector() {
override fun hasIgnoreMarker(m: AnnotatedMember): Boolean =
m.allAnnotations.has(Transient::class.java) || super.hasIgnoreMarker(m)
}
private class IgnoreTransientModule : SimpleModule() {
override fun setupModule(context: SetupContext) {
super.setupModule(context)
context.appendAnnotationIntrospector(TransientIntrospector)
}
}
// Just register the module in your `ObjectMapper` instance:
val ignoreTransientMapper = with(ObjectMapper()) {
registerModule(IgnoreTransientModule())
}
// And here is how to use it:
data class Customer(
val id: String? = null,
val firstName: String,
val lastName: String,
) {
@get:Transient
val fullName: String
get() = "$firstName $lastName"
}
Upvotes: 0
Reputation: 829
This solution worked for me. Check this for more info
private static final JacksonAnnotationIntrospector IGNORE_ENUM_ALIAS_ANNOTATIONS = new JacksonAnnotationIntrospector() {
@Override
protected <A extends Annotation> A _findAnnotation(final Annotated annotated, final Class<A> annoClass) {
if (!annotated.hasAnnotation(JsonEnumAliasSerializer.class)) {
return super._findAnnotation(annotated, annoClass);
}
return null;
}
};
And my custom annotation:
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = JsonEnumSerializer.class)
public @interface JsonEnumAliasSerializer {
}
And ObjectMapper:
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(IGNORE_ENUM_ALIAS_ANNOTATIONS);
Upvotes: 1
Reputation: 1114
I think it's a better idea to override findPropertiesToIgnore
method like this:
JacksonAnnotationIntrospector ignoreJsonTypeInfoIntrospector = new JacksonAnnotationIntrospector() {
@Override
public String[] findPropertiesToIgnore(AnnotatedClass ac) {
ArrayList<String> ret = new ArrayList<String>();
for (Method m : ac.getRawType().getMethods()) {
if(ReflectionUtils.isGetter(m)){
if(m.getAnnotation(Transient.class) != null)
ret.add(ReflectionUtils.getPropertyName(m));
}
};
return ret.toArray(new String[]{});
}
};
objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(ignoreJsonTypeInfoIntrospector);
Upvotes: 0
Reputation: 3091
This the best I've come across. I think I saw it on the Jackson user group forums somewhere.
Essentially it makes a custom annotation introspector, which returns null if it sees that it has a specific annotation (in this case JsonTypeInfo)
JacksonAnnotationIntrospector ignoreJsonTypeInfoIntrospector = new JacksonAnnotationIntrospector() {
@Override
protected TypeResolverBuilder<?> _findTypeResolver(
MapperConfig<?> config, Annotated ann, JavaType baseType) {
if (!ann.hasAnnotation(JsonTypeInfo.class)) {
return super._findTypeResolver(config, ann, baseType);
}
return null;
}
};
mapper.setAnnotationIntrospector(ignoreJsonTypeInfoIntrospector);
Upvotes: 2