杰克逊:如果属性为 null,则将属性反序列化为另一个属性



如果一个属性为空,我想将一个属性反序列化为另一个属性。

假设我有一个类:

public class User {
    private String login;
    private String nickname;
    // getters, setters
}

每次nickname显示为 null 时,我都想返回login默认值。

问:有没有一种通用的方法来实现这一点,使用杰克逊反序列化器?

注意:有一个向前推进的方法,像这样的getter将解决问题:

public String getNickname() {
    return nickname == null ? login : nickname;
}

但它并不优雅,我不想在我的 DTO 对象中加入任何逻辑。

您可以自定义序列化

public class CustomFooSerialize extends JsonSerializer<Foo> {
    @Override
    public void serialize(Foo foo, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        if (foo.getNickname() == null) {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("nickname", foo.getLogin());
            jsonGenerator.writeEndObject();
        }
    }
}

直接在类上注册序列化程序

@JsonSerialize(using = CustomFooSerialize.class)
public class Foo

在反序列化期间,杰克逊调用该类的二传手。所以,我会尝试:

public void setNickname(String nickname) {
    this.nickname == nickname;
    if (nickname != null) {
        login = nickname;
    }
}

在这种情况下,属性登录可能需要@JsonIgnore。无论如何,这段代码令人困惑,因为 setter 有一个副作用。

返回到反序列化程序。在这种情况下,您需要编写一个自定义反序列化程序:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
public class UserDeserializer extends JsonDeserializer<User> {
    @Override
    public User deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        ObjectCodec oc = jp.getCodec();
        JsonNode node = oc.readTree(jp);
        //final Long id = node.get("id").asLong();
        final String nickname = node.get("nickname").asText();
        final String login = null;
        if (nickname != null) {
            login = nickname;
        }
        User user = new User();
        user.setNickname(nickname);
        user.setLogin(login);
        return user;
    }
}

很抱歉缩进可能不正确。

最新更新