Created
August 27, 2018 15:25
-
-
Save bwaldvogel/5dae899974f6ab68cab556d524460382 to your computer and use it in GitHub Desktop.
Workaround for Jackson’s global inclusion behaviour change in 2.8.3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import com.fasterxml.jackson.annotation.JsonInclude; | |
import com.fasterxml.jackson.databind.BeanDescription; | |
import com.fasterxml.jackson.databind.SerializationConfig; | |
import com.fasterxml.jackson.databind.cfg.PackageVersion; | |
import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig; | |
import com.fasterxml.jackson.databind.ser.BeanSerializerFactory; | |
import com.fasterxml.jackson.databind.ser.PropertyBuilder; | |
import com.fasterxml.jackson.databind.ser.SerializerFactory; | |
/** | |
* <p>Workaround for https://github.com/FasterXML/jackson-databind/issues/1757</p> | |
* | |
* Usage example: | |
* <pre> | |
* ObjectMapper mapper = new ObjectMapper(); | |
* mapper.setSerializerFactory(new BeanSerializerFactoryWithGlobalIncludeDefaults()); | |
* mapper.setSerializationInclusion(Include.NON_DEFAULT); | |
* </pre> | |
*/ | |
public class BeanSerializerFactoryWithGlobalIncludeDefaults extends BeanSerializerFactory { | |
private static final long serialVersionUID = 1L; | |
private static final String REFLECTION_EXCEPTION_MESSAGE = "Failed to adjust " + PropertyBuilder.class + "." + | |
" This workaround is probably incompatible with Jackson " + PackageVersion.VERSION; | |
private final Field defaultInclusionField; | |
private final Field useRealPropertyDefaultsField; | |
BeanSerializerFactoryWithGlobalIncludeDefaults() { | |
this(null); | |
} | |
private BeanSerializerFactoryWithGlobalIncludeDefaults(SerializerFactoryConfig config) { | |
super(config); | |
try { | |
defaultInclusionField = PropertyBuilder.class.getDeclaredField("_defaultInclusion"); | |
defaultInclusionField.setAccessible(true); | |
useRealPropertyDefaultsField = PropertyBuilder.class.getDeclaredField("_useRealPropertyDefaults"); | |
useRealPropertyDefaultsField.setAccessible(true); | |
} catch (NoSuchFieldException e) { | |
throw new RuntimeException(REFLECTION_EXCEPTION_MESSAGE, e); | |
} | |
} | |
@Override | |
public SerializerFactory withConfig(SerializerFactoryConfig config) { | |
if (_factoryConfig == config) { | |
return this; | |
} | |
return new BeanSerializerFactoryWithGlobalIncludeDefaults(config); | |
} | |
@Override | |
protected PropertyBuilder constructPropertyBuilder(SerializationConfig config, BeanDescription beanDesc) { | |
PropertyBuilder propertyBuilder = super.constructPropertyBuilder(config, beanDesc); | |
try { | |
adjustUseRealPropertyDefaults(propertyBuilder); | |
} catch (ReflectiveOperationException e) { | |
throw new RuntimeException(REFLECTION_EXCEPTION_MESSAGE, e); | |
} | |
return propertyBuilder; | |
} | |
private void adjustUseRealPropertyDefaults(PropertyBuilder propertyBuilder) throws ReflectiveOperationException { | |
JsonInclude.Value defaultInclusion = (JsonInclude.Value) defaultInclusionField.get(propertyBuilder); | |
boolean useRealPropertyDefaults = defaultInclusion.getValueInclusion() == JsonInclude.Include.NON_DEFAULT; | |
useRealPropertyDefaultsField.setBoolean(propertyBuilder, useRealPropertyDefaults); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment