Сериализация / десериализация псевдонимов в Джексоне без лишних шаблонов - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть класс, который я хочу преобразовать в Java в класс. Один из атрибутов класса сам по себе является сериализуемым классом, который имеет один параметр примитива (String) и действительно представляет строку с псевдонимом, то есть строку с некоторыми дополнительными элементами, чтобы убедиться, что он имеет правильный формат. Это полезно в различных приложениях (например, идентификаторах), в данном случае это строка Cron, которая должна иметь конкретное представление c. Итак, у меня есть

class ScheduleConfigurations {
    private Cron cron;
    private Set<Cron> overrides;
    // other attributes, getters/setters, constructor
}


class Cron {
    private String cronString;

    private void validate() { // validates string has correct representation }
    // getters, setters, constructor
}

Очевидно, что стандартный десериализатор Джексона ожидает JSON в формате

{
    "cron": {
        "cronString": "someCronString",
    "overrides": [
        { "cronString": "someCronString1" },
        { "cronString": "someCronString2" }
    ]
}

Однако класс Cron явно является псевдонимом String. Я бы хотел, чтобы вышеперечисленное было сериализовано / десериализовано как

{
    "cron": "someCronString",
    "overrides": ["someCronString1", "someCronString2"]
}

. Я могу добиться этого с помощью специального сериализатора с кучей шаблонов, но я ищу элегантный способ сказать Джексону: «эй у этого класса есть один атрибут String, просто пропустите его и обработайте его сериализованное представление как единственный атрибут ".

1 Ответ

1 голос
/ 05 февраля 2020

Поскольку вы хотите, чтобы весь объект был (де) сериализован в виде строки, это очень просто:

@JsonSerialize(using = ToStringSerializer.class)
class Cron {
    private String cronString;
    public Cron(String cronString) { // Called by Jackson when deserializing from JSON string
        this.cronString = cronString;
    }
    @Override
    public String toString() { // Called by Jackson when serializing to JSON
        return this.cronString;
    }
}

Поскольку класс является просто оболочкой для строки, вам даже не нужен метод getter , сеттер или другой конструктор, даже для другого Java кода, хотя вы, конечно, можете его иметь.

Test

ScheduleConfigurations configObj = new ScheduleConfigurations();
configObj.setCron(new Cron("someCronString"));
configObj.setOverrides(new LinkedHashSet<>(Arrays.asList(
        new Cron("someCronString1"), new Cron("someCronString2"))));
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(configObj));
String json = "{\r\n" + 
              "  \"cron\" : \"someCronString\",\r\n" + 
              "  \"overrides\" : [ \"someCronString1\", \"someCronString2\" ]\r\n" + 
              "}";
ScheduleConfigurations configObj = new ObjectMapper().readValue(json, ScheduleConfigurations.class);
System.out.println("cron = " + configObj.getCron());
System.out.println("overrides = " + configObj.getOverrides());

Выход

{
  "cron" : "someCronString",
  "overrides" : [ "someCronString1", "someCronString2" ]
}
cron = someCronString
overrides = [someCronString1, someCronString2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...