在使用JAX-RS规范的Rest服务中,我可以定义像
这样的通用服务@GET
@Path("something")
@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public List<MyPojo> getMyPojoList() {
...
}
泽西岛发生了一些奇迹,因为在调用
时javax.ws.rs.ext.MessageBodyWriter#writeTo(T t,
Class<?> type,
Type genericType,
Annotation annotations[],
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException;
在分析genericType
时,很容易看出他的值为class MyPojo
。
我一直在尝试阅读Jersey源代码,以了解他们在调用writeTo
的方法javax.ws.rs.ext.MessageBodyWriter
之前如何提取Collection Generic类型,但是一旦到达就读了{ {1}}上课。
任何人都可以帮助我了解他们在那里使用哪种魔法?在此先感谢!!!
答案 0 :(得分:1)
通过编译器将一些通用信息保留到运行时中。看一下有关Java反射的文档。在这种情况下,它们可能使用getGenericReturnType,尽管有许多方法与参数类型甚至类的泛型参数有关。
这里最明显的缺点是只能保留编译时的信息 - 特别是你无法可靠地检查列表以确定它是List<Integer>
还是List<String>
。
答案 1 :(得分:0)
您需要使用JAX-RS框架的神奇类来保留您正在寻找的信息。我花了相当长的时间才能在我的项目上实际完成此工作,但这是我解决问题的方法:
首先,在您的Resource类中,这样传递通用集合(请注意,我使用Response Objects):
public Response findAll() {
Collection<MyType> entities = service.findAll(); // whatever code you need to load it.
GenericEntity<Collection<MyType>> list = new GenericEntity<Collection<MyType>>(entities) {}; // This line is key!
return Response.ok.entity(list).build();
}
然后,您可以创建一个普通的 MessageBodyWriter 实现,并在负责检查您的实现是否合适的方法中执行类型检查。
public class MyTypeMessageBodyWriter implements MessageBodyWriter<MyType> {
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
if (Collection.class.isAssignableFrom(type) && genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
return (actualTypeArgs.length == 1 && actualTypeArgs[0].equals(MyType.class));
} else {
return false;
}
}
}
您可以增强isWriteable
方法来执行更多检查,例如再次检查MediaType
是否正确,以及是否需要根据需要添加一些注释等。< / p>
但要总结一下:
GenericEntity<>
包装器包装您的收藏夹,以保存保存器通用类型信息