为了账号安全,请及时绑定邮箱和手机立即绑定

Jackson 2:仅在序列化时忽略瞬态字段

Jackson 2:仅在序列化时忽略瞬态字段

Helenr 2023-11-10 15:49:39
我在 JAX-RS 应用程序中使用 Jackson v2,并且试图弄清楚是否可以配置“ObjectMapper”以删除带有瞬态修饰符的字段,但仅限于序列化期间。这是一个 DTO 来说明我的用例(省略了 getter 和 setter)public class User {     private String email;         private transient String password; }考虑到上述 DTO,我希望有一个对象映射器,它在序列化时删除密码字段,并在反序列化期间包含它。我能找到的关于瞬态的唯一信息是:MapperFeature.PROPAGATE_TRANSIENT_MARKER但该配置与我的要求不相关。PS - 不使用注释,因为 DTO 不耦合到任何库,而且我不一定可以控制它们。
查看完整描述

1 回答

?
长风秋雁

TA贡献1757条经验 获得超7个赞

不知道,看起来像transient属性修饰符加上PROPAGATE_TRANSIENT_MARKER就可以了。反序列化是直接的。不过,在序列化过程中,瞬态标记有些麻烦。您需要为字段提供 getter,否则您将遇到异常“无法识别的字段...未标记为可忽略”。

为了满足额外的要求,我添加了一个使用 jackson mixins 的版本。请注意,mixin 版本生成带有空密码字段的 json,而 PROPAGATE_TRANSIENT_MARKER 版本根本不生成任何字段。

PROPAGATE_TRANSIENT_MARKER 版本

public class SerializeDeserializeAttributes {

    private final ObjectMapper mapper = new ObjectMapper();


public <T> T fromJson(String json, Class<T> c) throws IOException {

    synchronized (mapper) {

        mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, false);

        return mapper.readValue(json, c);

    }

}


public String toJson(Object o) throws JsonProcessingException {

    synchronized (mapper) {

        mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);

        return mapper.writeValueAsString(o);

    }

}


    private static final String jsonFull = "{\"name\":\"A\",\"email\":\"a@a\",\"password\":\"a\",\"width\":1,\"height\":1}";

    private static final String jsonPartial = "{\"name\":\"A\",\"email\":\"a@a\",\"width\":1,\"height\":1}";

    private static final User user = new User("A", "a@a", "a", 1, 1);


    @Test

    public void serializeDeserialize() throws IOException {

        assertEquals(user, fromJson(jsonFull, User.class));

        assertEquals(jsonPartial, toJson(user));

        assertEquals(user, fromJson(jsonFull, User.class));

        assertEquals(jsonPartial, toJson(user));

    }

}

Mixin version


public class SerializeDeserializeAttributesMixin {


    public abstract class UserMixin {

        @JsonSerialize(using = PwdSerializer.class)

        transient String password;

    }


    static class PwdSerializer extends StdSerializer<String> {


        public PwdSerializer() {

            this(String.class);

        }


        private PwdSerializer(Class<String> t) {

            super(t);

        }


        @Override

        public void serialize(String s, JsonGenerator jg, SerializerProvider sp) throws IOException {

            jg.writeString("");

        }

    }


    private static final String jsonFull = "{\"name\":\"A\",\"email\":\"a@a\",\"password\":\"a\",\"width\":1,\"height\":1}";

    private static final String jsonPartialMixin = "{\"name\":\"A\",\"email\":\"a@a\",\"password\":\"\",\"width\":1,\"height\":1}";

    private static final User user = new User("A", "a@a", "a", 1, 1);

    private static final ObjectMapper mapperMixin = new ObjectMapper();


    static {

        mapperMixin.addMixIn(User.class, UserMixin.class);

    }



    @Test

    public void serializeDeserializeUsingMixin() throws IOException {

        assertEquals(user, mapperMixin.readValue(jsonFull, User.class));

        assertEquals(jsonPartialMixin, mapperMixin.writeValueAsString(user));

    }


}

那是用户类。


class User {

    private String name;

    private String email;

    private transient String password;

    private int width;

    private int height;


    public User() {

    }


    User(String name, String email, String password, int width, int height) {

        this.name = name;

        this.email = email;

        this.password = password;

        this.width = width;

        this.height = height;

    }


    public String getName() {

        return name;

    }


    public String getEmail() {

        return email;

    }


    public String getPassword() {

        return password;

    }


    public int getWidth() {

        return width;

    }


    public int getHeight() {

        return height;

    }


    @Override

    public boolean equals(Object o) {

        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        return Float.compare(user.width, width) == 0 &&

                Float.compare(user.height, height) == 0 &&

                Objects.equals(name, user.name) &&

                Objects.equals(email, user.email) &&

                Objects.equals(password, user.password);

    }


    @Override

    public int hashCode() {

        return Objects.hash(name, email, password, width, height);

    }


    @Override

    public String toString() {

        return "User{" +

                "name='" + name + '\'' +

                ", email='" + email + '\'' +

                ", password='" + password + '\'' +

                ", width=" + width +

                ", height=" + height +

                '}';

    }

}



查看完整回答
反对 回复 2023-11-10
  • 1 回答
  • 0 关注
  • 110 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信