Могу ли я попросить Джексона условно сериализовать частную переменную экземпляра на основе метода с другим типом? - PullRequest
0 голосов
/ 31 мая 2018

Насколько я понимаю, Джексон

  • сериализует переменную общего экземпляра с именем переменной

    public List<String> myStrings = new ArrayList<>();

    сериализует в

    { 'myStrings' : [ ... ] }

  • сериализует переменную частного экземпляра в имя переменной, если у нее есть открытый метод получения с именем getVariable():

    private List<String> myStrings = new ArrayList<>();
    public List<String> getMyStrings() { return myStrings; }
    

    сериализует аналогично

    { 'myStrings' : [ ... ] }


Однако я пытаюсь добиться сериализации в строку (вместо массива строк)по другому методу, но сохраняйте ключ JSON (в некоторых случаях @JsonInclude(JsonInclude.Include.NON_NULL) подавляет оригинальный метод доступа

    @JsonInclude(JsonInclude.Include.NON_NULL)

    private boolean firstStringOnly = true;
    private List<String> myStrings = new ArrayList<>();
    public List<String> getMyStrings() { return firstStringOnly ? null: myStrings; }
    public String getFirstString() { return firstStringOnly ? myStrings.get(0) : null; } 

Требуемая сериализация JSON:

  • Для firstStringOnly==true: { 'myStrings' : 'first_String' } (используя getFirstString())

  • Для firstStringOnly==false: { 'myStrings' : [ ... ] } (используя getMyStrings())

Isэто возможно сделать? Я специально стараюсь не использовать пользовательские сериализаторы и делать это только с помощью аннотаций.nd Java 8.

Просто повторяем, ограничения вопроса:

* НЕТ пользовательского сериализатора

* В обоих случаях использования один и тот же ключ JSON

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Вы можете обобщить метод getMyStrings () и заставить его возвращать Object.А внутри проверьте флаг и верните первое значение или все значения.Вот мой образец

public class tst {
private static class YourObject {

    private boolean firstStringOnly;
    private List<String> myStrings = new ArrayList<>();

    public YourObject(boolean firstStringOnly) {
        this.firstStringOnly = firstStringOnly;
        this.myStrings.add("str1");
        this.myStrings.add("str2");
    }
    public Object getMyStrings(){
        return firstStringOnly ? myStrings.get(0) : myStrings;
    }

}

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(new YourObject(true)));
        System.out.println(mapper.writeValueAsString(new YourObject(false)));
    }
}

Выход

{"myStrings":"str1"}
{"myStrings":["str1","str2"]}
0 голосов
/ 31 мая 2018

РЕДАКТИРОВАТЬ: Извините, я неправильно прочитал ваш первоначальный вопрос.Я предполагаю, что вы хотите оставить оба набранных получателя.Будет ли это работать для вас?

public class TestClass {

  private boolean firstStringOnly = true;
  private List<String> myStrings = new ArrayList<>();

  @JsonIgnore
  public boolean isFirstStringOnly() {
    return firstStringOnly;
  }

  public void setFirstStringOnly(boolean firstStringOnly) {
    this.firstStringOnly = firstStringOnly;
  }

  @JsonIgnore
  public List<String> getMyStrings() {
    return firstStringOnly ? null : myStrings;
  }

  @JsonIgnore
  public String getFirstString() { return firstStringOnly ? myStrings.get(0) : null; }

  @JsonProperty("myStrings")
  public Object getMyStringsForSerialization() {
    return firstStringOnly ? getFirstString() : getMyStrings();
  }

  public void setMyStrings(List<String> myStrings) {
    this.myStrings = myStrings;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...