【问题标题】:Marshalling of generic types in Jersey泽西岛泛型类型的编组
【发布时间】:2012-06-10 04:32:46
【问题描述】:

我需要返回几个结果和结果总数的客户列表。我必须在具有不同实体的几个地方执行此操作,因此我希望有一个具有这两个属性的通用类:

@XmlRootElement
public class QueryResult<T> implements Serializable {
    private int count;
    private List<T> result;

    public QueryResult() {
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void setResult(List<T> result) {
        this.result = result;
    }

    public int getCount() {
        return count;
    }

    public List<T> getResult() {
        return result;
    }
}

还有服务:

@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public QueryResult<TestEntity> findAll(
    QueryResult<TestEntity> findAll = facade.findAllWithCount();
    return findAll;
}

实体不重要:

@XmlRootElement
public class TestEntity implements Serializable {
    ...
}

但这会导致:javax.xml.bind.JAXBException: class test.TestEntity nor any of its super class is known to this context.

仅返回集合很容易,但我不知道如何返回我自己的泛型类型。我尝试使用GenericType,但没有成功 - 我认为这是收藏品。

【问题讨论】:

    标签: java jaxb jersey


    【解决方案1】:

    我遇到了完全相同的问题。由于 Java 的类型擦除而出现此问题。

    我的第一个方法是为每个实体类型生成一个结果类:

    public class Entity1Result extends QueryResult<Entity1> { ... }
    
    public class Entity2Result extends QueryResult<Entity2> { ... }
    

    我在我的服务中返回了通用的QueryResult&lt;&gt;,仅用于QueryResult&lt;String&gt;QueryResult&lt;Integer&gt;等内置类型

    但这很麻烦,因为我有很多实体。所以我的另一种方法是只使用 JSON,我将结果类更改为非泛型并使用 Object 结果字段:

    public class QueryResult {
       private Object result;
    }
    

    它工作正常,Jersey 能够将我给它的所有内容序列化为 JSON(注意:我不知道它是否重要,但 QueryResult 和我所有的实体仍然有 @Xml... 注释。这也有效对于具有自己的实体类型的列表。

    如果收藏有问题,也可以看this question

    【讨论】:

      【解决方案2】:

      我用@XmlSeeAlso注解解决了:

      @XmlSeeAlso(TestEntity.class)
      @XmlRootElement
      public class QueryResult<T> implements Serializable {
          ...
      }
      

      另一种可能是使用@XmlElementRefs

      【讨论】:

      • 啊,是的 :) 但这仅在您没有很多实体并且总是希望返回该实体的列表时才有效。如果您想将QueryResult 用于不同的结果类型,那么这将变得不切实际。
      【解决方案3】:

      在自己与此作斗争后,我发现答案相当简单。 在您的服务中,返回相应键入的 GenericEntity (http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/GenericEntity.html) 的构建响应。例如:

      @GET
      @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public Response findAll(){
          return Response.ok(new GenericEntity<TestEntity>(facade.findAllWithCount()){}).build();
      }
      

      请参阅这篇文章,了解为什么不能简单地返回 GenericEntity:Jersey GenericEntity Not Working

      更复杂的解决方案可能是直接返回 GenericEntity 并创建您自己的 XmlAdapter (http://jaxb.java.net/nonav/2.2.4/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html) 来处理编组/解组。不过,我还没有尝试过,所以这只是一个理论。

      【讨论】:

        猜你喜欢
        • 2015-07-12
        • 1970-01-01
        • 2014-10-06
        • 1970-01-01
        • 1970-01-01
        • 2011-08-02
        • 1970-01-01
        • 2017-05-13
        • 2013-12-21
        相关资源
        最近更新 更多