WebServices Fácil com Apache CXF, Spring e Anotações no ORACLE Weblogic 10.3

WebServices é um padrão aberto que é muito utilizado, porem fazer um WebService escrevendo a WSDL pode ser uma tarefa pesada, usar ferramentas pode ser uma boa, mas isso pode gerar uma dependência com seu fornecedor de ferramentas. Vou mostrar como pode ser fácil e simples criar um Webservice com WSDL, sem você ter que criar uma linha de WSDL, como?

Usando duas excelentes soluções de mercado, Apache CXF veio do bom e velho XFire,Tempos passado eu fiz um poste sobre Spring e XFire, para dar mais facilidade, produtividade, simplicidade e outros tantos recursos vamos usar isso tudo em conjunto com o Spring Framework. Vamos fazer tudo isso usando anotações, no final você vai ver que com 6 arquivos, vamos fazer uma solução muito simples.

Não se preocupe para cada Webservice você não precisara criar 6 arquivos, por que 2 desses arquivos são o pom.xml do maven de dois projetos e um arquivo é o web.xml. Outro arquivo é um xml de beans do spring que pode ser reutilizado na criação de outros serviços des de que você vá adicionado mais definições dele.

Nesse exemplo além de usar Spring 2.5, Apache CXF 2.2 vou usar Maven 2 com o plugin do Cargo para fazer o deploy no ORACLE Weblogic 10.3, o servidor foi escolhido por que é muito robusto é fácil de fazer o deploy com maven.

Por fim vamos testar o Webservice de duas formas, a primeira dela escrevendo um client em Java usando o Apache CXF, Spring e Maven. Na segunda forma vou usar a ferramenta SoapUI que é excelente ferramenta para testes com WebServices.



Vamos ao código então, primeiro vamos a interface java que será exposta como Webservice, o legal do apache CXF é que ele vai gerar quase todo o mapeamento para o WSDL de forma automática, você ainda pode parametrizar informações via anotações se preferir ou tiver essa necessidade, no meu exemplo vou fazer o uso mais simples dessa solução.

DateService.java

package com.blogspot.diegopacheco.spring.cxf.service;

import javax.jws.WebService;

/**
* Interface do Serviço de datas.
*
* @author Diego Pacheco
* @version 1.0
* @since 13/06/2009
*
*/
@WebService
public interface DateService {
String getDate();
}

Aqui é uma interface java normal com uma anotação do JAX-WS que indica o uso de Webservices, vamos a implementação do serviço e do Webservice por conseqüência. Como o leitor pode perceber eu adoro criar serviços de datas, não são serviços propriamente ditos se estivermos falando de SOA por exemplo, nos meus exemplos faço isso para simplificar as coisas só por isso :)

DateServiceImpl.java
package com.blogspot.diegopacheco.spring.cxf.service;

import java.util.Date;

import javax.jws.WebService;

/**
* Implementação do Serviço de datas.
*
* @author Diego Pacheco
* @version 1.0
* @since 13/06/2009
*
*/
@WebService(endpointInterface = "com.blogspot.diegopacheco.spring.cxf.service.DateService")
public class DateServiceImpl implements DateService {

public String getDate() {
return new Date().toString();
}
}

Essa é a implementação do serviço de datas, como você pode reparar ele retorna a data/hora corrente do servidor aonde o Webservice esta publicado, isso será interessante para os testes, por que sempre tem que vir um valor diferente a cada chamada.

Nesta classe foi utilizada novamente um anotação padrão do JAX-WS para indicar qual a interface que esse serviço está implementado. Agora vamos a configuração do Spring juntamente com a configuração do Apache CXF.

spring-cxf-beans.xml

















Preciso explicar apenas 3 coisas nesse XML. A primeira é 'context:component-scan', com isso o spring registra os beans automaticamente des de que eles estejam devidamente anotados com as anotações do Spring Framework, ainda estou adicionado um filtro para ele pegar os beans com anotações do JAX-WS também. Se eu tivesse outros beans ou esses mesmos que fiz com anotações @Service ou @Component o spring ira registra-los também.

Esse é um recurso muito bom do Spring Framework que aumenta consideravelmente a produtividade, em contra partida perdemos um pouco a extensibilidade, pois para modificar os beans vamos ter que mexer no código :(

O Segundo ponto que vou explicar são os 3 imports de recursos que estão no jar do apache CXF, são necessários para o funcionamento da solução, antes esse tipo de configuração era feito na mão criando esses 3 arquivos com as configurações, com a evolução das coisas chegamos a essa solução que é prática e fácil.

Por fim o terceiro ponto que devo explicações a vocês é o 'jaxws' aonde são passadas algumas configurações para o Webservice como a implementação e o mais importante o atributo 'address' que sera utilizado no endpoint do WS para ser acessado pelos clientes.

Para expor esse Webservice no ORACLE Weblogic vamos ter que empacotar esses fontes em um war, no final do post eu dou o link para o meu repositório do Subversion onde vocês podem pegar os fontes completos com os códigos do maven para empacotamento do WAR e deploy do EAR no ORACLE Weblogic.

Vamos ver como fica o Web.xml desse projeto war aonde estão os serviços que serão expostos como Webservice, confira o arquivo a baixo:

web.xml





contextConfigLocationWEB-INF/spring-cxf-beans.xml



org.springframework.web.context.ContextLoaderListener




CXFServlet
org.apache.cxf.transport.servlet.CXFServlet

1



CXFServlet
/*



Nesse arquivo foi configurado o Listener do Spring que carrega o contexto do Spring quando a aplicação é iniciada no container da ORACLE Weblogic, também é configurado o servlet do Apache CXF. Essa configuração é padrão não se preocupe muito com isso.

Uma vez que você faça o deploy do EAR com o maven no Weblogic agora basta consumir o seu Webservice, vou mostrar isso de duas formas a primeira com a ferramenta de testes para Webservices chamada SoapUI.

Abra a ferramenta SoapUI e crie um projeto novo com qualquer nome e informa a localização do WSDL, você pode pegar o WSDL nesse endereço: http://localhost:7001/spring-cxf-pojo/DateService?wsdl certifique-se de que o servidor esta no ar.

Vá no método getDate() e execute o request, se der tudo certo vocÊ receberá um retorno semelhante a esse da figura a baixo:

Teste com SoapUI

Clique na figura para ver ela maior se quiser. Essa ferramenta é muito boa, além fazer testes com Webservices ela gera os cenários de testes e faz bons testes de Carga/Stress, outro ponto legal é que ela gera código através de integração com os mais diversos produtos e soluções de Webservices sendo um deles o próprio Apache CXF.

Vamos ao segundo teste, agora com uma classe do Spring, antes disso precisamos configurar o contexto do spring em outra aplicação que será o cliente Webservice, confira a configuração do Spring a baixo:

spring-cxf-wsclient-beans.xml








Aqui estou usando o 'jaxws' e estou dizendo qual é a interface Java que eu uso para segurar esse bean, e por fim qual é o endereço endpoint desse webservice. Depois disso ele é tratado como um bean normal do spring, logo você pode injeta-lo em outros beans através do seu id que se chama de 'dateService'.

Agora basta subir o contexto do Spring usado esse bean, veja isso na classe de testes do JUnit que segue a baixo:

package com.blogspot.diegopacheco.spring.cxf.wsclient;

import junit.framework.TestCase;

import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.blogspot.diegopacheco.spring.cxf.service.DateService;

/**
* Classe de testes do JUnit para o ws client.
*
* @author Diego Pacheco
* @version 1.0
* @since 13/06/2009
*
*/
public class WsClientTest extends TestCase {

@Test
public void testGetDate(){
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring-cxf-wsclient-beans.xml");
DateService ds = (DateService)ac.getBean("dateService");

Assert.assertNotNull("O ds nao pode ser null, erro no spring",ds);       
System.out.println("Data vinda do WS: " + ds.getDate());
}

}


Como você pode ver o bean foi usado normalmente como qualquer outro bean ordinário do Spring Framework por esse tipo de coisas que o Spring se solidificou como um modelo definitivo de desenvolvimento Java onde a simplicidade toma o lugar da complexidade da JEE.

Dessa forma podemos criar Webservices com WSDL de forma produtiva e sem se amarrar em ferramental. Se você quiser os fontes da aplicação completa pode pegar no meu repositório do SVN nos links a baixo:
Se você tiver algumas dúvida ou deseja contribuir com algo poste um cometário, comentários são sempre bem vindos :), se você queiser ler mais sobre Webservices confira outros posts relacionados ao assunto:
Abraços e até a próxima.

Popular posts from this blog

Kafka Streams with Java 15

Rust and Java Interoperability

HMAC in Java