Удалите дубликаты ключей в json, которые вызваны @JsonUnwrapped - RestController - PullRequest
1 голос
/ 04 марта 2020

У меня есть POJO, который содержит другой POJO:

public class Outer {

    private Long id;
    private String name;

    @JsonUnwrapped
    private Inner inner;

}

И это Внутренний класс:

public class Inner {

    private Long id;
    private String name;
    private String feature;

}

Как видите, оба эти объекта могут иметь идентификатор и имя, так как в то время как я использовал @JsonUnwrapped, могут быть некоторые дублированные ключи. У меня есть контроллер покоя:

@RestController
public class Temp {

    @RequestMapping("/test")
    public Outer test() {
        Inner inner = new Inner(null, "innerName", "feature");
        Outer outer = new Outer(10L, "outerName", inner);
        return outer;
    }

}

Каждый раз, когда я вызываю метод, результат будет таким: {"id":1, name:"outerName", id: null, name:"innerName","feature":"feature"}

Я хочу получить этот результат:

{"id":1, name:"innerName","feature":"feature"}

Я имею в виду, что всякий раз, когда у внутреннего объекта есть значение для дублирующего ключа, значение должно быть взято из внутреннего объекта, и если значение было равно нулю для дублирующего ключа внутри внутреннего класса, значение должен быть взят из внешнего объекта.

Ответы [ 4 ]

0 голосов
/ 04 марта 2020

Попробуйте с этим ниже pojo. Я думаю, что ваша проблема будет решена.

public class Outer {

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Long id;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String name;
    @JsonUnwrapped
    private Inner inner;
}

public class Inner {

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Long id;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String name;
    private String feature;
}
0 голосов
/ 04 марта 2020

Вы можете сделать это как:

public class Outer {
    private Long id;
    private String name;

    @JsonUnwrapped
    @JsonIgnoreProperties({"id", "name"})
    private Inner inner;
}
0 голосов
/ 04 марта 2020

Когда вы используете @JsonUnwrapped, Inner покроет Outer тех же клавиш.

Так что этого не произойдет {"id":1, name:"outerName", "id": null, "name":"innerName","feature":"feature"}, {"id": null, "name":"innerName","feature":"feature"} верно

В этом случай , мы хотим получить {"id": 1, "name":"innerName","feature":"feature"}

Inner необходимо изменить

  public class Inner {

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Long id;
    private String name;
    private String feature;

}

@JsonInclude(JsonInclude.Include.NON_NULL) может игнорировать нулевое значение. Для достижения использования Outer id .

0 голосов
/ 04 марта 2020

Если эта структура класса требуется для бизнес-логики c, то я бы предложил иметь отдельный класс для сериализации (что, как правило, хорошая идея в любом случае).

public class OuterJson {

   private Long id;
   private String name;
   private String feature;

   public OuterJson(Long id, String name, String feature) {
       // assign fields
   }

   // Getters
}

// In Utillity class or as a method in Outer
public OuterJson convertToJson(Outer outer) {
    Inner inner = outer.getInner();

    return new OuterJson(
      inner == null || inner.getId() == null ? outer.getId() : inner.getId(),
      inner == null || inner.getName() == null ? outer.getName() : inner.getName(),
      inner == null ? null : inner.getFeature()
    );
}

РЕДАКТИРОВАТЬ: I Я не эксперт по Джексону, но я не думаю, что это возможно только с помощью аннотаций Джексона. Существуют библиотеки, такие как MapStruct, которые могут упростить подобные операции. Я считаю, что он также должен иметь возможность делать то, что вам нужно.


Альтернативой может быть добавление методов-получателей, реализующих логи c:

public class Outer {
    @JsonIgnore
    private Long id;

    @JsonIgnore
    private String name;

    @JsonIgnore
    private Inner inner;

    @JsonProperty("id")
    public int getJsonId() {
       return inner == null || inner.getId() == null ? id : inner.getId();
    }
}
...