Merge branch '5.1.x'
This commit is contained in:
commit
0d8fbb4c65
|
@ -69,6 +69,7 @@ dependencies {
|
|||
}
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:${jackson2Version}")
|
||||
testCompile("org.apache.tomcat:tomcat-util:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -632,21 +632,24 @@ public class Jackson2ObjectMapperBuilder {
|
|||
public void configure(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "ObjectMapper must not be null");
|
||||
|
||||
Map<Object, Module> modulesToRegister = new LinkedHashMap<>();
|
||||
if (this.findModulesViaServiceLoader) {
|
||||
objectMapper.registerModules(ObjectMapper.findModules(this.moduleClassLoader));
|
||||
ObjectMapper.findModules(this.moduleClassLoader).forEach(module -> modulesToRegister.put(module.getTypeId(), module));
|
||||
}
|
||||
else if (this.findWellKnownModules) {
|
||||
registerWellKnownModulesIfAvailable(objectMapper);
|
||||
registerWellKnownModulesIfAvailable(modulesToRegister);
|
||||
}
|
||||
|
||||
if (this.modules != null) {
|
||||
objectMapper.registerModules(this.modules);
|
||||
this.modules.forEach(module -> modulesToRegister.put(module.getTypeId(), module));
|
||||
}
|
||||
if (this.moduleClasses != null) {
|
||||
for (Class<? extends Module> module : this.moduleClasses) {
|
||||
objectMapper.registerModule(BeanUtils.instantiateClass(module));
|
||||
for (Class<? extends Module> moduleClass : this.moduleClasses) {
|
||||
Module module = BeanUtils.instantiateClass(moduleClass);
|
||||
modulesToRegister.put(module.getTypeId(), module);
|
||||
}
|
||||
}
|
||||
objectMapper.registerModules(modulesToRegister.values());
|
||||
|
||||
if (this.dateFormat != null) {
|
||||
objectMapper.setDateFormat(this.dateFormat);
|
||||
|
@ -744,20 +747,22 @@ public class Jackson2ObjectMapperBuilder {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void registerWellKnownModulesIfAvailable(ObjectMapper objectMapper) {
|
||||
private void registerWellKnownModulesIfAvailable(Map<Object, Module> modulesToRegister) {
|
||||
try {
|
||||
Class<? extends Module> jdk8Module = (Class<? extends Module>)
|
||||
Class<? extends Module> jdk8ModuleClass = (Class<? extends Module>)
|
||||
ClassUtils.forName("com.fasterxml.jackson.datatype.jdk8.Jdk8Module", this.moduleClassLoader);
|
||||
objectMapper.registerModule(BeanUtils.instantiateClass(jdk8Module));
|
||||
Module jdk8Module = BeanUtils.instantiateClass(jdk8ModuleClass);
|
||||
modulesToRegister.put(jdk8Module.getTypeId(), jdk8Module);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// jackson-datatype-jdk8 not available
|
||||
}
|
||||
|
||||
try {
|
||||
Class<? extends Module> javaTimeModule = (Class<? extends Module>)
|
||||
Class<? extends Module> javaTimeModuleClass = (Class<? extends Module>)
|
||||
ClassUtils.forName("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", this.moduleClassLoader);
|
||||
objectMapper.registerModule(BeanUtils.instantiateClass(javaTimeModule));
|
||||
Module javaTimeModule = BeanUtils.instantiateClass(javaTimeModuleClass);
|
||||
modulesToRegister.put(javaTimeModule.getTypeId(), javaTimeModule);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// jackson-datatype-jsr310 not available
|
||||
|
@ -766,9 +771,10 @@ public class Jackson2ObjectMapperBuilder {
|
|||
// Joda-Time present?
|
||||
if (ClassUtils.isPresent("org.joda.time.LocalDate", this.moduleClassLoader)) {
|
||||
try {
|
||||
Class<? extends Module> jodaModule = (Class<? extends Module>)
|
||||
Class<? extends Module> jodaModuleClass = (Class<? extends Module>)
|
||||
ClassUtils.forName("com.fasterxml.jackson.datatype.joda.JodaModule", this.moduleClassLoader);
|
||||
objectMapper.registerModule(BeanUtils.instantiateClass(jodaModule));
|
||||
Module jodaModule = BeanUtils.instantiateClass(jodaModuleClass);
|
||||
modulesToRegister.put(jodaModule.getTypeId(), jodaModule);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// jackson-datatype-joda not available
|
||||
|
@ -778,9 +784,10 @@ public class Jackson2ObjectMapperBuilder {
|
|||
// Kotlin present?
|
||||
if (KotlinDetector.isKotlinPresent()) {
|
||||
try {
|
||||
Class<? extends Module> kotlinModule = (Class<? extends Module>)
|
||||
Class<? extends Module> kotlinModuleClass = (Class<? extends Module>)
|
||||
ClassUtils.forName("com.fasterxml.jackson.module.kotlin.KotlinModule", this.moduleClassLoader);
|
||||
objectMapper.registerModule(BeanUtils.instantiateClass(kotlinModule));
|
||||
Module kotlinModule = BeanUtils.instantiateClass(kotlinModuleClass);
|
||||
modulesToRegister.put(kotlinModule.getTypeId(), kotlinModule);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
if (!kotlinWarningLogged) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -21,6 +21,8 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -40,6 +42,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
|
|||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
|
@ -50,6 +53,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
|
||||
import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig;
|
||||
import com.fasterxml.jackson.databind.deser.BasicDeserializerFactory;
|
||||
|
@ -68,12 +72,14 @@ import com.fasterxml.jackson.databind.type.SimpleType;
|
|||
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
|
||||
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import kotlin.ranges.IntRange;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
@ -96,6 +102,8 @@ public class Jackson2ObjectMapperBuilderTests {
|
|||
|
||||
private static final String DATE_FORMAT = "yyyy-MM-dd";
|
||||
|
||||
private static final String DATA = "{\"offsetDateTime\": \"2020-01-01T00:00:00\"}";
|
||||
|
||||
|
||||
@Test(expected = FatalBeanException.class)
|
||||
public void unknownFeature() {
|
||||
|
@ -308,6 +316,18 @@ public class Jackson2ObjectMapperBuilderTests {
|
|||
assertThat(new String(objectMapper.writeValueAsBytes(new Integer(4)), "UTF-8"), containsString("customid"));
|
||||
}
|
||||
|
||||
@Test // gh-22576
|
||||
public void overrideWellKnownModuleWithModule() throws IOException {
|
||||
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
javaTimeModule.addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer());
|
||||
builder.modulesToInstall(javaTimeModule);
|
||||
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
ObjectMapper objectMapper = builder.build();
|
||||
DemoPojo demoPojo = objectMapper.readValue(DATA, DemoPojo.class);
|
||||
assertNotNull(demoPojo.getOffsetDateTime());
|
||||
}
|
||||
|
||||
|
||||
private static SerializerFactoryConfig getSerializerFactoryConfig(ObjectMapper objectMapper) {
|
||||
return ((BasicSerializerFactory) objectMapper.getSerializerFactory()).getFactoryConfig();
|
||||
|
@ -613,4 +633,38 @@ public class Jackson2ObjectMapperBuilderTests {
|
|||
|
||||
}
|
||||
|
||||
static class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
|
||||
|
||||
private static final String CURRENT_ZONE_OFFSET = OffsetDateTime.now().getOffset().toString();
|
||||
|
||||
@Override
|
||||
public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||
final String value = jsonParser.getValueAsString();
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return OffsetDateTime.parse(value);
|
||||
|
||||
} catch (DateTimeParseException exception) {
|
||||
return OffsetDateTime.parse(value + CURRENT_ZONE_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonDeserialize
|
||||
static class DemoPojo {
|
||||
|
||||
private OffsetDateTime offsetDateTime;
|
||||
|
||||
public OffsetDateTime getOffsetDateTime() {
|
||||
return offsetDateTime;
|
||||
}
|
||||
|
||||
public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
|
||||
this.offsetDateTime = offsetDateTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue