我有一个通用的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)
然后正常工作。
任何想法,我怎么可以把它与一般的科技工作?
一旦源代码被编译时,(匿名)类创建由行:
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>>
除了答案,读取响应对象后面的客户端上:
List<MyObject> list = response.readEntity(new GenericType<List<MyObject>>(){}));
Response对象被返回到客户端响应请求发送到服务器。 响应类有收集设置为其类型Response.ResponseBuilder的字段中的每个属性Response.ResponseBuilder内部类。 Response.ResponseBuilder应用生成器设计模式来构建响应对象。
构建()方法负责连接形成在构建的过程Response.ResponseBuilder对象链。 例如
Response.status(200);
状态的方法分配状况进行评估后返回Response.ResponseBuilder
Response.status(200).entity( AnyObj );
实体对象分配类型Response.ResponseBuilder的实体(有效载荷返回)和被分配给的响应的实例varible。 在此之后,状态也赋予的地位和返回Response.ResponseBuilder实例。 建设者在build()方法调用的时间将它们连接。
Response.status(200).entity( obj ).build();
最后,构建的方法构建完整的(包含属性阐述)响应。
现在来GenericEntity对象的问题。 它代表了一个泛型类型T的响应实体
例如,
GenericEntity> OBJ =新GenericEntity>(LST){}; Response.status(200).entity(OBJ).build();
obj是列表的类型如以上给出。 实体方法接受其是通用的对象类型。 在情况下,特定类型的需要,你得把它作为通过在运行时它强制转换为特定类型的对象GenericEntity类型的参数。
实际使用
想为我的球衣框架来这是List对象在我的Java模型回客户端作为响应对象的一部分数组类型的响应JSON。
因此,新GenericEntity> ---连铸对象/有效载荷列出类型新GenericEntity ---运行时类型变得字符串
资源WebService的方
public Response findAllFruits(@QueryParam("frtID") String frtID ) {
List<String> lst = new ArrayList<String>();
lst.add("Banana");
lst.add("Apple");
GenericEntity<List<String>> obj = new GenericEntity<List<String>>(lst) {};
return Response.status(200).entity( obj ).build();
}
输出响应返回给客户端。 [ “香蕉”, “苹果”]
如何阅读响应实体
List<CustomType> myObj= response.readEntity(new GenericType<List<CustomType>>() {});
为了解决这个问题一提出来返回的方法GenericEntity
然后从我的泛型类调用它,有些东西象下面这样:
@XmlRootElement
public abstract class AbstractRest<T extends IEntity> {
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
public abstract class SmartWebServiceNEW<R extends AbstractRest<T>> {
@GET
@Produces({MediaType.APPLICATION_XML})
public Response findAll() {
List<T> lista = getDelegate().findAll();
if (lista == null || lista.isEmpty()) {
return Response.status(Response.Status.NO_CONTENT).build();
}
List<R> retorno = new ArrayList<R>();
for (T it : lista) {
retorno.add(toRest(it));
}
GenericEntity entity = listToGenericEntity(retorno);
return Response.ok(entity).build();
}
protected abstract GenericEntity listToGenericEntity(List<R> restList);
}
@Path("/something")
@RequestScoped
public class MyEntityResource extends SmartWebServiceNEW<MyEntityExtendingAbstractRest> {
@Override
protected GenericEntity listToGenericEntity(List<MyEntityExtendingAbstractRest> restList) {
return new GenericEntity<List<MyEntityExtendingAbstractRest>>(restList) {
};
}
}
文章来源: Using Java-generics template type in RESTful Response object via GenericEntity>