generics - XML 或 JSON 的 JAX-RS 响应不起作用

标签 generics jax-rs java-ee-7

我有以下 GenericRest 类,我用它来扩展基于用 @XmlRootElement 注释的实体类的休息类。

public class GenericRest<T extends BaseEntity> {

    @Inject @Service
    GenericService<T> service;

    public GenericService<T> getService() {
        return service;
    }

    @GET
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public Response getAll() {
        // This works for JSON but does not work for XML Requests.
        List<T> list = getService().findAll();
        // This just gives the attributes for the BaseEntity.
        //GenericEntity<List<T>> list = new GenericEntity<List<T>>(getService().findAll()) {};
        return Response.ok(list).build();
    }
}
APPLICATION_JSON在当前未注释的情况下工作正常,但 APPLICATION_XML给出错误:

Could not find MessageBodyWriter for response object of type: java.util.ArrayList of media type: application/xml



注释的情况适用于两种 MediaType,但只返回 BaseEntity 的属性,而不是扩展类的附加属性。如何获取扩展类的属性 两个 MediaType 都可以工作吗?

可以在此处找到完整的存储库(正在进行中):https://github.com/martijnburger/multitenant

=== 更新 1 ===

我更改了 @XmlSeeAlso实体上的注释。它在特定实体上,但需要在 BaseEntity 上.此外,我使用了 GenericList上面的实现。这给出了正确的 XML回应。但是,它仍然只返回 BaseEntity JSON 中的属性 react 。我有两个后续问题:
  • 如何返回 JSON响应包括请求的特定对象的属性?
  • 如果 BaseEntity添加或删除特定 Entity 时不必触及类。因为@XmlSeeAlso每次我添加一个新的 Entity 时的注释类,我需要更新注释。有没有另一种方法来实现这个我不需要触摸 BaseEntity ?

  • 可以在此处找到具有更改的存储库:https://github.com/martijnburger/multitenant/tree/so_36291250

    === 更新 2 ===

    我很希望 @JsonSubTypes Jackson的注释可以解决我的问题1。但是,它没有。我用 Jackson 注释更新了存储库,但我看不到结果的任何变化。

    === 更新 3 ===

    请忽略我的更新 2。使用 Jackson 2 而不是 Jackson 1 时它完全有效。初学者错误。 :(
    这给我留下了一个问题:每次添加实体时是否可以在不接触 BaseEntity 的情况下使其工作。

    最佳答案

    您可以使用具有 XML 模块的 Jackson,而不是使用 JAXB for XML。对于 JAX-RS,您将使用 this artifact 1

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-xml-provider</artifactId>
        <version>${jackson2.version}</version>
    
        <!-- you'll probably want to use the same version as
             the jackson being used on your wildfly -->
    
    </dependency>
    
    如果您使用它,XML 将由 Jackson 处理,它没有 JAXB 所做的一些相同的怪癖。而且您所有的 Jackson JSON 注释也可以使用它,因此您只需要一组注释,用于 XML 和 JSON。在较低级别,Jackson XML 提供程序使用 jackson-dataformat-xml ,如果您想了解更多有关它的信息。
    根据我的测试,只需将工件添加到您的项目中就足以使其工作,尽管我没有在 Wildfly 上进行测试,我只是单独使用 RESTeasy 进行了测试。但我想应该仍然可以工作。
    如果它不能解决问题,我唯一能想象的就是 JAXB 提供者优先于这个提供者。您可能需要排除 resteasy-jaxb-provider在 jboss-structure.xml 文件中。但就像我说的,我认为这不是必需的。我会用 Wildfly 进行测试,但我真的不想下载它 :-)
    额外的
    OP 正在使用类路径扫描 2 来选择自动注册资源和提供程序,但是如果您在 Application 中手动注册资源和提供程序子类,您还需要手动注册 JacksonXMLProvider.class (或 JacksonJaxbXMLProvider.class ,如果您想要 JAXB 注释支持)。

    1 - 链接的项目显示为已弃用,但它链接到未弃用的更高版本。我链接到已弃用的那个,因为它在自述文件中有一些文档,尽管它很少。较新的项目根本没有文档。
    2 - 空 Application@ApplicationPath 注释的子类足以触发类路径扫描。一旦覆盖 getClasses()getSingletons()并返回一个非空集,类路径扫描被禁用。

    关于generics - XML 或 JSON 的 JAX-RS 响应不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36291250/

    相关文章:

    java - 推理变量 T 具有不兼容的边界

    Delphi Rtti 用于通用上下文中的接口(interface)

    java - jackson 检查可选字段

    jakarta-ee - 如何使用 JAX-RS 中的过滤器向 HTTP 请求添加 header ?

    java - 具有 JPA 实体的 JAX-RS JSON 序列化循环

    mongodb - Wildfly 8 中用于 CDI 的自定义 jndi 对象工厂

    java - 泛型通配符 : Assigning Super class object to a Subclass object list

    java - 将泛型转换为子类型

    java - 如何配置 Jersey (javax.ws.rs.*) 以重用 ssl session

    java - 是否可以从 servlet 或过滤器启动对话