基于另一个字段值忽略序列化字段

v440hwme  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(307)

我有这样一节课:

public class Profile {
        private String firstName;
        private String lastName;
        private String nickName;
        @JsonIgnore
        private boolean isNameSecret;
}

序列化对象时,可以隐藏属性 firstName 以及 lastName 如果 isNameSecrettrue ?

ql3eal8s

ql3eal8s1#

您需要编写自定义序列化程序并实现该逻辑。它可以如下所示:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.IOException;

public class ProfileApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        System.out.println(mapper.writeValueAsString(new Profile()));
    }
}

class ProfileJsonSerialize extends JsonSerializer<Profile> {

    @Override
    public void serialize(Profile profile, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        if (!profile.isNameSecret()) {
            gen.writeStringField("firstName", profile.getFirstName());
            gen.writeStringField("lastName", profile.getLastName());
        }
        gen.writeStringField("nickName", profile.getNickName());
        gen.writeEndObject();
    }
}

@JsonSerialize(using = ProfileJsonSerialize.class)
class Profile {

    private String firstName = "Rick";
    private String lastName = "Sanchez";
    private String nickName = "Pickle Rick";
    private boolean isNameSecret = true;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public boolean isNameSecret() {
        return isNameSecret;
    }

    public void setNameSecret(boolean nameSecret) {
        isNameSecret = nameSecret;
    }
}

以上代码打印:

{
  "nickName" : "Pickle Rick"
}
r55awzrz

r55awzrz2#

这可以通过使用jackson的mixin特性来实现。它允许在运行时应用外部类的注解。匹配是通过指定相同的属性名来完成的(也适用于getter/setter等方法名)
下面是一个问题示例(为了简单起见将示例变量公开),注意mixin类只包含要重写的属性。而且,它不需要初始化。
具有相同属性名和添加注解的mixin类

public class ProfileIgnoreFirstLastName
{
    @JsonIgnore
    public String firstName;
    @JsonIgnore
    public String lastName;
}

mixin类的条件应用序列化:

public static String serializeProfile(Profile profile) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    if (profile.isNameSecret) {
        mapper.addMixIn(Profile.class, ProfileIgnoreFirstLastName.class);
    }
    return mapper.writeValueAsString(profile);
}

试验方法

public static void main(String[] args) {
    try {
        Profile profile = new Profile();
        profile.isNameSecret = false;
        System.out.println(serializeProfile(profile));
        profile.isNameSecret = true;
        System.out.println(serializeProfile(profile));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

输出

{"firstName":"my first name","lastName":"my last name","nickName":"my nick name"}
{"nickName":"my nick name"}

相关问题