Exército de tipos genéricos em Jersey

Preciso retornar à lista de clientes com poucos resultados e contagem total de resultados. Eu tenho que fazer isso em vários lugares com entidades diferentes, então eu gostaria de ter uma class genérica com esses dois atributos:

@XmlRootElement public class QueryResult implements Serializable { private int count; private List result; public QueryResult() { } public void setCount(int count) { this.count = count; } public void setResult(List result) { this.result = result; } public int getCount() { return count; } public List getResult() { return result; } } 

E o serviço:

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

Entidade não é importante:

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

Mas isso faz com que: javax.xml.bind.JAXBException: class test.TestEntity nor any of its super class is known to this context.

Retornar apenas da coleção é fácil, mas não sei como retornar meu próprio tipo genérico. Eu tentei usar GenericType mas sem sucesso – eu acho que é para collections.

Depois de lutar com isso eu descobri a resposta é bastante simples. Em seu serviço, retorne uma resposta criada de um GenericEntity ( http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/GenericEntity.html ) digitada de acordo. Por exemplo:

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

Veja este post para porque você não pode simplesmente retornar GenericEntity: Jersey GenericEntity não funciona

Uma solução mais complexa poderia ser devolver o GenericEntity diretamente e criar seu próprio XmlAdapter ( http://jaxb.java.net/nonav/2.2.4/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html ) para lidar com marshalling / unmarshalling. Eu não tentei isso, então é apenas uma teoria.

Eu resolvi usando anotação @XmlSeeAlso :

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

Outra possibilidade é usar @XmlElementRefs .

Eu tive exatamente o mesmo problema. O problema ocorre devido ao apagamento de tipo do Java.

Minha primeira abordagem foi gerar uma class de resultado para cada tipo de entidade:

 public class Entity1Result extends QueryResult { ... } public class Entity2Result extends QueryResult { ... } 

Eu retornei o QueryResult<> genérico QueryResult<> em meus serviços apenas para tipos QueryResult como QueryResult ou QueryResult

Mas isso foi complicado, porque eu tinha muitas entidades. Então minha outra abordagem foi usar apenas JSON e mudei minha class de resultado para não-genérica e usei um campo de resultado Object :

 public class QueryResult { private Object result; } 

Funciona bem, Jersey é capaz de serializar tudo o que eu dou em JSON (Nota: Eu não sei se é importante, mas o QueryResult e todas as minhas entidades ainda têm annotations @Xml... Isso funciona também para listas com tipos de entidades próprias.

Se você tiver problemas com collections, também poderá ver essa pergunta