1. ホーム
  2. java

[解決済み] ジャクソンと汎用型リファレンス

2022-06-19 02:31:53

質問

以下のような汎用的なメソッドにjackson json libraryを使用したい。

public MyRequest<T> tester() {
    TypeReference<MyWrapper<T>> typeRef = new TypeReference<MyWrapper<T>>();  
    MyWrapper<T> requestWrapper = (MyWrapper<T>) JsonConverter.fromJson(jsonRequest, typeRef);
    return requestWrapper.getRequest();
}

public class MyWrapper<T> {

    private MyRequest<T> request;

    public MyRequest<T> getRequest() {
        return request;
    }

    public void setRequest(MyRequest<T> request) {
        this.request = request;
    }
}

public class MyRequest<T> {
     private List<T> myobjects;
        
     public void setMyObjects(List<T> ets) {
         this.myobjects = ets;
     }

     @NotNull
     @JsonIgnore
     public T getMyObject() {
         return myobjects.get(0);
     }
}

問題は、リクエスト・オブジェクトの中にある getMyObject() を呼び出すと、Jackson はネストされたカスタム・オブジェクトを LinkedHashMap として返すということです。T オブジェクトを返す必要があることを指定する方法はありますか?例えば、私がCustomer型のオブジェクトを送った場合、Customerはそのリストから返されるべきでしょうか?

どのように解決するのですか?

これはJavaの型消去でよく知られている問題で、Tは単なる型変数であり、実際のクラスを、通常はClassの引数として示さなければなりません。そのような情報がない場合、できる最善の方法は bounds を使用することであり、プレーン T は 'T extends Object' とほぼ同じです。そして、Jacksonは、JSONオブジェクトをMapとしてバインドします。

この場合、テスターメソッドはClassにアクセスする必要があります。

JavaType type = mapper.getTypeFactory().
  constructCollectionType(List.class, Foo.class)

で、次に

List<Foo> list = mapper.readValue(new File("input.json"), type);