Jackson:将空字符串反序列化为空字符串

uinbv5nw  于 2022-11-08  发布在  其他
关注(0)|答案(5)|浏览(322)

我有下面的类,那是JacksonMap的(简化版):

public class POI {
    @JsonProperty("name")
    private String name;
}

在某些情况下,服务器返回"name": null,然后我想将name设置为空Java String。
是否有Jackson注解,或者如果属性为null,我是否应该检查getter中的null并返回空字符串?

dvtswwa3

dvtswwa31#

Jackson2.9实际上提供了一个尚未提及的新机制:将@JsonSetter用于属性,并将其等效的“Config Overrides”用于String.class等类型。
https://medium.com/@cowtowncoder/jackson-2-9-features-b2a19029e9ff
但要点是,您可以像这样标记字段(或setter):

@JsonSetter(nulls=Nulls.AS_EMPTY) public String stringValue;

或者配置Map器对所有String值属性执行相同的操作:

mapper.configOverride(String.class)
 .setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));

这两个函数都将传入的null转换为空值,对于字符串,空值为“"。
如预期的那样,这也适用于CollectionMap

nkkqxpd9

nkkqxpd92#

同样,这个答案是为碰巧发现这个线程的SO用户准备的。
虽然接受的答案在所有意义上都是可接受的和有效的--但它对我没有帮助,因为只有在我们向iOS客户端提供服务之后,才决定将null字符串值设置为empty字符串。
因此,大约30-40个pojo(不断增加),并在示例化有问题的对象时或在声明时初始化它们,这太多了。
我们是这样做的。

public class CustomSerializerProvider extends DefaultSerializerProvider {

    public CustomSerializerProvider() {
        super();
    }

    public CustomSerializerProvider(CustomSerializerProvider provider, SerializationConfig config,
            SerializerFactory jsf) {
        super(provider, config, jsf);
    }

    @Override
    public CustomSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf) {
        return new CustomSerializerProvider(this, config, jsf);
    }

    @Override
    public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException {
        if (property.getType().getRawClass().equals(String.class))
            return Serializers.EMPTY_STRING_SERIALIZER_INSTANCE;
        else
            return super.findNullValueSerializer(property);
    }
}

并且,串行化器

public class Serializers extends JsonSerializer<Object> {
    public static final JsonSerializer<Object> EMPTY_STRING_SERIALIZER_INSTANCE = new EmptyStringSerializer();

    public Serializers() {}

    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException, JsonProcessingException {
        jsonGenerator.writeString("");
    }

    private static class EmptyStringSerializer extends JsonSerializer<Object> {
        public EmptyStringSerializer() {}

        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                throws IOException, JsonProcessingException {
            jsonGenerator.writeString("");
        }
    }
}

然后,在ObjectMapper中设置序列化程序。(Jackson2.7.4

ObjectMapper nullMapper = new ObjectMapper();
nullMapper.setSerializerProvider(new CustomSerializerProvider());

希望,这能为某人节省一些时间。

ws51t4hk

ws51t4hk3#

一个简单的解决方案,不使用Jackson的专长:为name编写一个Getter,它返回一个空String而不是null,因为Jackson使用这些值进行序列化。

public String getName() {
  return name != null ? name : "";
}

另一种方法是编写一个自定义反序列化程序。http://wiki.fasterxml.com/JacksonHowToCustomSerializers

oalqel3c

oalqel3c4#

您可以在预设建构函式中设定,或在宣告时设定:

public class POI {
    @JsonProperty("name")
    private String name; 

    public POI() {
        name = "";
    }
}

public class POI {
    @JsonProperty("name")
    private String name = "";
}
afdcj2ne

afdcj2ne5#

如果您正在寻找适用于 Spring Boot 的全局解决方案,则可以配置ObjectMapper

@Configuration
public class JacksonConfiguration {

    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder mapperBuilder) {
        DefaultSerializerProvider sp = new DefaultSerializerProvider.Impl();
        sp.setNullValueSerializer(new JsonSerializer<Object>() {
            public void serialize(Object value, JsonGenerator jgen,
                                  SerializerProvider provider)
                    throws IOException, JsonProcessingException
            {
                jgen.writeString("");
            }
        });
        ObjectMapper mapper = mapperBuilder.build();
        mapper.setSerializerProvider(sp);
        return mapper;
    }

}

相关问题