Simplify ObjectMapper configuration.

Remove activation of default typing configuration.

Change target Class type for ObjectTypeMetadataMixin (Mixin) to the (converted) source object's Class type.

Remove unnecessary SimpleModule registration including the addition of the custom BigDecimalSerializer, BigIntegerSerializer and TypelessCollectionSerializer objects.

Resolves gh-67.
This commit is contained in:
John Blum
2020-05-08 01:29:26 -07:00
parent 8418082a00
commit 4d7becad79
2 changed files with 76 additions and 41 deletions

View File

@@ -18,56 +18,46 @@ package org.springframework.geode.data.json.converter.support;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.geode.data.json.converter.ObjectToJsonConverter;
import org.springframework.geode.jackson.databind.serializer.BigDecimalSerializer;
import org.springframework.geode.jackson.databind.serializer.BigIntegerSerializer;
import org.springframework.geode.jackson.databind.serializer.TypelessCollectionSerializer;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* A {@link ObjectToJsonConverter} implementation using Jackson's {@link ObjectMapper} to convert
* from an {@link Object} to a {@literal JSON} {@link String}.
*
* @author John Blum
* @see com.fasterxml.jackson.annotation.JsonTypeInfo
* @see com.fasterxml.jackson.core.JsonGenerator
* @see com.fasterxml.jackson.databind.ObjectMapper
* @see com.fasterxml.jackson.databind.MapperFeature
* @see org.springframework.geode.data.json.converter.ObjectToJsonConverter
* @since 1.3.0
*/
public class JacksonObjectToJsonConverter implements ObjectToJsonConverter {
protected static final ObjectMapper.DefaultTyping DEFAULT_TYPING = ObjectMapper.DefaultTyping.NON_FINAL;
protected static final String AT_TYPE_METADATA_PROPERTY_NAME = "@type";
private static final String SPRING_BOOT_DATA_GEODE_JACKSON_MODULE_NAME = "spring.boot.data.geode.module";
// Since SBDG Version
// Only change version when the Module definition changes since SimpleModule implements java.io.Serializable;
// Although, as of Jackson 2.5.0, SimpleModule defines a fixed serialVersionUID, so...
private static final Version VERSION = new Version(1, 3, 0, null,
"org.springframework.geode", "spring-geode-starter");
/**
* Converts the given {@link Object} into {@link String JSON}.
*
* @param source {@link Object} to convert into {@link String JSON}.
* @return {@link String JSON} generated from the given {@link Object} using Jackson's {@link ObjectMapper}.
* @see com.fasterxml.jackson.databind.ObjectMapper
* @see #newObjectMapper()
* @see #newObjectMapper(Object)
*/
@Nullable @Override
public String convert(Object source) {
@Override
public @NonNull String convert(@NonNull Object source) {
Assert.notNull(source, "Source object to convert must not be null");
try {
return newObjectMapper().writeValueAsString(source);
return newObjectMapper(source).writeValueAsString(source);
}
catch (JsonProcessingException cause) {
throw new ConversionFailedException(TypeDescriptor.forObject(source), TypeDescriptor.valueOf(String.class),
@@ -81,25 +71,16 @@ public class JacksonObjectToJsonConverter implements ObjectToJsonConverter {
* @return a new instance of the Jackson {@link ObjectMapper} class.
* @see com.fasterxml.jackson.databind.ObjectMapper
*/
protected @NonNull ObjectMapper newObjectMapper() {
protected @NonNull ObjectMapper newObjectMapper(@NonNull Object target) {
ObjectMapper objectMapper = new ObjectMapper()
.activateDefaultTypingAsProperty(null, DEFAULT_TYPING, AT_TYPE_METADATA_PROPERTY_NAME)
.addMixIn(NonAccessibleType.class, ObjectTypeMetadataMixin.class)
Assert.notNull(target, "Target object must not be null");
return new ObjectMapper()
.addMixIn(target.getClass(), ObjectTypeMetadataMixin.class)
.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true)
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
objectMapper.registerModule(new SimpleModule(SPRING_BOOT_DATA_GEODE_JACKSON_MODULE_NAME, VERSION)
.addSerializer(BigDecimalSerializer.INSTANCE)
.addSerializer(BigIntegerSerializer.INSTANCE)
.addSerializer(new TypelessCollectionSerializer(objectMapper)));
return objectMapper;
}
@SuppressWarnings("unused")
private interface NonAccessibleType { }
@JsonTypeInfo(
use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.PROPERTY,