Миксин Джексона: как игнорировать или переименовывать поля из класса в виде дерева

Я пытаюсь выполнить глубокую фильтрацию (переименовать/игнорировать поля) из класса, представленного в виде дерева.

С помощью Jackson Mixin я могу переименовывать или игнорировать поля с корневого уровня. Чего я хочу добиться, так это того, как выполнять фильтрацию (переименовывать/игнорировать) на нескольких уровнях?

Например, у меня есть дерево с двумя классами. Класс A — корень, B — второй уровень глубины дерева. Применяя Jackson Mxiin, я хочу отфильтровать свойство a2 из корня A и свойство b1 из B.

Класс A, представляющий корневой класс

public class A {
  private String a1;
  private String a2;
  private B b;

  public A(String a1, String a2, B b) {
      this.a1 = a1;
      this.a2 = a2;
      this.b = b;
  }

  public String getA1() {
      return a1;
  }

  public void setA1(String a1) {
      this.a1 = a1;
  }

  public String getA2() {
      return a2;
  }

  public void setA2(String a2) {
      this.a2 = a2;
  }

  public B getB() {
      return b;
  }

  public void setB(B b) {
      this.b = b;
  }

}

Класс B — глубина второго уровня

public class B {

      private String b1;
      private String b2;

      public B(String b2, String b1) {
          this.b1 = b1;
          this.b2 = b2;
      }

      public String getB1() {
          return b1;
      }

      public void setB1(String b1) {
          this.b1 = b1;
      }

      public String getB2() {
          return b2;
      }

      public void setB2(String b2) {
          this.b2 = b2;
      }
    }

Фильтры

public interface AMixIn {
  // Filter for A (implemented to filter second depth as well)
  @JsonIgnore
  String getA2();

  @JsonIgnore
  public BMixIn getB();
}

public interface BMixIn {
  // Filter for B
  @JsonIgnore
  public String getB1();

}

Тест

public class SecondLevelTest {
  // Test
  private ObjectMapper mapper = null;
  private ObjectWriter writer = null;

  @Before
  public void setUp() {
      // init
      mapper = new ObjectMapper();
      mapper.setMixIns(ImmutableMap.<Class<?>, Class<?>>of(A.class, AMixIn.class));
      writer = mapper.writer().with(SerializationFeature.INDENT_OUTPUT);
  }

  @Test
  public void rename_field_jackson() throws JsonProcessingException {

      B b = new B("vb1", "vb2");
      A a = new A("va1", "va2", b);

      // I want to get this result
      // {
      // "a1" : "va1",
      // "b2" : "vb2"
      // }
      String json = writer.writeValueAsString(a);
      System.out.println(json);
  }
}

person Ster-BigData    schedule 20.12.2018    source источник
comment
Я думаю, вы ищете JsonUnwrapped. Он должен быть на getB(), а не в игноре.   -  person David Ehrmann    schedule 20.12.2018
comment
Я не понимаю, пожалуйста, можете объяснить? Может быть, вы можете поделиться, как это реализовать!   -  person Ster-BigData    schedule 20.12.2018


Ответы (1)


Это должно дать вам результат, который вы ищете. Измените свой setUp(), чтобы также использовать BMixIn:

@Before
public void setUp() {
    // init
    mapper = new ObjectMapper();
    mapper.setMixIns(ImmutableMap.of(A.class, AMixIn.class, B.class, BMixIn.class));
    writer = mapper.writer().with(SerializationFeature.INDENT_OUTPUT);
}

И измените AMixIn на разворачивание B

public interface AMixIn {
    // Filter for A (implemented to filter second depth as well)
    @JsonIgnore
    String getA2();

    @JsonUnwrapped
    public BMixIn getB();
}

Если вы забыли зарегистрировать BMixIn, его @JsonIgnore никогда не использовалось. @JsonUnwrapped раскрывает гнезда b, поэтому вы получаете плоскую структуру.

person David Ehrmann    schedule 20.12.2018