ジャクソン(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へジャクソンの注釈で同等とは何ですか?
ので、それは合格だ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;
}
//...