Upgrade to Jackson 2.7.2

Closes gh-5081
This commit is contained in:
Andy Wilkinson 2016-03-01 16:37:51 +00:00
parent 355860fd09
commit ef5087c5ee
8 changed files with 83 additions and 29 deletions

View File

@ -310,7 +310,7 @@ public class ConfigurationPropertiesReportEndpoint
private boolean isReadable(BeanDescription beanDesc, BeanPropertyWriter writer) {
String parentType = beanDesc.getType().getRawClass().getName();
String type = writer.getPropertyType().getName();
String type = writer.getType().getTypeName();
AnnotatedMethod setter = findSetter(beanDesc, writer);
// If there's a setter, we assume it's OK to report on the value,
// similarly, if there's no setter but the package names match, we assume
@ -324,7 +324,7 @@ public class ConfigurationPropertiesReportEndpoint
private AnnotatedMethod findSetter(BeanDescription beanDesc,
BeanPropertyWriter writer) {
String name = "set" + StringUtils.capitalize(writer.getName());
Class<?> type = writer.getPropertyType();
Class<?> type = writer.getType().getRawClass();
AnnotatedMethod setter = beanDesc.findMethod(name, new Class<?>[] { type });
// The enabled property of endpoints returns a boolean primitive but is set
// using a Boolean class

View File

@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.jmx;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.actuate.endpoint.Endpoint;
@ -40,6 +41,10 @@ public class EndpointMBean {
private final ObjectMapper mapper;
private final JavaType listObject;
private final JavaType mapStringObject;
/**
* Create a new {@link EndpointMBean} instance.
* @param beanName the bean name
@ -53,6 +58,10 @@ public class EndpointMBean {
Assert.notNull(objectMapper, "ObjectMapper must not be null");
this.endpoint = endpoint;
this.mapper = objectMapper;
this.listObject = objectMapper.getTypeFactory()
.constructParametricType(List.class, Object.class);
this.mapStringObject = objectMapper.getTypeFactory()
.constructParametricType(Map.class, String.class, Object.class);
}
@ManagedAttribute(description = "Returns the class of the underlying endpoint")
@ -77,9 +86,9 @@ public class EndpointMBean {
return result;
}
if (result.getClass().isArray() || result instanceof List) {
return this.mapper.convertValue(result, List.class);
return this.mapper.convertValue(result, this.listObject);
}
return this.mapper.convertValue(result, Map.class);
return this.mapper.convertValue(result, this.mapStringObject);
}
}

View File

@ -17,10 +17,12 @@
package org.springframework.boot.actuate.endpoint.jmx;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -199,12 +201,12 @@ public class EndpointMBeanExporterTests {
}
@Test
public void jsonConversionWithDefaultObjectMapper() throws Exception {
public void jsonMapConversionWithDefaultObjectMapper() throws Exception {
this.context = new GenericApplicationContext();
this.context.registerBeanDefinition("endpointMbeanExporter",
new RootBeanDefinition(EndpointMBeanExporter.class));
this.context.registerBeanDefinition("endpoint1",
new RootBeanDefinition(JsonConversionEndpoint.class));
new RootBeanDefinition(JsonMapConversionEndpoint.class));
this.context.refresh();
MBeanExporter mbeanExporter = this.context.getBean(EndpointMBeanExporter.class);
Object response = mbeanExporter.getServer().invoke(
@ -215,7 +217,7 @@ public class EndpointMBeanExporterTests {
}
@Test
public void jsonConversionWithCustomObjectMapper() throws Exception {
public void jsonMapConversionWithCustomObjectMapper() throws Exception {
this.context = new GenericApplicationContext();
ConstructorArgumentValues constructorArgs = new ConstructorArgumentValues();
ObjectMapper objectMapper = new ObjectMapper();
@ -225,7 +227,7 @@ public class EndpointMBeanExporterTests {
new RootBeanDefinition(EndpointMBeanExporter.class, constructorArgs,
null));
this.context.registerBeanDefinition("endpoint1",
new RootBeanDefinition(JsonConversionEndpoint.class));
new RootBeanDefinition(JsonMapConversionEndpoint.class));
this.context.refresh();
MBeanExporter mbeanExporter = this.context.getBean(EndpointMBeanExporter.class);
Object response = mbeanExporter.getServer().invoke(
@ -235,6 +237,22 @@ public class EndpointMBeanExporterTests {
assertThat(((Map<?, ?>) response).get("date")).isInstanceOf(String.class);
}
@Test
public void jsonListConversion() throws Exception {
this.context = new GenericApplicationContext();
this.context.registerBeanDefinition("endpointMbeanExporter",
new RootBeanDefinition(EndpointMBeanExporter.class));
this.context.registerBeanDefinition("endpoint1",
new RootBeanDefinition(JsonListConversionEndpoint.class));
this.context.refresh();
MBeanExporter mbeanExporter = this.context.getBean(EndpointMBeanExporter.class);
Object response = mbeanExporter.getServer().invoke(
getObjectName("endpoint1", this.context), "getData", new Object[0],
new String[0]);
assertThat(response).isInstanceOf(List.class);
assertThat(((List<?>) response).get(0)).isInstanceOf(Long.class);
}
private ObjectName getObjectName(String beanKey, GenericApplicationContext context)
throws MalformedObjectNameException {
return getObjectName("org.springframework.boot", beanKey, false, context);
@ -265,11 +283,11 @@ public class EndpointMBeanExporterTests {
}
public static class JsonConversionEndpoint
public static class JsonMapConversionEndpoint
extends AbstractEndpoint<Map<String, Object>> {
public JsonConversionEndpoint() {
super("json-conversion");
public JsonMapConversionEndpoint() {
super("json-map-conversion");
}
@Override
@ -281,4 +299,18 @@ public class EndpointMBeanExporterTests {
}
public static class JsonListConversionEndpoint
extends AbstractEndpoint<List<Object>> {
public JsonListConversionEndpoint() {
super("json-list-conversion");
}
@Override
public List<Object> invoke() {
return Arrays.<Object>asList(new Date());
}
}
}

View File

@ -166,9 +166,9 @@ public class JacksonAutoConfiguration {
public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.applicationContext(this.applicationContext);
if (this.jacksonProperties.getSerializationInclusion() != null) {
if (this.jacksonProperties.getDefaultPropertyInclusion() != null) {
builder.serializationInclusion(
this.jacksonProperties.getSerializationInclusion());
this.jacksonProperties.getDefaultPropertyInclusion());
}
if (this.jacksonProperties.getTimeZone() != null) {
builder.timeZone(this.jacksonProperties.getTimeZone());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
/**
* Configuration properties to configure Jackson.
@ -89,7 +90,7 @@ public class JacksonProperties {
* Controls the inclusion of properties during serialization. Configured with one of
* the values in Jackson's JsonInclude.Include enumeration.
*/
private JsonInclude.Include serializationInclusion;
private JsonInclude.Include defaultPropertyInclusion;
/**
* Time zone used when formatting dates. Configured using any recognized time zone
@ -146,12 +147,24 @@ public class JacksonProperties {
return this.generator;
}
@Deprecated
@DeprecatedConfigurationProperty(reason = "ObjectMapper.setSerializationInclusion was deprecated in Jackson 2.7", replacement = "spring.jackson.default-property-inclusion")
public JsonInclude.Include getSerializationInclusion() {
return this.serializationInclusion;
return getDefaultPropertyInclusion();
}
@Deprecated
public void setSerializationInclusion(JsonInclude.Include serializationInclusion) {
this.serializationInclusion = serializationInclusion;
setDefaultPropertyInclusion(serializationInclusion);
}
public JsonInclude.Include getDefaultPropertyInclusion() {
return this.defaultPropertyInclusion;
}
public void setDefaultPropertyInclusion(
JsonInclude.Include defaultPropertyInclusion) {
this.defaultPropertyInclusion = defaultPropertyInclusion;
}
public TimeZone getTimeZone() {

View File

@ -35,7 +35,7 @@ import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
@ -167,22 +167,22 @@ public class JacksonAutoConfigurationTests {
public void customPropertyNamingStrategyField() throws Exception {
this.context.register(JacksonAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context,
"spring.jackson.property-naming-strategy:CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES");
"spring.jackson.property-naming-strategy:SNAKE_CASE");
this.context.refresh();
ObjectMapper mapper = this.context.getBean(ObjectMapper.class);
assertThat(mapper.getPropertyNamingStrategy())
.isInstanceOf(LowerCaseWithUnderscoresStrategy.class);
.isInstanceOf(SnakeCaseStrategy.class);
}
@Test
public void customPropertyNamingStrategyClass() throws Exception {
this.context.register(JacksonAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context,
"spring.jackson.property-naming-strategy:com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy");
"spring.jackson.property-naming-strategy:com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy");
this.context.refresh();
ObjectMapper mapper = this.context.getBean(ObjectMapper.class);
assertThat(mapper.getPropertyNamingStrategy())
.isInstanceOf(LowerCaseWithUnderscoresStrategy.class);
.isInstanceOf(SnakeCaseStrategy.class);
}
@Test
@ -355,8 +355,8 @@ public class JacksonAutoConfigurationTests {
this.context.refresh();
ObjectMapper objectMapper = this.context
.getBean(Jackson2ObjectMapperBuilder.class).build();
assertThat(objectMapper.getSerializationConfig().getSerializationInclusion())
.isEqualTo(JsonInclude.Include.ALWAYS);
assertThat(objectMapper.getSerializationConfig().getDefaultPropertyInclusion()
.getValueInclusion()).isEqualTo(JsonInclude.Include.USE_DEFAULTS);
}
@Test
@ -367,8 +367,8 @@ public class JacksonAutoConfigurationTests {
this.context.refresh();
ObjectMapper objectMapper = this.context
.getBean(Jackson2ObjectMapperBuilder.class).build();
assertThat(objectMapper.getSerializationConfig().getSerializationInclusion())
.isEqualTo(JsonInclude.Include.NON_NULL);
assertThat(objectMapper.getSerializationConfig().getDefaultPropertyInclusion()
.getValueInclusion()).isEqualTo(JsonInclude.Include.NON_NULL);
}
@Test

View File

@ -112,9 +112,9 @@ public class DataSourceJsonSerializationTests {
for (BeanPropertyWriter writer : beanProperties) {
AnnotatedMethod setter = beanDesc.findMethod(
"set" + StringUtils.capitalize(writer.getName()),
new Class<?>[] { writer.getPropertyType() });
new Class<?>[] { writer.getType().getRawClass() });
if (setter != null && this.conversionService.canConvert(String.class,
writer.getPropertyType())) {
writer.getType().getRawClass())) {
result.add(writer);
}
}

View File

@ -86,7 +86,7 @@
<httpclient.version>4.5.1</httpclient.version>
<httpcore.version>4.4.4</httpcore.version>
<infinispan.version>8.1.2.Final</infinispan.version>
<jackson.version>2.6.5</jackson.version>
<jackson.version>2.7.2</jackson.version>
<janino.version>2.7.8</janino.version>
<javassist.version>3.18.1-GA</javassist.version> <!-- Same as Hibernate -->
<javax-cache.version>1.0.0</javax-cache.version>