programing

Jackson JSON 시리얼화, 레벨 정의에 의한 재귀 회피

fastcode 2023. 3. 6. 21:33
반응형

Jackson JSON 시리얼화, 레벨 정의에 의한 재귀 회피

는 잭슨 하여 나의 를 pojo 를 pojo로 연재한다.JSON B클래스 등이 .

class A {
  private int id;
  private B b;

  constructors...
  getters and setters
}

class B {
  private int ind;
  private A a;

  constructors...
  getters and setters
}

클래스 A에서 개체를 직렬화하는 경우 직렬화하는 동안 재귀가 발생할 수 있습니다. 수 걸 요.@JsonIgnore.

깊이 레벨에 따라 시리얼화를 제한할 수 있습니까?

예를 들어 레벨이 2인 경우 시리얼화는 다음과 같이 진행됩니다.

  • serialize a, level = 0 (0 < 2 ok) -> serialize
  • serialize a.b, level = 1 (1 <2 ok) -> serialize
  • a.b.a, 레벨 = 2 (2 < 2 not true ) -> stop

잘 부탁드립니다.

최근에 비슷한 문제가 발생했습니다.Jackson - 양방향 관계를 가진 엔티티의 직렬화(회피 주기)

따라서 Jackson 2.0으로 업그레이드하고 다음 주석을 클래스에 추가하는 것이 해결책입니다.

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...

이건 완벽하게 작동한다.

다음 링크를 체크하면 도움이 될 수 있습니다.

그 후 유일한 옵션은 오브젝트 타입의 시리얼화/디시리얼라이제이션용 커스텀모듈을 작성하는 것입니다.여기를 참조해 주세요.

안부 전해요.

수준 기반의 무식한 사람들에 대한 지지는 없다.

그러나 잭슨이 2.0을 사용하여 순환 참조를 처리하도록 할 수 있습니다. 예를 들어, 사용 방법에 대한 설명은 "Jackson 2.0 릴리스됨"을 참조하십시오.@JsonIdentityInfo.

자신을 한 수준(즉, 현재 객체의 자녀로 이동하지 않고)으로 제한하려면 @JsonView를 사용하는 간단한 솔루션이 있습니다.

다른 객체에 대한 링크인 각 필드에서 현재 클래스를 뷰로 하여 주석을 추가합니다.

class A {
  private int id;
  @JsonView(A.class) private B b;

  constructors...
  getters and setters
}

class B {
  private int ind;
  @JsonView(B.class) private A a;

  constructors...
  getters and setters
}

그런 다음 직렬화할 때 개체 클래스를 보기로 사용하십시오.A의 인스턴스를 직렬화하면 다음과 같이 렌더링됩니다.

{
  id: 42,
  b: {
    id: 813
  }
}

DEFAULT_VIEW_를 확인합니다.INCLUCTION이 true로 설정되어 있지 않으면 @JsonView 주석이 없는 필드는 렌더링되지 않습니다.또는 오브젝트 클래스 또는 일반적인 슈퍼 클래스를 사용하여 @JsonView를 사용하여 다른 모든 필드에 주석을 달 수 있습니다.

class A {
  @JsonView(Object.class) private int id;
  @JsonView(A.class) private B b;

  constructors...
  getters and setters
}

상세한 시리얼라이제이션에 대해서는, 다음의 예를 참조해 주세요.

경우에 따라 최대 깊이를 유지하는 스레드 로컬 정수를 사용하여 일련화 깊이를 제한할 수 있습니다. 답을 보세요.

수개월간의 많은 조사 끝에, 저는 제 영역을 잭슨 의존으로부터 보호하기 위해 저만의 솔루션을 구현했습니다.

public class Parent {
    private Child child;
    public Child getChild(){return child;} 
    public void setChild(Child child){this.child=child;}
}

public class Child {
    private Parent parent;
    public Child getParent(){return parent;} 
    public void setParent(Parent parent){this.parent=parent;}
}

먼저 다음과 같이 쌍방향 관계의 각 엔티티를 선언해야 합니다.

public interface BidirectionalDefinition {

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Parent.class)
    public interface ParentDef{};

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Child.class)
    public interface ChildDef{};

}

그 후 오브젝트매퍼를 자동으로 설정할 수 있습니다.

ObjectMapper om = new ObjectMapper();
Class<?>[] definitions = BidirectionalDefinition.class.getDeclaredClasses();
for (Class<?> definition : definitions) {
    om.addMixInAnnotations(definition.getAnnotation(JsonIdentityInfo.class).scope(), definition);
}

언급URL : https://stackoverflow.com/questions/10191671/jackson-json-serialization-recursion-avoidance-by-level-defining

반응형