A1Provendo e Consumindo Web-Services com JAX-WS Capítulo 22 Introdução aos Web-Services via JAX-WS - Um breve histórico sobre Web-Services Os Web-Services são uma tecnologia popular para apoiar iniciativas de B2B, SOA e computação distribuída em geral, quando pensamos na Internet. Em sua forma mais clássica, baseada em protocolo SOAP/XML, prover ou consumir serviços pode requerer um grande esforço quando implementados manualmente, sem o apoio de um framework e gerador especializados. Para amenizar este problema, desde o início do século que não faltam frameworks e geradores para Web- Services. Produtos como o Apache Axis e inúmeros outros produtos comerciais, porém, davam suas próprias saídas e modificaram o problema original para outro: falta de padrão e até de compatibilidade entre as diversas soluções, que introduziam extensões proprietárias aos seus produtos. Felizmente, é para problemas como este que o padrão Java EE foi criado. A partir da versão 2.0 da API JAX-WS, introduzida no Java EE 5, a simplicidade se concretizou (tanto quanto possível). E esta simplicidade, aliada a um padrão de mercado, tornaram o JAX-WS a melhor opção do mundo Java para se prover ou consumir serviços Web via SOAP! - SOAP x REST No próximo capítulo veremos uma solução alternativa aos Web-Services "SOAP" abordados neste capítulo, chamada RESTful Web-Services. Esta alternativa pode ser implementada também de forma padrão, pela API JAX-RS - e também conta com frameworks de apoio à produtividade. Na verdade, por ser de fato mais simples de se utilizar, dispensando a camada SOAP sobre o protocolo HTTP, o XML e outras exigências de Web-Services tradicionais, os RESTful Web-Services já são inclusive mais populares na Internet. Há quem diga inclusive que eles irão sepultar os Web-Services, mas há também quem aponte vantagens únicas do padrão JAX-WS. Possivelmente, neste momento e por algum tempo, o desenvolvedor terá que dominar ambos: muitos serviços públicos são expostos em somente uma destas modalidades e ainda há nicho significativo para ambos. Por este motivo, e como este assunto é vasto, deixaremos esta polêmica fora de nosso escopo, trabalhando com os dois padrões. Do ponto de vista estritamente técnico, o próprio desenvolvedor poderá tirar suas próprias conclusões após as práticas deste e do próximo capítulo. Provendo um Serviço - Entendendo a demanda de negócio do "provedor" Suponhamos que nosso sistema seja instalado em uma filial multinacional e que a matriz ou outras filiais queiram, diretamente de seus sistemas, recuperar dados de um funcionário. Eles precisam de nome, sexo e data de nascimento, mas possuem o CPF em seu sistema (na falta de um campo mais "neutro" como uma matrícula global). Do ponto de vista tecnológico, há também a preferência por expor este serviço na forma de um W eb- Service tradicional, por questões culturais - os analistas já trabalham há alguns anos com isso e querem manter o padrão. Vamos então implementar este serviço no padrão JAX-WS 2.0 e, o que é ainda mais interessante, fora de um contêiner EJB! O padrão JAX-WS opera de forma ainda mais transparente com o uso de um método de EJB, mas é possível utilizá-lo no Tomcat, por exemplo, através de utilitários de geração que veremos.
Importante: Podemos utilizar EJB 3.x no jcompany, sem problemas, utilizando o jboss AS, por exemplo, mas como todo o tutorial do livro se baseou no Tomcat, manteremos esta linha. - Criando a classe de serviço O primeiro passo para a criação de um W S * é a definição de uma classe que será exposta como serviço na Web. No nosso exemplo, teremos uma classe "com.empresa.rhtutorial.ws.buscafuncionariows" em que seu método exposto recebe uma String "CPF" e retorna uma entidade" com.empresa.rhtutorial.ws.entity.funcionario". Vamos implementar a nossa classe de serviço na camada de controle, uma vez que não utilizaremos nenhuma lógica de negócios e acesso a banco de dados. Tomamos a iniciativa de simplificar o exemplo para que o foco fique exclusivamente na criação do W S. As classes podem ser vistas na Figura G22.1 e na Figura G22.2. Importante: Não se esqueça que os objetos a serem transmitidos pelo W S devem ser serializáveis! Figura G22.1. Classe "Funcionario". Figura G22.2. Classe de serviço "BuscaFuncionarioWS". #1. Anotação "@WebService" indica que a classe "BuscaFuncionarioWS" é um serviço web (WS). #2. Anotação "@WebMethod" indica que esse método será exposto no WS. #3. Anotação "@WebParam" serve para informar o nome do parâmetro do WS. #4. Nesse ponto, pedimos a nossa fachada para recuperar o funcionário baseado no nosso CPF. Não vamos entrar em detalhe na implementação da camada de modelo para não fugir do nosso foco principal. - Configurando dependências no projeto para geração dos artefatos de suporte a Web-Services JAX- WS (somente Tomcat) 1. Adicione as dependências do JAX-WS no arquivo "pom.xml" do projeto onde será implementado o WS. * N es ta doc umentação iremos utilizar a s igla WS para indic ar Web-Service.
Capítulo G22 Figura G22.3. Conf igurando o arquivo "pom.xml" com as dependências do JAX-WS. - Configurando o JAX-WS. Para configurar o JAX-WS, vamos seguir os passos abaixo: 1. Crie o arquivo "sun-jaxws.xml" dentro da pasta WEB-INF do projeto, informando os WEB-SERVICES criados. Figura G22.4. Arquivo "sun-jaxws.xml" com as conf igurações do WS criado. 2. Mapeie a aplicação para responder ao serviço. Essa configuração deverá ser feita no arquivo "web.xml". Figura G22.5. Mapeando o serviço no arquivo web.xml. - Ativando a execução de deploy-completo e testando. 1. Acione a opção de Deploy Completo. 2. Verifique a disponibilidade do serviço pelo browser através da URL: http://localhost:8080/rhtutorial/busca. O serviço pode ser visto na Figura G22.. Figura G22.6. Tela identif icando que o serviço está ativo.
Consumindo um Serviço - Entendendo o lado do "consumidor" Como não traz nenhuma restrição proprietária, o serviço que criamos no passo anterior está disponível para ser consumido por qualquer "cliente" de WS, que pode utilizar qualquer tecnologia para acessá-lo. Mas como nossa tecnologia é Java, precisamos fechar o nosso ciclo para também entender quais são os padrões JAX-WS para o lado "consumidor". Como teste, e para evitar a proliferação de aplicações, vamos definir nossa classe consumidora no mesmo projeto "rhtutorial". Fica sob responsabilidade do desenvolvedor testá-la em outra aplicação, se desejado. - Configurando dependências no projeto para geração dos artefatos de suporte ao JAX-WS (somente Tomcat) Para estabelecer o serviço de consumo, nós devemos seguir a demanda abaixo para configurar o JAX-WS como uma dependência da classe provedora *. 1. Adicione o plugin para geração dos Stubs em tempo de empacotamento. A documentação detalhada do plugin se encontra em: https://jax-ws-commons.dev.java.net/jaxws-maven-plugin/. Vamos adicionar configurações de profile no arquivo "pom.xml" 2. Adicione ao arquivo "pom.xml" os parâmetros de profile e dependências mostrados na Figura G22.7. * P or motivos didáticos, nes te livro a c lasse provedora e c onsumidora pertencem ao mes mo projeto. N o mundo real is s o muito dific ilmente irá ac ontecer, uma vez que o objetivo de us o dos WS é a trans mis são de dados entre aplicações. N o c ontexto de aplicações diferentes para o us o do WS a c lasse c onsumidora prec isaria também das dependências do jc ompany Service em s eu arquivo "pom.xml".
Capítulo G22 Figura G22.7. Adicionando prof ile do maven no arquivo "pom.xml". #1. Este trecho não tem muitas novidades quanto ao descrito anteriormente, a diferença é a tag "goals" que neste caso indica que os artefatos importados pertencem à classe provedora. 3. Execute o comando maven "install" com o parâmetro "-Dwebservice=S" para gerar os artefatos. Após rodar o script, serão gerados os artefatos para consumo com os mesmos pacotes da aplicação do serviço. Veja Erro! Fonte de referência não encontrada.. Figura G22.8. Artef atos gerados no consumidor do WS.
Importante: Lembrando que para geração dos artefatos no consumidor, ao executar o script de deploy, a aplicação provedora do serviço deve estar executando. Importante: Para o cliente funcionar na mesma aplicação do serviço, após a geração dos Stubs de cliente, deve-se alterar a interface BuscaFuncionarioWS para IBuscaFuncionarioWS para não dar conflito com a classe do serviço. - Criando a classe de consumo Vamos criar um formulário para entrada dos dados, no nosso caso o CPF e uma classe de controle que recebe esse parâmetro da tela e retorna o funcionário. Para o exemplo vamos utilizar o padrão "controle simples", que é um padrão que dispensa diversos itens de arquitetura da camada visã o e controle. 1. Crie a classe de controle conforme Erro! Fonte de referência não encontrada.. Figura G22.9. Classe de controle para consumir o serviço. 2. Crie o arquivo "buscafuncionario.xhtml" dentro da pasta ".../WEB-INF/fcls/buscafuncionario/". Esse arquivo será utilizado para entrada e exibição dos dados.
Capítulo G22 Figura G22.10. Arquivo xhtml para entrada e exibição dos dados da classe de controle para consumir o serviço. #1. Tag que cria o campo para o usuário informar o "CPF". #2. Lógica para mostrar o retorno da pesquisa. Se o funcionário for retornado, seus dados são mostrados, caso contrário a mensagem "Funcionário não encontrado!" é exibida. 3. Crie um menu para acessar o nossa classe provedora. Para isso adicione o código da Erro! Fonte de referência não encontrada. no arquivo "geralmenu.xhtml" da aplicação. Figura G22.11. Adicionando um item de menu. - Testando o novo serviço de consumo Neste ponto, nossa aplicação estará pronta para fornecer e consumir o serviço estabelecido anteriormente. Dê um "Liberação Para Tomcat Completa Desenvolvimento", acione o tomcat e teste o serviço gerado pelo WS. Figura G22.4. Tela com o acesso ao serviço de busca de f uncionário por CPF.
Sumário Neste capítulo discutimos brevemente sobre Web-Services tradicionais, baseados em SOAP sob o protocolo HTTP e uso de XML/WSDL. Criamos um primeiro serviço para recuperar os dados principais de um funcionário a partir de seu CPF. Em seguida, implementamos um exemplo do lado "consumidor", utilizando em ambos os casos o padrão JAX-WS sobre o Tomcat. No próximo capítulo, iremos explorar a alternativa RESTful Web-Services, baseada no padrão JAX-RS, para viabilizar uma comparação entre os dois modelos, além de conhecer generalidades do jcompany nesta área, através do jcompany Service.