私はしばらくの間、プロジェクトで FasterXML/Jackson-Databind を使用してきましたが、この投稿を発見し、このアプローチを使用して @JsonProperty アノテーションなしでオブジェクトを逆シリアル化するまで、すべてがうまく機能していました。
問題は、複数のパラメーターを取り、このコンストラクターを @JsonCreator アノテーションで装飾するコンストラクターがある場合、Jackson が次のエラーをスローすることです。
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:
Argument #0 of constructor [constructor for com.eliti.model.Cruiser, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at [Source: {
"class" : "com.eliti.model.Cruiser",
"inventor" : "afoaisf",
"type" : "MeansTransport",
"capacity" : 123,
"maxSpeed" : 100
}; line: 1, column: 1]
問題を説明するために小さなプロジェクトを作成しました。逆シリアル化しようとしているクラスは次のとおりです。
public class Cruise extends WaterVehicle {
private Integer maxSpeed;
@JsonCreator
public Cruise(String name, Integer maxSpeed) {
super(name);
System.out.println("Cruise.Cruise");
this.maxSpeed = maxSpeed;
}
public Integer getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(Integer maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
デシリアライズするコードは次のようになります。
public class Test {
public static void main(String[] args) throws IOException {
Cruise cruise = new Cruise("asd", 100);
cruise.setMaxSpeed(100);
cruise.setCapacity(123);
cruise.setInventor("afoaisf");
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES));
String cruiseJson = mapper.writeValueAsString(cruise);
System.out.println(cruiseJson);
System.out.println(mapper.readValue(cruiseJson, Cruise.class));
}
すでに @JsonCreator を削除しようとしましたが、削除すると、次の例外がスローされます。
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.eliti.model.Cruise: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: {
"class" : "com.eliti.model.Cruise",
"inventor" : "afoaisf",
"type" : "MeansTransport",
"capacity" : 123,
"maxSpeed" : 100
}; line: 3, column: 3]
「mvn clean install」を実行しようとしましたが、問題が解決しません。
いくつかの追加情報を含めるために、この問題について徹底的に調査しました (GitHub の問題、ブログ投稿、StackOverflow Q&A)。私が最後に行ったデバッグ/調査は次のとおりです。
調査1
生成されたバイトコードでjavap -vを実行すると、次のようになります。
MethodParameters:
Name Flags
name
maxSpeed
コンストラクターについて話すとき、-parametersフラグが本当に javac コンパイラー用に設定されていると思います。
調査2
単一のパラメーターを持つコンストラクターを作成すると、オブジェクトは初期化されますが、複数のパラメーターのコンストラクターを使用したい/使用する必要があります。
調査3
各フィールドで注釈 @JsonProperty を使用しても同様に機能しますが、元のプロジェクトでは、コンストラクターに多くのフィールドがあるため、オーバーヘッドが大きすぎます (また、注釈を使用してコードをリファクタリングするのが非常に難しくなります)。
残っている問題は 、Jackson を注釈なしで複数のパラメーター コンストラクターと連携させるにはどうすればよいかということです。