/* * Copyright 2002-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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.http.converter.json; import java.io.IOException; import java.io.UnsupportedEncodingException; 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; import java.util.TimeZone; import com.fasterxml.jackson.annotation.JsonFilter; import com.fasterxml.jackson.annotation.JsonInclude; 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.DeserializationFeature; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonMappingException; 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; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig; import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig; import com.fasterxml.jackson.databind.deser.BasicDeserializerFactory; import com.fasterxml.jackson.databind.deser.Deserializers; import com.fasterxml.jackson.databind.deser.std.DateDeserializers; import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.module.SimpleSerializers; import com.fasterxml.jackson.databind.ser.BasicSerializerFactory; import com.fasterxml.jackson.databind.ser.Serializers; import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; import com.fasterxml.jackson.databind.ser.std.ClassSerializer; import com.fasterxml.jackson.databind.ser.std.NumberSerializer; 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 kotlin.ranges.IntRange; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Test; import org.springframework.beans.FatalBeanException; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; /** * Test class for {@link Jackson2ObjectMapperBuilder}. * * @author Sebastien Deleuze */ @SuppressWarnings("deprecation") public class Jackson2ObjectMapperBuilderTests { private static final String DATE_FORMAT = "yyyy-MM-dd"; @Test public void settersWithNullValues() { // Should not crash: Jackson2ObjectMapperBuilder.json().serializers((JsonSerializer<?>[]) null) .serializersByType(null).deserializersByType(null) .featuresToEnable((Object[]) null).featuresToDisable((Object[]) null); } @Test(expected = FatalBeanException.class) public void unknownFeature() { Jackson2ObjectMapperBuilder.json().featuresToEnable(Boolean.TRUE).build(); } @Test public void defaultProperties() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); assertNotNull(objectMapper); assertFalse(objectMapper.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertFalse(objectMapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); assertTrue(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_FIELDS)); assertTrue(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_GETTERS)); assertTrue(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)); assertTrue(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_SETTERS)); assertFalse(objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)); assertTrue(objectMapper.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)); } @Test public void propertiesShortcut() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().autoDetectFields(false) .defaultViewInclusion(true).failOnUnknownProperties(true).failOnEmptyBeans(false) .autoDetectGettersSetters(false).indentOutput(true).build(); assertNotNull(objectMapper); assertTrue(objectMapper.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertTrue(objectMapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_FIELDS)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_GETTERS)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_SETTERS)); assertTrue(objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)); assertFalse(objectMapper.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)); } @Test public void booleanSetters() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() .featuresToEnable(MapperFeature.DEFAULT_VIEW_INCLUSION, DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, SerializationFeature.INDENT_OUTPUT) .featuresToDisable(MapperFeature.AUTO_DETECT_FIELDS, MapperFeature.AUTO_DETECT_GETTERS, MapperFeature.AUTO_DETECT_SETTERS, SerializationFeature.FAIL_ON_EMPTY_BEANS).build(); assertNotNull(objectMapper); assertTrue(objectMapper.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertTrue(objectMapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_FIELDS)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_GETTERS)); assertFalse(objectMapper.isEnabled(MapperFeature.AUTO_DETECT_SETTERS)); assertTrue(objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)); assertFalse(objectMapper.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)); } @Test public void setNotNullSerializationInclusion() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); assertSame(JsonInclude.Include.ALWAYS, objectMapper.getSerializationConfig().getSerializationInclusion()); objectMapper = Jackson2ObjectMapperBuilder.json().serializationInclusion(JsonInclude.Include.NON_NULL).build(); assertSame(JsonInclude.Include.NON_NULL, objectMapper.getSerializationConfig().getSerializationInclusion()); } @Test public void setNotDefaultSerializationInclusion() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); assertSame(JsonInclude.Include.ALWAYS, objectMapper.getSerializationConfig().getSerializationInclusion()); objectMapper = Jackson2ObjectMapperBuilder.json().serializationInclusion(JsonInclude.Include.NON_DEFAULT).build(); assertSame(JsonInclude.Include.NON_DEFAULT, objectMapper.getSerializationConfig().getSerializationInclusion()); } @Test public void setNotEmptySerializationInclusion() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); assertSame(JsonInclude.Include.ALWAYS, objectMapper.getSerializationConfig().getSerializationInclusion()); objectMapper = Jackson2ObjectMapperBuilder.json().serializationInclusion(JsonInclude.Include.NON_EMPTY).build(); assertSame(JsonInclude.Include.NON_EMPTY, objectMapper.getSerializationConfig().getSerializationInclusion()); } @Test public void dateTimeFormatSetter() { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().dateFormat(dateFormat).build(); assertEquals(dateFormat, objectMapper.getSerializationConfig().getDateFormat()); assertEquals(dateFormat, objectMapper.getDeserializationConfig().getDateFormat()); } @Test public void simpleDateFormatStringSetter() { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().simpleDateFormat(DATE_FORMAT).build(); assertEquals(dateFormat, objectMapper.getSerializationConfig().getDateFormat()); assertEquals(dateFormat, objectMapper.getDeserializationConfig().getDateFormat()); } @Test public void localeSetter() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().locale(Locale.FRENCH).build(); assertEquals(Locale.FRENCH, objectMapper.getSerializationConfig().getLocale()); assertEquals(Locale.FRENCH, objectMapper.getDeserializationConfig().getLocale()); } @Test public void timeZoneSetter() { TimeZone timeZone = TimeZone.getTimeZone("Europe/Paris"); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().timeZone(timeZone).build(); assertEquals(timeZone, objectMapper.getSerializationConfig().getTimeZone()); assertEquals(timeZone, objectMapper.getDeserializationConfig().getTimeZone()); } @Test public void timeZoneStringSetter() { String zoneId = "Europe/Paris"; ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().timeZone(zoneId).build(); TimeZone timeZone = TimeZone.getTimeZone(zoneId); assertEquals(timeZone, objectMapper.getSerializationConfig().getTimeZone()); assertEquals(timeZone, objectMapper.getDeserializationConfig().getTimeZone()); } @Test(expected = IllegalArgumentException.class) public void wrongTimeZoneStringSetter() { String zoneId = "foo"; Jackson2ObjectMapperBuilder.json().timeZone(zoneId).build(); } @Test public void modules() { NumberSerializer serializer1 = new NumberSerializer(Integer.class); SimpleModule module = new SimpleModule(); module.addSerializer(Integer.class, serializer1); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(module).build(); Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); assertSame(serializer1, serializers.findSerializer(null, SimpleType.construct(Integer.class), null)); } @Test @SuppressWarnings("unchecked") public void modulesToInstallByClass() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modulesToInstall(CustomIntegerModule.class).build(); Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); assertSame(CustomIntegerSerializer.class, serializers.findSerializer(null, SimpleType.construct(Integer.class), null).getClass()); } @Test public void modulesToInstallByInstance() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modulesToInstall(new CustomIntegerModule()).build(); Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); assertSame(CustomIntegerSerializer.class, serializers.findSerializer(null, SimpleType.construct(Integer.class), null).getClass()); } @Test public void wellKnownModules() throws JsonProcessingException, UnsupportedEncodingException { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); Long timestamp = 1322903730000L; DateTime dateTime = new DateTime(timestamp, DateTimeZone.UTC); assertEquals(timestamp.toString(), new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")); Path file = Paths.get("foo"); assertTrue(new String(objectMapper.writeValueAsBytes(file), "UTF-8").endsWith("foo\"")); Optional<String> optional = Optional.of("test"); assertEquals("\"test\"", new String(objectMapper.writeValueAsBytes(optional), "UTF-8")); // Kotlin module IntRange range = new IntRange(1, 3); assertEquals("{\"start\":1,\"end\":3}", new String(objectMapper.writeValueAsBytes(range), "UTF-8")); } @Test // SPR-12634 public void customizeWellKnownModulesWithModule() throws JsonProcessingException, UnsupportedEncodingException { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() .modulesToInstall(new CustomIntegerModule()).build(); DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); assertEquals("1322903730000", new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")); assertThat(new String(objectMapper.writeValueAsBytes(new Integer(4)), "UTF-8"), containsString("customid")); } @Test // SPR-12634 @SuppressWarnings("unchecked") public void customizeWellKnownModulesWithModuleClass() throws JsonProcessingException, UnsupportedEncodingException { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modulesToInstall(CustomIntegerModule.class).build(); DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); assertEquals("1322903730000", new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")); assertThat(new String(objectMapper.writeValueAsBytes(new Integer(4)), "UTF-8"), containsString("customid")); } @Test // SPR-12634 public void customizeWellKnownModulesWithSerializer() throws JsonProcessingException, UnsupportedEncodingException { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() .serializerByType(Integer.class, new CustomIntegerSerializer()).build(); DateTime dateTime = new DateTime(1322903730000L, DateTimeZone.UTC); assertEquals("1322903730000", new String(objectMapper.writeValueAsBytes(dateTime), "UTF-8")); assertThat(new String(objectMapper.writeValueAsBytes(new Integer(4)), "UTF-8"), containsString("customid")); } private static SerializerFactoryConfig getSerializerFactoryConfig(ObjectMapper objectMapper) { return ((BasicSerializerFactory) objectMapper.getSerializerFactory()).getFactoryConfig(); } private static DeserializerFactoryConfig getDeserializerFactoryConfig(ObjectMapper objectMapper) { return ((BasicDeserializerFactory) objectMapper.getDeserializationContext().getFactory()).getFactoryConfig(); } @Test public void propertyNamingStrategy() { PropertyNamingStrategy strategy = new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy(); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().propertyNamingStrategy(strategy).build(); assertSame(strategy, objectMapper.getSerializationConfig().getPropertyNamingStrategy()); assertSame(strategy, objectMapper.getDeserializationConfig().getPropertyNamingStrategy()); } @Test public void serializerByType() { JsonSerializer<Number> serializer = new NumberSerializer(Integer.class); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() .modules(new ArrayList<>()) // Disable well-known modules detection .serializerByType(Boolean.class, serializer).build(); assertTrue(getSerializerFactoryConfig(objectMapper).hasSerializers()); Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); assertSame(serializer, serializers.findSerializer(null, SimpleType.construct(Boolean.class), null)); } @Test public void deserializerByType() throws JsonMappingException { JsonDeserializer<Date> deserializer = new DateDeserializers.DateDeserializer(); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() .modules(new ArrayList<>()) // Disable well-known modules detection .deserializerByType(Date.class, deserializer).build(); assertTrue(getDeserializerFactoryConfig(objectMapper).hasDeserializers()); Deserializers deserializers = getDeserializerFactoryConfig(objectMapper).deserializers().iterator().next(); assertSame(deserializer, deserializers.findBeanDeserializer(SimpleType.construct(Date.class), null, null)); } @Test public void mixIn() { Class<?> target = String.class; Class<?> mixInSource = Object.class; ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules() .mixIn(target, mixInSource).build(); assertEquals(1, objectMapper.mixInCount()); assertSame(mixInSource, objectMapper.findMixInClassFor(target)); } @Test public void mixIns() { Class<?> target = String.class; Class<?> mixInSource = Object.class; Map<Class<?>, Class<?>> mixIns = new HashMap<>(); mixIns.put(target, mixInSource); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules() .mixIns(mixIns).build(); assertEquals(1, objectMapper.mixInCount()); assertSame(mixInSource, objectMapper.findMixInClassFor(target)); } @Test public void filters() throws JsonProcessingException { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() .filters(new SimpleFilterProvider().setFailOnUnknownId(false)).build(); JacksonFilteredBean bean = new JacksonFilteredBean("value1", "value2"); String output = objectMapper.writeValueAsString(bean); assertThat(output, containsString("value1")); assertThat(output, containsString("value2")); objectMapper = Jackson2ObjectMapperBuilder.json().filters((new SimpleFilterProvider().setFailOnUnknownId(false) .setDefaultFilter(SimpleBeanPropertyFilter.serializeAllExcept("property2")))).build(); output = objectMapper.writeValueAsString(bean); assertThat(output, containsString("value1")); assertThat(output, not(containsString("value2"))); } @Test public void completeSetup() throws JsonMappingException { NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance; Map<Class<?>, JsonDeserializer<?>> deserializerMap = new HashMap<>(); JsonDeserializer<Date> deserializer = new DateDeserializers.DateDeserializer(); deserializerMap.put(Date.class, deserializer); JsonSerializer<Class<?>> serializer1 = new ClassSerializer(); JsonSerializer<Number> serializer2 = new NumberSerializer(Integer.class); Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json() .modules(new ArrayList<>()) // Disable well-known modules detection .serializers(serializer1) .serializersByType(Collections.<Class<?>, JsonSerializer<?>>singletonMap(Boolean.class, serializer2)) .deserializersByType(deserializerMap) .annotationIntrospector(annotationIntrospector) .featuresToEnable(SerializationFeature.FAIL_ON_EMPTY_BEANS, DeserializationFeature.UNWRAP_ROOT_VALUE, JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS) .featuresToDisable(MapperFeature.AUTO_DETECT_GETTERS, MapperFeature.AUTO_DETECT_FIELDS, JsonParser.Feature.AUTO_CLOSE_SOURCE, JsonGenerator.Feature.QUOTE_FIELD_NAMES) .serializationInclusion(JsonInclude.Include.NON_NULL); ObjectMapper objectMapper = new ObjectMapper(); builder.configure(objectMapper); assertTrue(getSerializerFactoryConfig(objectMapper).hasSerializers()); assertTrue(getDeserializerFactoryConfig(objectMapper).hasDeserializers()); Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); assertSame(serializer1, serializers.findSerializer(null, SimpleType.construct(Class.class), null)); assertSame(serializer2, serializers.findSerializer(null, SimpleType.construct(Boolean.class), null)); assertNull(serializers.findSerializer(null, SimpleType.construct(Number.class), null)); Deserializers deserializers = getDeserializerFactoryConfig(objectMapper).deserializers().iterator().next(); assertSame(deserializer, deserializers.findBeanDeserializer(SimpleType.construct(Date.class), null, null)); assertSame(annotationIntrospector, objectMapper.getSerializationConfig().getAnnotationIntrospector()); assertSame(annotationIntrospector, objectMapper.getDeserializationConfig().getAnnotationIntrospector()); assertTrue(objectMapper.getSerializationConfig().isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)); assertTrue(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.UNWRAP_ROOT_VALUE)); assertTrue(objectMapper.getFactory().isEnabled(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER)); assertTrue(objectMapper.getFactory().isEnabled(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS)); assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.AUTO_DETECT_GETTERS)); assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); assertFalse(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.AUTO_DETECT_FIELDS)); assertFalse(objectMapper.getFactory().isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)); assertFalse(objectMapper.getFactory().isEnabled(JsonGenerator.Feature.QUOTE_FIELD_NAMES)); assertSame(JsonInclude.Include.NON_NULL, objectMapper.getSerializationConfig().getSerializationInclusion()); } @Test public void xmlMapper() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.xml().build(); assertNotNull(objectMapper); assertEquals(XmlMapper.class, objectMapper.getClass()); } @Test public void createXmlMapper() { Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json().indentOutput(true); ObjectMapper jsonObjectMapper = builder.build(); ObjectMapper xmlObjectMapper = builder.createXmlMapper(true).build(); assertTrue(jsonObjectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)); assertTrue(xmlObjectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)); 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>")); } @Test // SPR-14435 public void smile() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.smile().build(); assertNotNull(objectMapper); assertEquals(SmileFactory.class, objectMapper.getFactory().getClass()); } @Test // SPR-14435 public void cbor() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.cbor().build(); assertNotNull(objectMapper); assertEquals(CBORFactory.class, objectMapper.getFactory().getClass()); } @Test // SPR-14435 public void factory() { ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder().factory(new SmileFactory()).build(); assertNotNull(objectMapper); assertEquals(SmileFactory.class, objectMapper.getFactory().getClass()); } public static class CustomIntegerModule extends Module { @Override public String getModuleName() { return this.getClass().getSimpleName(); } @Override public Version version() { return Version.unknownVersion(); } @Override public void setupModule(SetupContext context) { SimpleSerializers serializers = new SimpleSerializers(); serializers.addSerializer(Integer.class, new CustomIntegerSerializer()); context.addSerializers(serializers); } } public static class CustomIntegerSerializer extends JsonSerializer<Integer> { @Override public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); gen.writeNumberField("customid", value); gen.writeEndObject(); } } @JsonFilter("myJacksonFilter") public static class JacksonFilteredBean { public JacksonFilteredBean() { } public JacksonFilteredBean(String property1, String property2) { this.property1 = property1; this.property2 = property2; } private String property1; private String property2; public String getProperty1() { return property1; } public void setProperty1(String property1) { this.property1 = property1; } public String getProperty2() { return property2; } public void setProperty2(String property2) { this.property2 = property2; } } 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; } } }