Configure Jackson ObjectMapper to find and register additional modules declared on the application's classpath.
Resolves gh-67.
This commit is contained in:
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.geode.data.json.converter.ObjectToJsonConverter;
|
||||
import org.springframework.geode.pdx.PdxInstanceWrapper;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -41,7 +42,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class JacksonObjectToJsonConverter implements ObjectToJsonConverter {
|
||||
|
||||
protected static final String AT_TYPE_METADATA_PROPERTY_NAME = "@type";
|
||||
protected static final String AT_TYPE_METADATA_PROPERTY_NAME = PdxInstanceWrapper.AT_TYPE_FIELD_NAME;
|
||||
|
||||
/**
|
||||
* Converts the given {@link Object} into {@link String JSON}.
|
||||
@@ -57,7 +58,7 @@ public class JacksonObjectToJsonConverter implements ObjectToJsonConverter {
|
||||
Assert.notNull(source, "Source object to convert must not be null");
|
||||
|
||||
try {
|
||||
return newObjectMapper(source).writeValueAsString(source);
|
||||
return convertObjectToJson(source);
|
||||
}
|
||||
catch (JsonProcessingException cause) {
|
||||
throw new ConversionFailedException(TypeDescriptor.forObject(source), TypeDescriptor.valueOf(String.class),
|
||||
@@ -65,6 +66,24 @@ public class JacksonObjectToJsonConverter implements ObjectToJsonConverter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given {@link Object} into {@link String JSON}.
|
||||
*
|
||||
* @param source {@link Object} to convert to {@link String JSON}; must not be {@literal null}.
|
||||
* @return {@link String JSON} generated from the given {@link Object}.
|
||||
* @throws IllegalArgumentException if {@link Object source} is {@literal null}.
|
||||
* @throws JsonProcessingException if the generation of {@link String JSON} from the given {@link Object}
|
||||
* results in an error.
|
||||
* @see com.fasterxml.jackson.databind.ObjectMapper#writeValueAsString(Object)
|
||||
* @see #newObjectMapper(Object)
|
||||
*/
|
||||
protected @NonNull String convertObjectToJson(@NonNull Object source) throws JsonProcessingException {
|
||||
|
||||
Assert.notNull(source, "Source object to convert must not be null");
|
||||
|
||||
return newObjectMapper(source).writeValueAsString(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the Jackson {@link ObjectMapper} class.
|
||||
*
|
||||
@@ -75,10 +94,21 @@ public class JacksonObjectToJsonConverter implements ObjectToJsonConverter {
|
||||
|
||||
Assert.notNull(target, "Target object must not be null");
|
||||
|
||||
return new ObjectMapper()
|
||||
return newObjectMapper()
|
||||
.addMixIn(target.getClass(), ObjectTypeMetadataMixin.class)
|
||||
.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true)
|
||||
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
|
||||
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
|
||||
.findAndRegisterModules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of Jackson's {@link ObjectMapper}.
|
||||
*
|
||||
* @return a new instance of Jackson's {@link ObjectMapper}; never {@literal null}.
|
||||
* @see com.fasterxml.jackson.databind.ObjectMapper
|
||||
*/
|
||||
@NonNull ObjectMapper newObjectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
|
||||
@JsonTypeInfo(
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.geode.data.json.converter.support;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
@@ -25,6 +26,7 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
@@ -44,6 +46,7 @@ import example.app.crm.model.Customer;
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see com.fasterxml.jackson.databind.ObjectMapper
|
||||
* @see org.springframework.geode.data.json.converter.support.JacksonObjectToJsonConverter
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@@ -139,12 +142,29 @@ public class JacksonObjectToJsonConverterUnitTests {
|
||||
|
||||
Object target = Customer.newCustomer(1L, "Jon Doe");
|
||||
|
||||
ObjectMapper objectMapper = new JacksonObjectToJsonConverter().newObjectMapper(target);
|
||||
ObjectMapper mockObjectMapper = mock(ObjectMapper.class);
|
||||
|
||||
JacksonObjectToJsonConverter converter = spy(new JacksonObjectToJsonConverter());
|
||||
|
||||
doReturn(mockObjectMapper).when(converter).newObjectMapper();
|
||||
doReturn(mockObjectMapper).when(mockObjectMapper).addMixIn(any(), any());
|
||||
doReturn(mockObjectMapper).when(mockObjectMapper).configure(any(JsonGenerator.Feature.class), anyBoolean());
|
||||
doReturn(mockObjectMapper).when(mockObjectMapper).configure(any(MapperFeature.class), anyBoolean());
|
||||
doReturn(mockObjectMapper).when(mockObjectMapper).findAndRegisterModules();
|
||||
|
||||
ObjectMapper objectMapper = converter.newObjectMapper(target);
|
||||
|
||||
assertThat(objectMapper).isNotNull();
|
||||
assertThat(objectMapper.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)).isTrue();
|
||||
assertThat(objectMapper.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN)).isTrue();
|
||||
assertThat(objectMapper.getSerializationConfig().findMixInClassFor(target.getClass()))
|
||||
.isEqualTo(JacksonObjectToJsonConverter.ObjectTypeMetadataMixin.class);
|
||||
|
||||
verify(converter, times(1)).newObjectMapper();
|
||||
|
||||
verify(mockObjectMapper, times(1))
|
||||
.addMixIn(eq(target.getClass()), eq(JacksonObjectToJsonConverter.ObjectTypeMetadataMixin.class));
|
||||
verify(mockObjectMapper, times(1))
|
||||
.configure(eq(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN), eq(true));
|
||||
verify(mockObjectMapper, times(1))
|
||||
.configure(eq(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY), eq(true));
|
||||
verify(mockObjectMapper, times(1)).findAndRegisterModules();
|
||||
verifyNoMoreInteractions(mockObjectMapper);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user