9

JSONのシリアル化/逆シリアル化にJackson(2.1.1)を使用しています。JAXBアノテーションを持つ既存のクラスがあります。これらの注釈のほとんどは正しく、jacksonでそのまま使用できます。これらのクラスの逆シリアル化/シリアル化をわずかに変更するために、ミックスインを使用しています。

ObjectMapperコンストラクターでは、次のことを行います。

setAnnotationIntrospector(AnnotationIntrospector.pair(
                 new JacksonAnnotationIntrospector(), 
                 new JaxbAnnotationIntrospector(getTypeFactory())));

上記に基づいて、イントロスペクターの順序により、JacksonアノテーションはJaxbよりも優先されます。これは、JacksonJaxbのドキュメントに基づいています。無視したいフィールドの場合@JsonIgnore、ミックスインのフィールドへの追加は正常に機能しています。@XmlTransient無視したくない既存のクラスのようにマークされているフィールドがいくつかあります。ミックスインのフィールドに追加しようと@JsonPropertyしましたが、機能しないようです。

元のクラスは次のとおりです。

public class Foo {
    @XmlTransient public String getBar() {...}
    public String getBaz() {...}
}

ミックスインは次のとおりです。

public interface FooMixIn {
    @JsonIgnore String getBaz(); //ignore the baz property
    @JsonProperty String getBar(); //override @XmlTransient with @JsonProperty
}

元のクラスを変更せずにこれを解決する方法はありますか?

また、ミックスインを使用する代わりに、@JsonPropertyをメンバーに追加することもテストしました。

public class Foo {
    @JsonProperty @XmlTransient public String getBar() {...}
    @JsonIgnore public String getBaz() {...}
}

ミックスインで行ったのと同じ動作をするようです。@XmlTransientが削除されない限り、プロパティは無視されます。

4

1 に答える 1

9

問題は、いずれかのイントロスペクターが無視マーカーを検出した場合、AnnotationIntrospectorPair.hasIgnoreMarker()メソッドが基本的に無視することです。@JsonProperty

    public boolean hasIgnoreMarker(AnnotatedMember m) {
        return _primary.hasIgnoreMarker(m) || _secondary.hasIgnoreMarker(m);
    }

参照:github

回避策は、をサブクラス化しJaxbAnnotationIntrospectorて、目的の動作を取得することです。

public class CustomJaxbAnnotationIntrospector extends JaxbAnnotationIntrospector {
    public CustomJaxbAnnotationIntrospector(TypeFactory typeFactory) {
        super(typeFactory);
    }

    @Override
    public boolean hasIgnoreMarker(AnnotatedMember m) {
        if ( m.hasAnnotation(JsonProperty.class) ) {
            return false;
        } else {
            return super.hasIgnoreMarker(m);
        }
    }
}

次に、でを使用しCustomJaxbAnnotationIntrospectorますAnnotationIntrospectorPair

于 2013-01-04T22:06:19.070 に答える