Add defaultUseWrapper support to Jackson builder

Issue: SPR-13975
This commit is contained in:
Sebastien Deleuze 2016-03-01 23:47:40 +01:00
parent ffbf264976
commit 7b861c9a8a
3 changed files with 68 additions and 2 deletions

View File

@ -47,6 +47,8 @@ import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlFactory;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.springframework.beans.BeanUtils;
@ -127,6 +129,8 @@ public class Jackson2ObjectMapperBuilder {
private ApplicationContext applicationContext;
private Boolean defaultUseWrapper;
/**
* If set to {@code true}, an {@link XmlMapper} will be created using its
@ -392,6 +396,16 @@ public class Jackson2ObjectMapperBuilder {
return this;
}
/**
* Define if a wrapper will be used for indexed (List, array) properties or not by
* default (only applies to {@link XmlMapper}).
* @since 4.3
*/
public Jackson2ObjectMapperBuilder defaultUseWrapper(boolean defaultUseWrapper) {
this.defaultUseWrapper = defaultUseWrapper;
return this;
}
/**
* Specify features to enable.
* @see com.fasterxml.jackson.core.JsonParser.Feature
@ -547,7 +561,8 @@ public class Jackson2ObjectMapperBuilder {
public <T extends ObjectMapper> T build() {
ObjectMapper mapper;
if (this.createXmlMapper) {
mapper = new XmlObjectMapperInitializer().create();
mapper = (this.defaultUseWrapper == null ? new XmlObjectMapperInitializer().create()
: new XmlObjectMapperInitializer().create(this.defaultUseWrapper));
}
else {
mapper = new ObjectMapper();
@ -757,11 +772,21 @@ public class Jackson2ObjectMapperBuilder {
private static class XmlObjectMapperInitializer {
public ObjectMapper create() {
return new XmlMapper(xmlInputFactory());
}
public ObjectMapper create(boolean defaultUseWrapper) {
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(defaultUseWrapper);
return new XmlMapper(new XmlFactory(xmlInputFactory()), module);
}
private static final XMLInputFactory xmlInputFactory() {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
inputFactory.setXMLResolver(NO_OP_XML_RESOLVER);
return new XmlMapper(inputFactory);
return inputFactory;
}
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {

View File

@ -324,6 +324,15 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper
this.builder.indentOutput(indentOutput);
}
/**
* Define if a wrapper will be used for indexed (List, array) properties or not by
* default (only applies to {@link XmlMapper}).
* @since 4.3
*/
public void setDefaultUseWrapper(boolean defaultUseWrapper) {
this.builder.defaultUseWrapper(defaultUseWrapper);
}
/**
* Specify features to enable.
* @see com.fasterxml.jackson.core.JsonParser.Feature

View File

@ -22,9 +22,11 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
@ -437,6 +439,16 @@ public class Jackson2ObjectMapperBuilderTests {
assertTrue(xmlObjectMapper.getClass().isAssignableFrom(XmlMapper.class));
}
@Test // SPR-13975
public void defaultUseWrapper() throws JsonProcessingException {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.xml().defaultUseWrapper(false).build();
assertNotNull(objectMapper);
assertEquals(XmlMapper.class, objectMapper.getClass());
ListContainer<String> container = new ListContainer<>(Arrays.asList("foo", "bar"));
String output = objectMapper.writeValueAsString(container);
assertThat(output, containsString("<list>foo</list><list>bar</list></ListContainer>"));
}
public static class CustomIntegerModule extends Module {
@ -501,4 +513,24 @@ public class Jackson2ObjectMapperBuilderTests {
}
}
public static class ListContainer<T> {
private List<T> list;
public ListContainer() {
}
public ListContainer(List<T> list) {
this.list = list;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
}