汎用JAX-RSリソースクラスがあり、汎用findAll
メソッドを定義しました
public abstract class GenericDataResource<T extends GenericModel> {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response findAll() {
Query query = em.createNamedQuery(modelClass.getSimpleName()+".findAll");
List<T> list = query.getResultList();
return Response.ok(new GenericEntity<List<T>>(list) {}).build();
}
}
およびユーザークラス:
public class User extends GenericModel {
...
}
そしてここにサブクラス定義の例があります:
@Path("users")
public class UserResource extends GenericDataResource<User> {
public UserResource() {
super(User.class);
}
}
私は例外を下回ります:
com.sun.jersey.api.MessageException: A message body writer for Java class
java.util.Vector, and Java type java.util.List<T>,
and MIME media type application/json was not found exception.
Tを次のUser
ように定義されたクラスに置き換えると、
GenericEntity<List<User>>(list)
その後、正常に動作します。
ジェネリックTでどのように機能させるかについてのアイデアはありますか?
ソースコードがコンパイルされると、次の行で作成される(匿名)クラス:
new GenericEntity<List<T>>(list) {}
型変数を使用して、その親を参照します。型変数は実行時に値を持たないため、このようなジェネリックを使用することはできません。呼び出し側サイトからいわゆるタイプトークンを渡す必要があります。これは、の呼び出し元からトークンを渡す必要がある例findAll()
ですが、コンストラクタでトークンを要求して、インスタンス変数に保存することもできます。
public abstract class GenericDataResource<T extends GenericModel> {
public Response findAll(GenericEntity<List<T>> token) {
Query query = em.createNamedQuery(modelClass.getSimpleName() + ".findAll");
List<T> list = query.getResultList();
return Response.ok(token).build();
}
}
発信者は次のようなトークンを送信します
new GenericEntity<List<User>>() {}
パラメータ化されていないサブクラスのみを使用する場合はfindAll()
、リフレクションを利用してトークンを作成することができます(テストされていません。
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response findAll() {
Query query = em.createNamedQuery(modelClass.getSimpleName()+".findAll");
List<T> list = query.getResultList();
return Response.ok(new GenericEntity(list, getType())).build();
}
getType()
目的のタイプを返すように実装する必要があります。ParameterizedType
タイプを表すことができるサブクラスになりますList<DAO<User>>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加