【问题标题】:Ignore empty string as null during deserialization在反序列化期间将空字符串忽略为空
【发布时间】:2017-09-07 02:00:02
【问题描述】:

我尝试将以下 json 反序列化为 java pojo。

[{
    "image" : {
        "url" : "http://foo.bar"
    }
}, {
    "image" : ""      <-- This is some funky null replacement
}, {
    "image" : null    <-- This is the expected null value (Never happens in that API for images though)
}]

我的 Java 类看起来像这样:

public class Server {

    public Image image;
    // lots of other attributes

}

public class Image {

    public String url;
    // few other attributes

}

我使用杰克逊 2.8.6

ObjectMapper.read(json, LIST_OF_SERVER_TYPE_REFERENCE);

但我不断收到以下异常:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of Image: no String-argument constructor/factory method to deserialize from String value ('')

如果我为它添加一个字符串设置器

public void setImage(Image image) {
    this.image = image;
}

public void setImage(String value) {
    // Ignore
}

我得到以下异常

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token

无论我(也)是否添加图像设置器,异常都不会改变。

我也试过@JsonInclude(NOT_EMPTY),但这似乎只会影响序列化。

总结:一些(设计糟糕的)API 向我发送了一个空字符串 ("") 而不是 null,我必须告诉 Jackson 忽略那个糟糕的值。我该怎么做?

【问题讨论】:

  • 你需要一个自定义的反序列化器,它首先检查你是否有一个图像对象或一个字符串然后反序列化它。

标签: java json jackson json-deserialization


【解决方案1】:

似乎没有开箱即用的解决方案,所以我选择了自定义反序列化器:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;

public class ImageDeserializer extends JsonDeserializer<Image> {

    @Override
    public Image deserialize(final JsonParser parser, final DeserializationContext context)
            throws IOException, JsonProcessingException {
        final JsonToken type = parser.currentToken();
        switch (type) {
            case VALUE_NULL:
                return null;
            case VALUE_STRING:
                return null; // TODO: Should check whether it is empty
            case START_OBJECT:
                return context.readValue(parser, Image.class);
            default:
                throw new IllegalArgumentException("Unsupported JsonToken type: " + type);
        }
    }

}

并使用以下代码使用它

@JsonDeserialize(using = ImageDeserializer.class)
@JsonProperty("image")
public Image image;

【讨论】:

    猜你喜欢
    • 2021-08-25
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    相关资源
    最近更新 更多