Джексон: Как изменить существующее свойство до JSON, не изменяя POJO? - PullRequest
1 голос
/ 28 мая 2020

Мне нужно отредактировать имя «существующего поля» в POJO вместо добавления «extra_field». Возможно ли это с помощью ссылки, указанной ниже?

Обратите внимание, что я не хочу использовать аннотацию @JsonProperty.

Требование: у меня есть POJO, и я хочу использовать разные имена полей каждый время без изменений в POJO. Например, у меня есть поле c_id в POJO, и иногда его нужно писать как cust_id, а в другой раз это будет my_id.

Также обратите внимание, что я не могу изменить реализацию POJO, поскольку она уже есть используется в нескольких модулях и имеет общую реализацию c.

POJO Пример:

class MyPojo {
    String id; 
    // getter and setters
}

Ожидаемый результат может быть следующим: (имя поля можно изменить)

  1. {" cust_id ":" 123 "}
  2. {" my_id ":" 123 "}

1 Ответ

2 голосов
/ 28 мая 2020

Mixins

Самый простой способ изменить вывод Jackson без добавления аннотаций к исходному POJO - использовать миксины.

Просто определите класс mixin с необходимые аннотации и укажите Джексону, что вы хотите использовать миксин при сериализации исходного объекта.

private static class MyPojoMixin {
    @JsonProperty("cust_id")
    private String id;
}

public String serializeWithMixin(MyPojo p) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.addMixIn(MyPojo.class, MyPojoMixin.class);

    return mapper.writeValueAsString(p);
}

Стратегия именования настраиваемых свойств

Если вам нужно программно изменить имя поля, возможно, вы не сможете использовать раствор миксина. Затем вы можете использовать настраиваемую PropertyNamingStrategy:

public class IdRenamingStrategy extends PropertyNamingStrategy {
    private final PropertyNamingStrategy inner;
    private final String newIdPropertyName;

    public IdRenamingStrategy(String newIdPropertyName) {
        this(PropertyNamingStrategy.LOWER_CAMEL_CASE, newIdPropertyName);
    }

    public IdRenamingStrategy(PropertyNamingStrategy inner, String newIdPropertyName) {
        this.inner = inner;
        this.newIdPropertyName = newIdPropertyName;
    }

    private String translate(String propertyName) {
        if ("id".equals(propertyName)) {
            return newIdPropertyName;
        } else {
            return propertyName;
        }
    }

    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return inner.nameForField(config, field, translate(defaultName));
    }

    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return inner.nameForGetterMethod(config, method, translate(defaultName));
    }

    @Override
    public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return inner.nameForSetterMethod(config, method, translate(defaultName));
    }

    @Override
    public String nameForConstructorParameter(MapperConfig<?> config, AnnotatedParameter ctorParam, String defaultName) {
        return inner.nameForConstructorParameter(config, ctorParam, translate(defaultName));
    }
}

Это можно использовать следующим образом:

public String serializeWithPropertyNamingStrategy(MyPojo p) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(new IdRenamingStrategy("cust_id"));

    return mapper.writeValueAsString(p));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...