Java Jackson:如果属性为null,则将其反序列化为另一个属性

Java Jackson:如果属性为null,则将其反序列化为另一个属性,java,jackson,deserialization,Java,Jackson,Deserialization,如果一个属性为null,我想将其反序列化为另一个属性 假设我有一门课: public class User { private String login; private String nickname; // getters, setters } 每次昵称为空时,我都想将登录作为默认值返回 Q:有没有一个通用的方法来实现这一点 注意:有一个海峡前进的道路,像这样的getter可以解决问题: public String getNickname() { retur

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

假设我有一门课:

public class User {
    private String login;
    private String nickname;
    // getters, setters
}
每次
昵称
为空时,我都想将
登录
作为默认值返回

Q:有没有一个通用的方法来实现这一点

注意:有一个海峡前进的道路,像这样的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();
        }
    }
}

在反序列化过程中,jackson调用类的setter。因此,我会尝试:

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;
    }
}
import com.fasterxml.jackson.core.JsonParser;
导入com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.core.ObjectCodec;
导入com.fasterxml.jackson.databind.DeserializationContext;
导入com.fasterxml.jackson.databind.JsonDeserializer;
导入com.fasterxml.jackson.databind.JsonNode;
导入java.io.IOException;
公共类UserDeserializer扩展JsonDeserializer{
@凌驾
公共用户反序列化(JsonParser jp,反序列化上下文ctxt)引发IOException,JsonProcessingException{
ObjectCodec oc=jp.getCodec();
JsonNode=oc.readTree(jp);
//final Long id=node.get(“id”).asLong();
最后一个字符串昵称=node.get(“昵称”).asText();
最终字符串login=null;
if(昵称!=null){
登录名=昵称;
}
用户=新用户();
user.set昵称(昵称);
user.setLogin(login);
返回用户;
}
}

很抱歉缩进可能不正确。

谢谢您的回答。这不起作用,因为这段代码序列化为json,但我需要将其反序列化回java对象。但我理解这个想法。不幸的是,它不适用于我,我希望有一些通用的解决方案。@OleksandrShpota同样,您可以自定义反序列化。谢谢您的回答,但它不是通用的解决方案。我必须为每个DTO写这样的东西。
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;
    }
}