Blog

Criando e consumindo WebServices SOAP em Java


É muito comum que cada vez mais analistas optem por utilizar uma arquitetura distribuída e busquem tornar seus projetos prontos para operarem em multiplataformas. Evidentemente, existem muitas práticas necessárias para atingir este objetivo e, portanto, não se trata apenas de uma prática ou outra, mas sim o conjunto delas. Neste artigo apenas será abordado uma das tecnologias disponíveis para isso.

Para tornar mais fácil a compreensão da tecnologia, foi utilizado um exemplo de uma consulta de endereço por CEP com apenas um método com um retorno fixo simples. 


package com.joaofelipe.cep;

public class Endereco {

    public String estado;
    public String cidade;
    public String bairro;
}


Nota-se no código a seguir que foi criada uma interface que possui apenas um método, "consultar". Este método apresenta a notação "WebMethod" que indica se tratar de um método acessível do WebService. Os métodos que não possuem essa notação não serão acessíveis como métodos do WebService, mas terão comportamento normal assim como qualquer método de uma classe.

A interface também possui algumas anotações como "WebService", que indica se tratar de uma classe com comportamento de serviço web. Já a anotação "SOAPBinding(style = Style.RPC)" indica a forma como o serviço está sendo disponibilizado, neste caso, via RPC.


package com.joaofelipe.cep;
import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; @WebService @SOAPBinding(style = Style.RPC) public interface CepServer { @WebMethod Endereco consultar(int cep); }


Russell Butek explica um pouco mais sobre as diferenças de estilo do SOAPBinding no developerWorks da IBM:


Before I go any further, let me clear up some confusion that many of us have stumbled over. The terminology here is very unfortunate: RPC versus document. These terms imply that the RPC style should be used for RPC programming models and that the document style should be used for document or messaging programming models. That is not the case at all. The style has nothing to do with a programming model. It merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model.


Na classe CepServerImpl estão as implementações dos métodos da interface CepServer, apresentada acima. A anotação "WebService(endpointInterface = "com.joaofelipe.cep.CepServer")" indica o pacote e a interface do WebService.


package com.joaofelipe.cep;
import javax.jws.WebService; @WebService(endpointInterface = "com.joaofelipe.cep.CepServer") public class CepServerImpl implements CepServer { public Endereco consultar(int cep) { Endereco endereco = new Endereco(); endereco.estado = "BA"; endereco.cidade = "Salvador"; endereco.bairro = "Pituba"; return endereco; } }


Para rodar o serviço utilizamos apenas um Endpoint, pois não havia necessidade de utilizar algo com mais recursos, como um Apache Tomcat ou outro servidor qualquer. Desta forma, apenas iniciamos o serviço e deixamos ele acessível para que um cliente o consuma. Para saber um pouco mais sobre EndPoints, visite o site da Oracle em docs.oracle.com.


package com.joaofelipe.cep;
import javax.xml.ws.Endpoint; public class CepServerPublisher { public static void main(String[] args) { Endpoint.publish("http://127.0.0.1:9871/cep", new CepServerImpl()); } }


Para consumir o WebService SOAP que criamos, será preciso mapear seus métodos da seguinte forma:


package com.joaofelipe.cep;
import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; class CepClient { public static void main(String args[]) throws Exception { URL url = new URL("http://127.0.0.1:9871/cep?wsdl"); QName qname = new QName("http://cep.joaofelipe.com/","CepServerImplService"); Service ws = Service.create(url, qname); CepServer cep = ws.getPort(CepServer.class); Endereco endereco = cep.consultar(41810215); System.out.println("Estado: " + endereco.estado); System.out.println("Cidade: " + endereco.cidade); System.out.println("Bairro: " + endereco.bairro); } }


Evidentemente, o projeto onde o WebService será consumido precisa conhecer a classe Endereco e a interface que define os métodos do mesmo e, portanto, será preciso criar um projeto para ser utilizado por ambos, evitando assim duplicidade de código que ocorreria caso uma cópia da classe e da interface existisse em cada projeto, o que não deixa de ser funcional.



No fim seu projeto deve ficar divido de forma semelhante a apresentada acima. Importante observar que neste exemplo o projeto "soap-common" é utilizado pelos demais projetos "soap-server" e "soap-client".

SOAP Java WebService