Created
December 1, 2019 12:00
-
-
Save chenyhd/907967f47912efe430e65bdc08185ca9 to your computer and use it in GitHub Desktop.
Jackson return empty instead of null
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xx.xx; | |
import com.fasterxml.jackson.core.JsonGenerator; | |
import com.fasterxml.jackson.core.JsonProcessingException; | |
import com.fasterxml.jackson.databind.*; | |
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider; | |
import com.fasterxml.jackson.databind.ser.SerializerFactory; | |
import java.io.IOException; | |
import java.util.List; | |
import java.util.Map; | |
public class CustomNullSerializer extends DefaultSerializerProvider { | |
// A couple of constructors and factory methods to keep the compiler happy | |
public CustomNullSerializer() { | |
super(); | |
} | |
public CustomNullSerializer(CustomNullSerializer provider, SerializationConfig config, | |
SerializerFactory jsf) { | |
super(provider, config, jsf); | |
} | |
@Override | |
public CustomNullSerializer createInstance(SerializationConfig config, | |
SerializerFactory jsf) { | |
return new CustomNullSerializer(this, config, jsf); | |
} | |
// This is the interesting part. When the property has a null value it will call this method to get the | |
// serializer for that null value. At this point, we have the BeanProperty, which contains information about | |
// the field that we are trying to serialize (including the type!) So we can discriminate on the type to determine | |
// which serializer is used to output the null value. | |
@Override | |
public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException { | |
if (property.getType().getRawClass().equals(String.class)) { | |
return EmptyStringSerializer.INSTANCE; | |
} else if (property.getType().getRawClass().equals(List.class)) { // You can also add ArrayList,LinkedList etc | |
return new JsonSerializer<Object>() { | |
@Override | |
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { | |
gen.writeStartArray(); | |
gen.writeEndArray(); | |
} | |
}; | |
} else if (property.getType().getRawClass().equals(Map.class)) { // You can also add HashMap,TreeMap etc | |
return new JsonSerializer<Object>() { | |
@Override | |
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { | |
gen.writeStartObject(); | |
gen.writeEndObject(); | |
} | |
}; | |
} else { | |
return super.findNullValueSerializer(property); | |
} | |
} | |
// This is our fancy serializer that takes care of writing the value desired in the case of a null string. We could | |
// write whatever we want in here, but in order to maintain backward compatibility we choose the empty string | |
// instead of something like "joel is awesome." | |
public static class EmptyStringSerializer extends JsonSerializer<Object> { | |
public static final JsonSerializer<Object> INSTANCE = new EmptyStringSerializer(); | |
private EmptyStringSerializer() { | |
} | |
// Since we know we only get to this seralizer in the case where the value is null and the type is String, we can | |
// do our handling without any additional logic and write that empty string we are so desperately wanting. | |
@Override | |
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) | |
throws IOException, JsonProcessingException { | |
jsonGenerator.writeString(""); | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xx.xx; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.http.converter.HttpMessageConverter; | |
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | |
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; | |
import java.util.List; | |
@Configuration | |
public class WebMvcConfig extends WebMvcConfigurationSupport { | |
@Override | |
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { | |
converters.add(customJackson2HttpMessageConverter()); | |
super.configureMessageConverters(converters); | |
} | |
@Bean | |
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() { | |
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); | |
ObjectMapper objectMapper = new ObjectMapper(); | |
objectMapper.setSerializerProvider(new CustomNullSerializer()); | |
jsonConverter.setObjectMapper(objectMapper); | |
return jsonConverter; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I quoted some other websites (such as StackOverflow, baeldung and so on) code and combined it to make it look more complete, but I can't find the website I referred to before. If you find the original code you can contact me and I will add the original author.