Джексон 2: игнорировать переходные поля только при сериализации - PullRequest
0 голосов
/ 19 октября 2019

Я использую Jackson v2 в приложении JAX-RS и пытаюсь выяснить, можно ли настроить «ObjectMapper» для удаления полей с модификатором переходных процессов, но только во время сериализации.

Вот DTO, чтобы проиллюстрировать мой вариант использования (геттеры и сеттеры опущены)

public class User {
    private String email;
    private transient String password;
}

Имея в виду вышеупомянутый DTO, я хотел бы иметь объектный преобразователь, который сбрасывает поле пароля при сериализации и включает егово время десериализации.

Единственное, что я смог найти в отношении переходного процесса, это:

MapperFeature.PROPAGATE_TRANSIENT_MARKER

Но этот конфиг не соответствует моим требованиям.

PS - Нет комментариевдля использования, так как DTO не должны быть связаны с какой-либо библиотекой, плюс я не обязательно контролирую их.

1 Ответ

1 голос
/ 19 октября 2019

Не знаю, похоже transient модификатор атрибута плюс PROPAGATE_TRANSIENT_MARKER просто делает это. Десериализация прямолинейна. Тем не менее, во время сериализации наблюдается суета с переходным маркером . Вы должны предоставить геттеры для полей, иначе вы застрянете с исключением «Нераспознанное поле ... не помечено как игнорируемое».

Реакция на дополнительные требования Я добавил версию, используя миксины Джексона. Обратите внимание, что версия 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

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 +
                '}';
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...