私は、Instance
という名前の抽象クラスと、その2つの実装、UserInstance
とHardwareInstance
を持っています。私が抱えている問題は、@POST
の残りのエンドポイントをデータベースに呼び出すときに、インスタンスがRESTエンドポイントに渡される.../rest/soexample/instance/create
のようにすることです。理想的にはInstance
がなかった場合2つ以上の実装で抽象化することはできませんが、2つあるため、Jackson.databind
エラーが発生します。
"問題:抽象型は具象型にマップするか、カスタムデシリアライザーを使用するか、追加の型情報でインスタンス化する必要があります"
これの解決策を調べた後、私はSOの答えを見つけました。
@JsonDeserialize(as=UserInstance.class)
しかし、それは抽象クラスの実装が1つある場合にのみ役立つようです。それがどのタイプのインスタンスになるかを決定する方法がないため、私はそれを2回呼び出すことができないと仮定します。
だから私はこの状況を処理するための最良の方法は何だと思いますか?異なるエンドポイントを作成する必要がありますか?お気に入り:
.../rest/soexample/userinstance/create
&.../rest/soexample/hardwareinstance/create
@ REST関連するものですが、積極的に学びたいと思っています。ありがとう!
これは私があなたの同じケースでしたことです:
_@JsonDeserialize(using = InstanceDeserializer.class)
public abstract class Instance {
//.. methods
}
@JsonDeserialize(as = UserInstance.class)
public class UserInstance extends Instance {
//.. methods
}
@JsonDeserialize(as = HardwareInstance.class)
public class HardwareInstance extends Instance {
//.. methods
}
public class InstanceDeserializer extends JsonDeserializer<Instance> {
@Override
public Instance deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
ObjectNode root = (ObjectNode) mapper.readTree(jp);
Class<? extends Instance> instanceClass = null;
if(checkConditionsForUserInstance()) {
instanceClass = UserInstance.class;
} else {
instanceClass = HardwareInstance.class;
}
if (instanceClass == null){
return null;
}
return mapper.readValue(root, instanceClass );
}
}
_
Instance
に@JsonDeserialize(using = InstanceDeserializer.class)
の注釈を付けて、抽象クラスの逆シリアル化に使用されるクラスを示します。次に、各子クラスがas
自体を逆シリアル化することを示す必要があります。それ以外の場合は、親クラスのデシリアライザを使用してStackOverflowError
を取得します。
最後に、InstanceDeserializer
の内部で、逆シリアル化するロジックを1つまたは別の子クラス(たとえば、checkConditionsForUserInstance()
)に配置します。