简体   繁体   English

Jackson:将属性反序列化为另一个属性(如果为null)

[英]Jackson: deserialize property to another property if it is null

I want to deserialize one property to another property if it is null. 我想将一个属性反序列化为另一个属性,如果它为null。

Let's say I have a class: 假设我有一堂课:

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

Every time nickname comes as null I'd like to return login as default value. 每次nickname为null时,我都想返回login作为默认值。

Q: Is there a general way to achieve this playing around with Jackson deserializers? 问:是否有一般方法可以与Jackson解串器配合使用?

Note: There is a strait-forward way, getter like this will solve the problem: 注意:有两种方法可以解决此问题:

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

But it isn't elegant, and I don't want to put any logic into my DTO objects. 但这并不优雅,我也不想在DTO对象中加入任何逻辑。

You can custom the serialization 您可以自定义序列化

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();
        }
    }
}

register the serializer directly on the class 在类上直接注册序列化器

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

During the deserialization jackson calls setters of the class. 在反序列化期间,杰克逊会呼叫该类的设置者。 So, I would try: 因此,我会尝试:

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

The property login probably needs @JsonIgnore in this case. 在这种情况下,属性登录名可能需要@JsonIgnore。 Anyway, this code is confusing, because setter has a side effect. 无论如何,此代码令人困惑,因为setter有副作用。

Returning to deserializer. 返回解串器。 In such case, you need to write a custom deserializer: 在这种情况下,您需要编写一个自定义反序列化器:

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;
    }
}

Sorry for possibly incorrect indentation. 很抱歉缩进不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM