programing

Jackson Json Ignore를 동적으로 변경

javajsp 2023. 3. 20. 21:28

Jackson Json Ignore를 동적으로 변경

저는 클래스가 있고 그 안에 변수도 있습니다.일부 필드를 무시하고 싶을 때도 있고 역직렬화할 때도 없습니다(시리얼라이즈에서도 마찬가지일 수 있습니다.잭슨에서 어떻게 해요?

시리얼라이제이션의 경우는, 「프로퍼티 필터링」블로그 엔트리가 도움이 됩니다.기술된 내용을 필터링하는 것이 일반적이기 때문에 역직렬화 쪽은 지원이 적습니다.

가능한 접근법 중 하나는 서브클래스를JacksonAnnotationIntrospector메서드(및/또는 필드)의 자기무시성이라는 메서드를 덮어쓰고 원하는 로직을 사용합니다.

또한 실제 적용 사례, 즉 무엇을, 왜 역직렬화를 방지하려고 하는지 예를 들면 도움이 될 수 있습니다.

JsonViews를 사용하는 것이 좋습니다(원래는 http://wiki.fasterxml.com/JacksonJsonViews에서 가져온 것입니다.- broken now - web archive link : https://web.archive.org/web/20170831135842/http : //wiki.fasterxml.com/JacksonJsonViews )

인용:

첫째, 뷰를 정의하는 것은 클래스를 선언하는 것을 의미합니다.기존 클래스를 재사용하거나 가짜 클래스를 만들 수 있습니다.이러한 클래스는 관계 정보가 있는 뷰 식별자에 불과합니다(자녀가 부모로부터 뷰 멤버쉽을 상속받습니다).

 // View definitions:
  class Views {
            static class Public { }
            static class ExtendedPublic extends PublicView { }
            static class Internal extends ExtendedPublicView { }
  }

  public class Bean {
            // Name is public
            @JsonView(Views.Public.class) String name;
            // Address semi-public
            @JsonView(Views.ExtendPublic.class) Address address;
            // SSN only for internal usage
            @JsonView(Views.Internal.class) SocialSecNumber ssn;
  }

이러한 뷰 정의를 사용하면 시리얼화는 다음과 같이 이루어집니다.

 // short-cut:
  objectMapper.writeValueUsingView(out, beanInstance, ViewsPublic.class);

  // or fully exploded:
  objectMapper.getSerializationConfig().setSerializationView(Views.Public.class);
  // (note: can also pre-construct config object with 'mapper.copySerializationConfig'; reuse)
  objectMapper.writeValue(out, beanInstance); // will use active view set via Config

  // or, starting with 1.5, more convenient (ObjectWriter is reusable too)
  objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);
and result would only contain 'name', not 'address' or 'ssn'.

Jackson 최신 버전의 모듈 기능을 살펴봐야 합니다.

가능한 메커니즘 중 하나는 BeanDeserializer Modifier를 사용하는 것입니다.

도움이 되는 온라인 튜토리얼이나 예를 찾고 있습니다만, 곧바로 아무것도 표시되지 않습니다.당신의 상황에 대해 더 많이 알고 있다면 뭔가 해결할 수 있을지도 모릅니다.관리 중입니까?ObjectMapper또는 스프링에 주입된 JAX-RS 설정에서 사용하는가?

나는 답을 찾기 위해 전체 웹을 검색했다(그렇다).제가 직접 쓴 게 있어요

난 잭슨 이온 탈직렬화 작업을 하고 있어필드를 동적으로 무시하는 커스텀 리더를 작성했습니다.

json 역직렬화에도 같은 작업을 수행할 수 있습니다.

이와 같은 실체를 가정해 봅시다.

User {
    id
    name
    address {
       city
    }
}

필드 선택을 나타내는 트리 구조를 만듭니다.

public class IonField {

    private final String name;
    private final IonField parent;
    private final Set<IonField> fields = new HashSet<>();

    // add constructs and stuff
}

커스텀 이온 리더는 https://github.com/amzn/ion-java에서 amazon 이온 리더로 확장되었습니다.

public class IonReaderBinaryUserXSelective extends IonReaderBinaryUserX {

    private IonField _current;
    private int hierarchy = 0;

    public IonReaderBinaryUserXSelective(byte[] data, int offset, int length,
                                         IonSystem system, IonField _current) {
        super(system, system.getCatalog(), UnifiedInputStreamX.makeStream(data, offset, length));
        this._current = _current;
    }

    @Override
    public IonType next() {
        IonType type = super.next();

        if (type == null) {
            return null;
        }

        String file_name = getFieldName();

        if (file_name == null || SystemSymbols.SYMBOLS.equals(file_name)) {
            return type;
        }

        if (type == IonType.STRUCT || type == IonType.LIST) {
            IonField field = _current.getField(getFieldName());
            if (field != null) {
                this._current = field;
                return type;
            } else {
                super.stepIn();
                super.stepOut();
            }
            return next();
        } else {
            if (this._current.contains(file_name)) {
                return type;
            } else {
                return next();
            }
        }
    }

    @Override
    public void stepIn() {
        hierarchy = (hierarchy << 1);
        if (getFieldName() != null && !SystemSymbols.SYMBOLS.equals(getFieldName())) {
            hierarchy = hierarchy + 1;
        }
        super.stepIn();
    }

    @Override
    public void stepOut() {
        if ((hierarchy & 1) == 1) {
            this._current = this._current.getParent();
        }
        hierarchy = hierarchy >> 1;
        super.stepOut();
    }

동적 뷰를 구성합니다.이 트리는 동적으로 생성되어 리더에게 전달되어 역직렬화됩니다.

주소 안에 도시만 있으면 된다고 칩시다.

IonField root = new IonField("user", null);

IonField address = new IonField("address", root);
IonField city = new IonField("city", address);
address.addChild(city);

root.addChild(id);


//now usual stuff.

IonFactory ionFactory = new IonFactory();
IonObjectMapper mapper = new IonObjectMapper(ionFactory);

File file = new File("file.bin"); // ion bytes

byte[] ionData =  Files.readAllBytes(file.toPath());

IonSystem ionSystem = IonSystemBuilder.standard().build();
IonReader ionReader = new IonReaderBinaryUserXSelective(ionData, 0, ionData.length, ionSystem, root);

User user = mapper.readValue(ionReader, User.class);

언급URL : https://stackoverflow.com/questions/8179986/jackson-change-jsonignore-dynamically