JAX-WS Webservice retornando uma Collection

12 respostas
G

Pessoal, estou usando o JAX-WS para publicar meus webservices e quando utilizo um tipo básico ou mesmo um bean da minha aplicação como tipo de retorno tudo funciona certo. No entanto quando tento retornar uma Coleção (ArrayList, HashMap…) eu recebo no meu cliente um objeto “empty”.
Tem algum detalhe que eu preciso cuidar para fazer isso? No início pensei que fosse porque meu Map continha tipos complexos, mas usando diretamente os tipos complexos, sem estar numa coleção, funciona.
Deve ser coisa simples. Aguardo a ajuda de vocês.
Obrigado.

12 Respostas

L

gilliard_santos,

nao sei se te ajuda em algo, mas eu tive um problema parecido.

foi mais ou menos assim: no meu bean A eu tenho um ArrayList de um outro objeto meu(B), aí quando eu criava um método no meu ws para retornar este meu objeto A, ele nao vinha com a lista do meu objeto B. Para resolver isso, eu precisei colocar neste meu bean A um método set para esta minha lista, pois tinha apenas o set.

Aí com isso pude perceber q para que uma property apareça mapeada no meu ws, é necessário que ela tenha ambos os métodos get e set.

Nao sei se ajudo, mas c vc descobrir algo sobre este problema, posta aí pra gente ter uma idéia … :smiley:

[]’'sss!!!

G

Valeu leonickel. Vou testar isso amanha cedo quando estiver no serviço.
Mas se mais alguem tiver uma solução, ou entao puder comentar sobre como isso funciona exatamente eu agradeço.

P

Ola!

Retorne Collection em vez das classes concretas, pois elas estão especificadas. As vezes quando voce retorna classe concreta ele trata como complex type e procura por todos os atributos não-transientes para transforma-los em XML. E advinha? Algumas colecoes alguns dos atributos sao transientes pois eles tem os metodos readObject e writeObject…

E ate onde eu sei, JAX-WS nao define suporte a MAP.

M

Também é bom evitar o uso de coleções em web services, prefira usar arrays mesmo que são bem mais fáceis de serem “mapeados”, especialmente pra outras linguagens de programação.

G

Paulo, no início eu tentei utilizar Interface, mas me dava um erro dizendo que eu tinha que trabalhar com classes concretas senão o jaxb não conseguia fazer binding. E sobre o Map eu não sei, mas achei um cara que tinha o mesmo problema usando ArrayList, por exemplo.
E Maurício, valeu pelo toque, vou procurar utilizar da forma como voce disse.
Qual seria então a forma “correta” de se fazer isso? A maioria dos exemplos que encontro na net ou é solução específica de algum framework ou então só trabalha com string e int. Tem também alguns outros exemplos que ao meu ver pareceram muito complexos e pareceram nao combinar com a facilidade de criar um WS usando JavaEE 5. Como a aplicação que estou fazendo vai acabar servindo de referência para muitas outras, gostaria de algo bem simples como “para retornar coleção o procedimento é este…” (não preciso de nada muito diferente, só arroz com feijão mesmo).
Vocês teriam algum bom material de WS com JAX-WS 2 para indicar?
Obrigado novamente.

M

A melhor dica que eu posso dar é, não use coleções, especialmente se você está escrevendo web services que vão ser utilizados por outras aplicações em outras linguagens. A sua ferramenta de web services pode gerar um WSDL bizarro que ache que a coleção é na verdade um tipo complexo, o que não é nem um pouco interessante.

A melhor forma de lidar com essas coisas é trabalhar com arrays mesmo, porque qualquer ferramenta pé-de-chulé vai saber o que fazer com eles e lá do outro lado do web service ninguém precisa saber que você tá usando um ArrayList ou HashSet, o que eles querem são os dados.

T

De qualquer forma, é super-simples retornar um Objeto[] em vez de um List<Objeto>; basta usar o método toArray.

G

Valeu Maurício! Passei a retornar um Array e funcionou. Ao mesmo tempo que eu eliminei o problema, deixei o serviço melhor de usar em outras linguagens. É que eu estava usando o mesmo método para disponibilizar o serviço via EJB e WS. Agora vou fazer um para cada tecnologia e deve ficar melhor. Obrigado a todos!

P

Maurício Linhares:
A melhor dica que eu posso dar é, não use coleções, especialmente se você está escrevendo web services que vão ser utilizados por outras aplicações em outras linguagens. A sua ferramenta de web services pode gerar um WSDL bizarro que ache que a coleção é na verdade um tipo complexo, o que não é nem um pouco interessante.

A melhor forma de lidar com essas coisas é trabalhar com arrays mesmo, porque qualquer ferramenta pé-de-chulé vai saber o que fazer com eles e lá do outro lado do web service ninguém precisa saber que você tá usando um ArrayList ou HashSet, o que eles querem são os dados.

Mauricio! sua ferramenta que nao esta fazendo o trabalho direito. Nao va se adaptar a um framework, ele que deveria ja ter sido feito pensando em voce! Uma boa implementacao de JavaWS vai mapear Collection para array. Voce nao precisa usar uma array java para isso…

Do outro lado ele vai trabalahr com o que a linguagem dele mapear Collection!

thingol! denovo o seu framework que ta forçando a voce a trabalhar com Object[] em vez de List…

M

Paulo, já tive problemas o suficiente com ferramentas que não sabiam mapear collections (e isso não é nem um problema só delas, até porque não dá pra saber o tipo da coleção sem genéricos e mesmo com genéricos isso não é trivial) ou com clientes de web services que não sabiam ler os WSDLs gerados, usar um array nesse caso não mata ninguém e ainda simplifica a interoperabilidade, não custa nada ajudar as ferramentas ou cuidar pra que elas tenham que adivinhar o mínimo possível.

P

Mauricio, eu entendo voce… a gente as vezes quer se precaver em relacao as ferramentas malucas que tem por ai. mas o default do jaxb é transformar List em uma tag que tem maxOccurs=“unbounded”… isso deveria sempre funcionar. Um JAX-WS que nao esta fazendo isso me parece estranho… gilliard, voce poderia me passar o codigo fonte da sua interface que recebia Collection para eu testar?

G

Paulo, era aproximadamente isso

Interface

@Remote
@WebService(name="GerenciadorSeguranca", targetNamespace="http://meupacote.seguranca.service")
public interface GerenciadorSeguranca {

	//usando a implementacao HashMap pois o JAXB nao trabalha com interfaces
	public HashMap&lt;String, Acesso&gt; verificaPermissoes(Usuario usuario, Perfil perfil, String componente, String sistema);

}

Implementacao (apenas para testar)

@Stateless(name="GerenciadorSeguranca")
@WebService(serviceName="GerenciadorSeguranca",	
		targetNamespace="http://meupacote.seguranca.service",
		endpointInterface="meupacote.seguranca.service.GerenciadorSeguranca")
public class GerenciadorSegurancaImpl implements GerenciadorSeguranca {

  public HashMap&lt;String, Acesso&gt; verificaPermissoes(Usuario usuario, Perfil perfil, String componente, String sistema) {
		

   HashMap&lt;String, Acesso&gt; retorno = new HashMap&lt;String, Acesso&gt;();
   retorno.put("teste1", Acesso.EDITAR);
   retorno.put("teste2", Acesso.NAO_MOSTRAR);
   retorno.put("teste3", Acesso.VISUALIZAR);

   return retorno;

  }
}

Obrigado pelos toques :smiley:

Criado 18 de fevereiro de 2008
Ultima resposta 18 de fev. de 2008
Respostas 12
Participantes 5