ジャクソンConstructorPropertiesは、プロパティ名を無視します

yanefedor:

ジャクソン(2.9.6バージョン)がどのように私は本当に混乱していObjectMapperて動作します@ConstructorProperties注釈。

マッパが中に存在しているプロパティ名は無視されているようです@ConstructorProperties注釈値法を。

さらに興味深いものだ - マッパーは関係なく、プロパティ名の正しく動作します。

私は何をについて話していますか?

のは、カスタムXmlMapperを考えてみましょう:

private static final ObjectMapper XML_MAPPER = new XmlMapper()
            .setAnnotationIntrospector(
                    AnnotationIntrospector.pair(
                            new JaxbAnnotationIntrospector(),
                            new JacksonAnnotationIntrospector()
                    )
            )
            .registerModule(new JavaTimeModule())
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            .setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE);

そして、単純なデータ転送オブジェクト(DTO):

    @XmlRootElement(name = "person")
    @XmlAccessorType(XmlAccessType.NONE)
    static class Person {
        @XmlAttribute
        final int age;

        @XmlAttribute
        final String name;

        @XmlAttribute
        final LocalDate dateOfBirth;

        @ConstructorProperties({"age","name","dateOfBirth"})
        public Person(int age, String name, LocalDate dateOfBirth) {
            this.age = age;
            this.name = name;
            this.dateOfBirth = dateOfBirth;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    ", dateOfBirth=" + dateOfBirth +
                    '}';
        }
    }

私は、問題を再現するために、テストを作成しました:

@Test
@DisplayName("Check xml deseralization for Person class")
void deserialization() throws IOException {
    String xml = "<person age=\"26\" name=\"Fred\" date-of-birth=\"1991-11-07\"/>";
    Person person = XML_MAPPER.readValue(xml, Person.class);
    Assertions.assertEquals("Person{age=26, name='Fred', dateOfBirth=1991-11-07}", person.toString());
}

テストは関係なく、渡された理由は、私にとっては奇妙だ@ConstructorProperties注釈。アノテーションで渡されたテスト

        @ConstructorProperties({"a","b","c"})
        public Person(int age, String name, LocalDate dateOfBirth) {
            this.age = age;
            this.name = name;
            this.dateOfBirth = dateOfBirth;
        }

それは魔法のですか?どのようにジャクソンはこの注釈を処理しますか?ConstructorPropertiesへジャクソンの注釈で同等とは何ですか?

Teppic:

ので、それは合格だJaxbAnnotationIntrospectorからプロパティ名を決定することができます@XmlAttribute注釈を。

上のドキュメントはAnnotationIntrospectorPair言います:

1つのイントロスペクタを使用する一次として作用するよう2 introspectorsを使用可能にするヘルパークラス。プライマリ方法に決定的または有用な結果を提供しない場合、フォールバックとしての第2のものを用います。

JacksonAnnotationIntrospector(理解した@ConstructorPropertiesアノテーション)を全く使用されていません。

あなたはすべてを削除するとJAXBは、正しい名前が指定されている場合、あなたのテストにのみ合格する注釈します@ConstructorProperties

あなたはそれを「ジャクソンの道」を実行する場合は、JAXB注釈を削除し、JaxbAnnotationIntrospector完全に(だけにコールをドロップしsetAnnotationIntrospector、マッパーは使用がデフォルトになりますJacksonAnnotationIntrospector)を。

デシリアライゼーションは動作しますが、あなたが同じ直列化されたフォームを達成する必要がある場合は、いくつかのジャクソンネイティブ注釈を追加する必要があります:

@JacksonXmlRootElement(localName = "person")
static class Person {
    @JacksonXmlProperty(isAttribute = true)
    final int age;

    @JacksonXmlProperty(isAttribute = true)
    final String name;

    @JacksonXmlProperty(isAttribute = true)
    final LocalDate dateOfBirth;

    @ConstructorProperties({"age", "name", "dateOfBirth"})
    public Person(int age, String name, LocalDate dateOfBirth) {
        this.age = age;
        this.name = name;
        this.dateOfBirth = dateOfBirth;
    }

    //...

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=218770&siteId=1