我发现了一些我无法理解的奇怪行为.
I found some strange behaviour that I cannot understand.
我已经测试了4个类似的示例:
I have tested 4 similar examples:
@GET @Produces(MediaType.APPLICATION_JSON) public Response produce() { List<Book> books = Arrays .asList(new Book[] { new Book("aaa", "AAA", "12345"), new Book("bbb", "BBB", "09876") }); return Response.ok(books).build(); }2
@GET @Produces(MediaType.APPLICATION_JSON) public List<Book> produce() { List<Book> books = Arrays .asList(new Book[] { new Book("aaa", "AAA", "12345"), new Book("bbb", "BBB", "09876") }); return books; }3
@GET @Produces(MediaType.APPLICATION_XML) public List<Book> produce() { List<Book> books = Arrays .asList(new Book[] { new Book("aaa", "AAA", "12345"), new Book("bbb", "BBB", "09876") }); return books; }4
@GET @Produces(MediaType.APPLICATION_XML) public Response produce() { List<Book> books = Arrays .asList(new Book[] { new Book("aaa", "AAA", "12345"), new Book("bbb", "BBB", "09876") }); return Response.ok(books).build(); }一切都在#1,#2,#3中起作用,但第4个示例抛出:
Everything works in #1, #2, #3 but 4th example throws:
找不到类型为的响应对象的MessageBodyWriter: 媒体类型为java.util.Arrays $ ArrayList:application/xml.
Could not find MessageBodyWriter for response object of type: java.util.Arrays$ArrayList of media type: application/xml.
我在Wildfly 9上运行它,不知道它是否与RestEasy或JaxRS有关?我知道可以通过将集合包装在GenericEntity中来解决此问题,但是我不理解这种不一致的行为.
I run it on Wildfly 9 and I wonder if it is related to RestEasy or JaxRS in general? I know that I can fix it by wrapping collection in GenericEntity, but I don't understand this inconsistent behaviour.
推荐答案问题是缺少类型信息.对于处理XML序列化的JAXB,这是必需的.
The problem is the missing of type information. This is required for JAXB, which handles the XML serialization.
1和2之所以起作用,是因为Jackson用于JSON,并且通常不需要内省属性就知道类型信息.
1 and 2 works because Jackson is being used for JSON, and it generally doesn't need to know type information as it just introspects properties.
3之所以有效,是因为通过方法返回类型可以知道类型信息.
3 works because type information is known through the method return type.
4不起作用,因为没有类型信息. 类型擦除将其删除.这就是GenericEntity的解决方法.它存储类型信息.
4 doesn't work because there is no type information. It's is erased by type erasure. That's where GenericEntity comes to the rescue. It stores the type information.
GenericEntity
通常,类型擦除会删除通用类型信息,以使包含例如类型为List<String>的实体的Response实例在运行时看起来包含原始的List<?>.当需要通用类型来选择合适的MessageBodyWriter时,可以使用此类包装实体并捕获其通用类型.
Normally type erasure removes generic type information such that a Response instance that contains, e.g., an entity of type List<String> appears to contain a raw List<?> at runtime. When the generic type is required to select a suitable MessageBodyWriter, this class may be used to wrap the entity and capture its generic type.
更多推荐
@在JAXRS/RestEasy中产生集合
发布评论