diff --git a/src/main/java/com/github/trickl/jackson/module/httpquery/deser/BeanPropertySetterProvider.java b/src/main/java/com/github/trickl/jackson/module/httpquery/deser/BeanPropertySetterProvider.java deleted file mode 100644 index d861102..0000000 --- a/src/main/java/com/github/trickl/jackson/module/httpquery/deser/BeanPropertySetterProvider.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.trickl.jackson.module.httpquery.deser; - -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.DeserializationConfig; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig; -import com.fasterxml.jackson.databind.deser.BeanDeserializer; -import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder; -import com.fasterxml.jackson.databind.deser.BeanDeserializerFactory; -import com.fasterxml.jackson.databind.deser.ValueInstantiator; - -public class BeanPropertySetterProvider extends BeanDeserializerFactory { - - private static final long serialVersionUID = 1542811325586920895L; - - private final DeserializationContext context; - - /** - * Create a bean introspector. - * - * @param context The deserialization context - */ - public BeanPropertySetterProvider(DeserializationContext context) { - super(new DeserializerFactoryConfig()); - this.context = context; - } - - /** Get the serializable properties for a bean. */ - public BeanDeserializer getBeanDeserializer(JavaType javaType) throws JsonMappingException { - DeserializationConfig config = context.getConfig(); - BeanDescription beanDesc = config.introspect(javaType); - BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(context, beanDesc); - ValueInstantiator valueInstantiator = findValueInstantiator(context, beanDesc); - builder.setValueInstantiator(valueInstantiator); - addBeanProps(context, beanDesc, builder); - addInjectables(context, beanDesc, builder); - - BeanDeserializer deserializer = (BeanDeserializer) builder.build(); - deserializer.resolve(context); - return deserializer; - } -} diff --git a/src/main/java/com/github/trickl/jackson/module/httpquery/deser/HttpQueryDeserializer.java b/src/main/java/com/github/trickl/jackson/module/httpquery/deser/HttpQueryDeserializer.java index 4ef1620..2c83bbd 100644 --- a/src/main/java/com/github/trickl/jackson/module/httpquery/deser/HttpQueryDeserializer.java +++ b/src/main/java/com/github/trickl/jackson/module/httpquery/deser/HttpQueryDeserializer.java @@ -7,12 +7,17 @@ import com.fasterxml.jackson.core.json.ReaderBasedJsonParser; import com.fasterxml.jackson.core.sym.CharsToNameCanonicalizer; import com.fasterxml.jackson.core.util.BufferRecycler; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.PropertyName; +import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig; import com.fasterxml.jackson.databind.deser.BeanDeserializer; import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder; +import com.fasterxml.jackson.databind.deser.BeanDeserializerFactory; import com.fasterxml.jackson.databind.deser.SettableBeanProperty; import com.fasterxml.jackson.databind.deser.ValueInstantiator; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; @@ -54,9 +59,8 @@ public Object deserialize(JsonParser jp, DeserializationContext ctxt) if (queryString.startsWith("?")) { queryString = queryString.substring(1, queryString.length()); } - - BeanPropertySetterProvider beanPropertyProvider = new BeanPropertySetterProvider(ctxt); - BeanDeserializer beanDeserializer = beanPropertyProvider.getBeanDeserializer(javaType); + + BeanDeserializer beanDeserializer = getBeanDeserializer(ctxt, javaType); ValueInstantiator valueInstantiator = beanDeserializer.getValueInstantiator(); final Object bean = valueInstantiator.createUsingDefault(ctxt); @@ -117,6 +121,17 @@ public void deserializeNameValue( prop.deserializeAndSet(parser, ctxt, bean); } + private BeanDeserializer getBeanDeserializer( + DeserializationContext context, JavaType javaType) throws JsonMappingException { + DeserializationConfig config = context.getConfig(); + BeanDescription beanDesc = config.introspect(javaType); + BeanDeserializerFactory factory = BeanDeserializerFactory.instance; + BeanDeserializer deserializer = (BeanDeserializer) + factory.createBeanDeserializer(context, javaType, beanDesc); + deserializer.resolve(context); + return deserializer; + } + private IOContext getIoContext() { BufferRecycler recycler = new BufferRecycler(); return new IOContext(recycler, null, false); diff --git a/src/main/java/com/github/trickl/jackson/module/httpquery/ser/BeanPropertyWriterProvider.java b/src/main/java/com/github/trickl/jackson/module/httpquery/ser/BeanPropertyWriterProvider.java deleted file mode 100644 index 20dda82..0000000 --- a/src/main/java/com/github/trickl/jackson/module/httpquery/ser/BeanPropertyWriterProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.github.trickl.jackson.module.httpquery.ser; - -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.SerializationConfig; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; -import com.fasterxml.jackson.databind.ser.BeanSerializerBuilder; -import com.fasterxml.jackson.databind.ser.BeanSerializerFactory; -import java.util.List; - -public class BeanPropertyWriterProvider extends BeanSerializerFactory { - - private static final long serialVersionUID = 1L; - - private SerializerProvider provider; - - public BeanPropertyWriterProvider(SerializerProvider provider) { - super(null); - this.provider = provider; - } - - /** - * Get the serializable properties for a bean. - */ - public List getProperties(JavaType javaType) - throws JsonMappingException { - SerializationConfig config = provider.getConfig(); - BeanDescription beanDesc = config.introspect(javaType); - BeanSerializerBuilder builder = new BeanSerializerBuilder(beanDesc); - List props = findBeanProperties(provider, beanDesc, builder); - props.stream().forEach(prop -> prop.fixAccess(config)); - return props; - } -} diff --git a/src/main/java/com/github/trickl/jackson/module/httpquery/ser/HttpQuerySerializer.java b/src/main/java/com/github/trickl/jackson/module/httpquery/ser/HttpQuerySerializer.java index a6c3e14..ac6b40d 100644 --- a/src/main/java/com/github/trickl/jackson/module/httpquery/ser/HttpQuerySerializer.java +++ b/src/main/java/com/github/trickl/jackson/module/httpquery/ser/HttpQuerySerializer.java @@ -2,9 +2,16 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.BeanSerializer; +import com.fasterxml.jackson.databind.ser.BeanSerializerBuilder; +import com.fasterxml.jackson.databind.ser.BeanSerializerFactory; +import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.github.trickl.jackson.module.httpquery.annotations.HttpQueryDelimited; import java.io.IOException; @@ -13,9 +20,11 @@ import java.lang.reflect.Array; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -41,15 +50,16 @@ public HttpQuerySerializer( @Override public final void serialize(Object bean, JsonGenerator gen, SerializerProvider provider) - throws IOException { - BeanPropertyWriterProvider beanPropertyProvider = new BeanPropertyWriterProvider(provider); - BeanPropertyWriter[] props = - beanPropertyProvider.getProperties(javaType).toArray(new BeanPropertyWriter[0]); - + throws IOException { + BeanSerializer beanSerializer = getBeanSerializer(provider, javaType); + List propList = new ArrayList<>(); + beanSerializer.properties().forEachRemaining((prop) -> propList.add((BeanPropertyWriter) prop)); + BeanPropertyWriter[] props = propList.toArray(new BeanPropertyWriter[0]); + int i = 0; boolean propertyWritten = false; try { - for (final int len = props.length; i < len; ++i) { + for (final int len = props.length; i < len; ++i) { if (i == 0 && includeQuestionMark) { gen.writeRaw("?"); } else if (propertyWritten) { @@ -70,8 +80,7 @@ public final void serialize(Object bean, JsonGenerator gen, SerializerProvider p /** Write a property out as "name=value". */ public boolean serializeAsNameValue( Object bean, BeanPropertyWriter prop, JsonGenerator gen, SerializerProvider provider) - throws Exception { - + throws Exception { JsonFactory jsonFactory = new JsonFactory(); StringWriter valueWriter = new StringWriter(); Object propValue = prop.get(bean); @@ -84,13 +93,10 @@ public boolean serializeAsNameValue( if (propValue == null) { if (prop.willSuppressNulls()) { return false; - } else if (!prop.hasNullSerializer()) { - // Just return the parameter name + } else { gen.writeRaw(name); return true; - } else { - provider.findNullValueSerializer(prop).serialize(propValue, valueGenerator, provider); - } + } } else if (prop.getType().isTypeOrSubTypeOf(Collection.class) || prop.getType().isArrayType()) { Collection collection = Collections.emptyList(); @@ -140,4 +146,16 @@ public boolean serializeAsNameValue( private String encode(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } + + private BeanSerializer getBeanSerializer( + SerializerProvider provider, JavaType javaType) throws JsonMappingException { + + SerializationConfig config = provider.getConfig(); + BeanDescription beanDesc = config.introspect(javaType); + BeanSerializerFactory factory = BeanSerializerFactory.instance; + BeanSerializer serializer = (BeanSerializer) + factory.findBeanSerializer(provider, javaType, beanDesc); + serializer.resolve(provider); + return serializer; + } } diff --git a/src/test/java/com/github/trickl/jackson/module/httpquery/JsonIncludeTest.java b/src/test/java/com/github/trickl/jackson/module/httpquery/JsonIncludeTest.java index fe031aa..725eade 100644 --- a/src/test/java/com/github/trickl/jackson/module/httpquery/JsonIncludeTest.java +++ b/src/test/java/com/github/trickl/jackson/module/httpquery/JsonIncludeTest.java @@ -31,35 +31,23 @@ private static class MultiPropertyQuery { @JsonProperty("paramB") private String valueB; - @JsonProperty("paramC") - @JsonSerialize(nullsUsing = NullSerializer.class) - private String valueC; - - public MultiPropertyQuery(String valueA, String valueB, String valueC) { + public MultiPropertyQuery(String valueA, String valueB) { this.valueA = valueA; this.valueB = valueB; - this.valueC = valueC; } } @Test public void testExcludedNullParamSerialization() throws JsonProcessingException { - assertEquals("?paramB=valueB¶mC=valueC", + assertEquals("?paramB=valueB", objectMapper.writeValueAsString( - new MultiPropertyQuery(null, "valueB", "valueC"))); + new MultiPropertyQuery(null, "valueB"))); } @Test public void testIncludedNullAsEmptyParamSerialization() throws JsonProcessingException { - assertEquals("?paramA=valueA¶mB¶mC=valueC", - objectMapper.writeValueAsString( - new MultiPropertyQuery("valueA", null, "valueC"))); - } - - @Test - public void testIncludedNullAsNullParamSerialization() throws JsonProcessingException { - assertEquals("?paramA=valueA¶mB=valueB¶mC=null", + assertEquals("?paramA=valueA¶mB", objectMapper.writeValueAsString( - new MultiPropertyQuery("valueA", "valueB", null))); + new MultiPropertyQuery("valueA", null))); } }