Desenvolvendo a primeira aplicação com Apache CXF

Veja neste artigo os passos necessários para criar uma primeira aplicação Java do tipo Web Service utilizando o framework Apache CXF.

O Apache CXF é um framework de integração que dá suporte à criação de serviços no padrão Web Service. Através dele podemos criar e consumir serviços, utilizando código Java e configuração do framework Spring. Não é objetivo desse artigo explicar extensamente o que é um Web Service, ou como é organizado um WSDL e nem mesmo o que é SOA. Abordaremos apenas como criar um projeto simples com o apache Maven, como utilizar a geração de código Java a partir de um arquivo WSDL pré-existente e ainda como publicar uma implementação do serviço.

Quando trabalhamos com Apache CXF, temos claramente duas linhas principais de desenvolvimento. A primeira é gerar o código Java anotado e compatível com o JAX-WS a partir de um descritor WSDL (que veremos a seguir). A segunda forma é criar o código Java manualmente e em seguida utilizá-lo para gerar o arquivo WSDL. O resultado final é o mesmo: um serviço no padrão Web Service.

O WSDL que utilizaremos é bem simples e oferece apenas uma operação que retorna obrigatoriamente uma resposta de sucesso ou um erro. Operações que trabalham requisição/resposta de forma síncrona são ditas que seguem o MEP (message exchange pattern) Request/Reply. Erros são comumente chamados de Fault.

<?xml version="1.0" encoding="UTF-8" ?> <wsdl:definitions name="HelloWorldService" targetNamespace="http://helloworldservice.devmedia.com.br/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://helloworldservice.devmedia.com.br/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:do="http://helloworldservice.devmedia.com.br/schema/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <wsdl:types> <xs:schema targetNamespace="http://helloworldservice.devmedia.com.br/schema/" attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:tns="http://helloworldservice.devmedia.com.br/schema/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Nome" type="tns:Nome"/> <xs:element name="Saudacao" type="tns:Saudacao" /> <xs:element name="Erro" type="tns:Erro"/> <xs:complexType name="Nome"> <xs:sequence> <xs:element name="conteudo" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name="Saudacao"> <xs:sequence> <xs:element name="conteudo" type="xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name="Erro"> <xs:sequence> <xs:element name="conteudo" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="DigaOlaRequisicao"> <wsdl:part name="parametro" type="do:Nome" /> </wsdl:message> <wsdl:message name="DigaOlaResposta"> <wsdl:part name="saudacao" type="do:Saudacao" /> </wsdl:message> <wsdl:message name="DigaOlaException"> <wsdl:part name="DigaOlaException" type="do:Erro" /> </wsdl:message> <wsdl:portType name="DigaOla_PortType"> <wsdl:documentation> A operacao digaOla recebe um nome por parametro e devolve um cumprimento ou erro em situacoes especificas </wsdl:documentation> <wsdl:operation name="digaOla"> <wsdl:input name="DigaOlaRequisicao" message="tns:DigaOlaRequisicao" /> <wsdl:output name="DigaOlaResposta" message="tns:DigaOlaResposta" /> <wsdl:fault name="DigaOlaException" message="tns:DigaOlaException" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="DigaOla_SoapBinding" type="tns:DigaOla_PortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="digaOla"> <soap:operation soapAction="" /> <wsdl:input name="DigaOlaRequisicao"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="DigaOlaResposta"> <soap:body use="literal" /> </wsdl:output> <wsdl:fault name="DigaOlaException"> <soap:fault name="DigaOlaException" use="literal" /> </wsdl:fault> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldService"> <wsdl:port name="HelloWorldService_Port" binding="tns:DigaOla_SoapBinding"> <soap:address location="https://www.devmedia.com.br/HelloWorldService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
Listagem 1. WSDL do serviço de exemplo
Figura 1. Estrutura do WSDL

Na Figura 1 conseguimos ver a estrutura do nosso WSDL. Todo descritor WSDL é composto de duas partes principais: uma abstrata que relaciona os tipos suportados (types), as mensagens (message) e as operações (portType e operation) e a outra concreta, que amarra as definições abstratas em detalhes de protocolo, transporte, endereços físicos e codificação (binding, service). Para mais detalhes sobre a estrutura de um WSDL, visite o site: Web Services Description Language.

Uma vez que já temos o nosso descritor de serviço, podemos criar nosso projeto do maven (pom.xml) da seguinte forma:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.cxf.samples</groupId> <artifactId>wsdl_first_cxf</artifactId> <packaging>jar</packaging> <name>WSDL first usando apache cxf</name> <description>WSDL first usando apache cxf</description> <version>2.7.0</version> <build> <plugins> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>${project.version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <wsdlOptions> <wsdlOption> <wsdl>src/main/resources/ HelloWorldService.wsdl</wsdl> <extraargs> <extraarg>-all</extraarg> </extraargs> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
Listagem 2. Projeto do maven

Nesse pom.xml a parte mais interessante está na seção de plugins. Vemos uma ferramenta bem útil do CXF chamada wsdl2java. Esse plugin transformará o WSDL em código Java anotado utilizando o padrão JAX-WS. O JAX-WS é um padrão de mercado suportado por vários fornecedores e traz facilidade na criação de serviços, apenas adicionado anotações do Java a classes Pojo. Um fato importante é que se utilizamos JAX-WS, não estamos necessariamente amarrados ao CXF. O JAX-WS é nativamente suportado pelo Java 6 em diante.

mvn clean package eclipse:eclipse
Listagem 3. Comando maven

Esse comando faz com que o código Java seja gerado e ao mesmo tempo cria o projeto compatível com o IDE Eclipse. Podemos agora abrir o projeto e finalmente fazer o nosso serviço funcionar. Lembre-se: se você não conhece o maven, visite Apache.org.

A opção “-all” criará para nós exemplos de servidor e cliente. O servidor é simplesmente a classe Java que dá vida ao Web Service. Essa classe implementará uma interface Java que define o comportamento descrito pelo WSDL e será publicada em um endereço físico acessível pelo cliente. O cliente é qualquer sistema que queira invocar operações do serviço inclusive outros serviços. A seguir, uma implementação simples da operação digaOla.

package br.com.devmedia.helloworldservice; import br.com.devmedia.helloworldservice.schema.Erro; import br.com.devmedia.helloworldservice.schema.Nome; import br.com.devmedia.helloworldservice.schema.Saudacao; import br.com.devmedia.helloworldservice.wsdl.DigaOlaException; import br.com.devmedia.helloworldservice.wsdl.DigaOlaPortType; @javax.jws.WebService( serviceName = "HelloWorldService", portName = "HelloWorldService_Port", targetNamespace = "http://helloworldservice.devmedia.com.br/wsdl/", endpointInterface = "br.com.devmedia.helloworldservice.wsdl.DigaOlaPortType") public class SimpleHelloWorldService implements DigaOlaPortType { @Override public Saudacao digaOla(Nome parametro) throws DigaOlaException { Saudacao s = new Saudacao(); if ("ze".equals(parametro.getConteudo())) { s.setConteudo("Bom dia"); } else if ("maria".equals(parametro.getConteudo())){ s.setConteudo("Ola"); } else { Erro erro = new Erro(); erro.setConteudo("ERR_01"); throw new DigaOlaException("Nao quero conversar",erro); } return s; } }
Listagem 4. Implementação de exemplo
Figura 2. Estrutura do projeto

Alguns pontos importantes dessa implementação devemos ressaltar:

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados