Criando um WebService com a JSR 181

O Paulo colocou um capítulo de webservices no curso de EJB, com o intuito de aumentar a abrangência do curso em relação as novidades do Java EE 5 e aos poucos diminuir a pesada carga da 1.4, conforme o mercado assimila mais a nova versão.

Fui ver então como ele podia inserir um tema que tem tantos detalhes e conceitos em um curso que já era pesado. Ele está usando a JSR 181, que define anotações para a criação de um webservice para qualquer bean que você deseje deixar acessível. Fiquei muito impressionado com a simplicidade. Vamos direto ao código:

@WebService
public class AgenteDeReservaBean {
  @WebMethod
    public boolean reserva(@WebParam(name = "nome") String nome,
                                         @WebParam(name = "voo") String voo) {

    // acesso ao EntityManager injetado
    // logica de negocios, ou delegacao para o BO
    return false
  }
}

@WebParam é opcional, mas como o bytecode do java 5 não retém os nomes dos parâmetros (em outras palavras, por reflection você não obtém essa informação), o WSDL gerado iria gerar nomes automáticos para os parâmetros (arg0, arg1, etc).

Como ativar esse webservice? XMLs gigantes de configuração? Não! Basta um container que já faz tudo isso para você.

Existem algumas opções de implementações da JSR-181. O pessoal do GUJ gosta do XFire, mas como ele não é um container Java EE 5, você precisa fazer algumas configurações (tais como o web.xml e um outro xml dele próprio) para realizar o deploy.

O JBossWS é uma opção extremamente simples: anote sua classe com @Stateless, instale o JBoss 4.0.x com suporte a ejb3, ligue-o, gere o viagens.jar com essa única classe, deploy, e acesse:

http://localhost:8080/viagens/AgenteDeReserva?wsdl

Seu webservice já está respondendo nesse memo endereço (sem o ?wsdl no final, claro). Um monte de defaults foram usados (nome do serviço, das operações, do resultado, complex types, etc), você poderia configurar tudo isso através das anotações.

Você ainda pode gerar a interface do endpoint necessária através do wstools que acompanha o jboss. Uma maneira extramamente mais simples é já criar um endpoint, definindo essa interface como @WebService, e no seu bean você pode indicar que essa interface é o seu endpoint, evitando assim a geração de código java.

É, e você pensava que o Apache Axis te ajudava bastante para criar um webservice…

15 Comentários

  1. Carlos Villela 17/08/2006 at 08:27 #

    Lindo, mas publicar um metodo na web eh relativamente so uma pequena parte do problema. Manter esse metodo seguro, estavel, escalavel, aguentar multiplas versoes do sistema, parametros opcionais… a simplicidade de um @WebMethod eh joia, mas esconde um monte de perigos que a maioria prefere fingir que nao existe.

    Depois, SOAP eh nojento 🙂

  2. Paulo Silveira 17/08/2006 at 14:27 #

    É. Se explor um método em uma interface já é uma decisão difícil, expor um método por SOAP é mais ainda… e depois não vai ter @Deprecated pra ajudar, vai ser o pessoal reclamando e vários 404.

    Também prefiro chamadas remotas via XML sem estar envelopado no SOAP: crio meu schema e aviso os clientes. A vantagem do SOAP é a quantidade de ferramentas para gerar os stubs dado o WSDL.

  3. Carlos Villela 20/08/2006 at 10:15 #

    Qual o problema com REST? 🙂

  4. Paulo Silveira 21/08/2006 at 01:54 #

    nada! você também pode usar as anotações!
    http://java.sun.com/developer/technicalArticles/WebServices/restful/

  5. Paulo Silveira 15/12/2007 at 04:29 #

    Pra ser mais fácil ainda, há uma maneira de você publicar o serviço pelo Java SE, que se encarrega de rodar um servidor web super simples:

    http://weblogs.java.net/blog/jitu/archive/2006/01/web_service_end.html

  6. Andre 24/10/2010 at 23:53 #

    Olá,
    muito interessante.
    E como eu posso colocar uma API no WS e referenciá-la no XML build?

    att,

    André.

Deixe uma resposta