Category Archives: WSDL

Axis 2 – org.apache.axis2.AxisFault: The given SOAPAction … does not match an operation.

E ai pessoal beleza? bom venho aqui para postar a solução de um problema que tive aqui no trabalho, que me custou alguns dias de pesquisa…

Eu estava tentando consumir um webservice de um cliente e estava tomando o seguinte erro:
org.apache.axis2.AxisFault: The given SOAPAction … does not match an operation.

porém pelo soapUI funciona perfeitamente… entao, eu tinha riscado a hipótese de ser algo com o WSDL

tentei gerar o client do axis2 com ADB e com XMLBEANS porém ambos caíram no mesmo erro…
ai finalmente descobri o motivo, o WSDL do cliente realmente tinha algo errado…
os campos soapAction estavam vazios:

<soap:operation soapAction="" style="document" /> 

então  vi que existem 3 maneiras de resolver esse problema… 1ª o cliente arrumar o WSDL dele,
o que vai depender da boa vontade dele… 2ª setar o valor da action em tempo de execução e a 3ª e ultima que é desabilitar essa soap action…

a 2ª opção é fazendo o seguinte:
AlgumaCoisaServiceStub stub = new AlgumaCoisaServiceStub(); //é gerado pelo axis2
stub._getServiceClient().getOptions().setAction(“http://suaaction&#8221;);

eu acho que a action é manipulada diferentemente para cada versão do soap, para especificar a versão utilize:
stub._getServiceClient().getOptions().setSoapVersionURI(org.apache.axiom.soap.SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
(ou a versão SOAP12 da constante).

e a 3º opção é fazer o seguinte:
AlgumaCoisaServiceStub stub = new AlgumaCoisaServiceStub(); //é gerado pelo axis2
stub._getServiceClient().getOptions().setProperty(org.apache.axis2.Constants.Configuration.DISABLE_SOAP_ACTION, true);

Bom… espero que esse post tenha ajudado vocês 😀
se resolver, irá poupar algumas boas horas de pesquisa 😀

Fonte: StackOverflow – Michael Sharek / mstewart

Anúncios

Criando um Web Service em Java utilizando Apache Axis2 e Eclipse

Web services são componentes da aplicação que se comunicam utilizando protocolos abertos. Usando Web Services nós podemos disponibilizar nossas funcionalidades da aplicação para qualquer um. Neste tutorial provê instruções passo a passo para desenvolver Web Services utilizando Web Services Axis2 / SOAP / WSDL e a IDE Eclipse. Vamos começar.

1. Configurando o Ambiente de Desenvolvimento

1.1 Primeiro você precisa configurar o ambiente de desenvolvimento. Os passos a seguir são necessários se você deseja criar um Web Service utilizando Axis2 e a IDE Eclipse.

Algumas versões do eclipse alguns problemas de compatibilidade com Axis2. Este tutorial é testado com Apache Axis2 1.5.2, Eclipse Helios e Apache Tomcat 6.

1) Apache Axis2 Distribuição Binary – Download
2) Apache Axis2 Distribuição WAR – Download
3) Apache Tomcat – Download
4) Eclipse IDE – Download
5) Java instalado no seu computador – Download

1.2. Então você precisa setar as variáveis de ambiente para o Java e Tomcat. Segue as variáveis que devem ser adicionadas:

JAVA_HOME : Sete o valor do diretório do jdk (ex.: C:\Program Files\Java\jdk1.6.0_21)
TOMCAT_HOME : Sete o valor do diretório da sua instalação do Tomcat(ex.: D:\programs\apache-tomcat-6.0.29)
PATH : Sete o valor do diretório bin do seu jdk (ex.: C:\Program Files\Java\jdk1.6.0_21\bin)

1.3. Agora você precisa adicionar o ambiente de execução no eclipse. Vá em Windows > Preferences > Server > Runtime Environments.

Selecione o Apache Tomcat v6.0 e na próxima tela, procure o diretório da instalação do Apache e clique em finish.

1.4. Então clique em Web Service > Axis2 Preferences e procure o diretório do Apache Axis2.

2. Criando o Web Service utilizando a abordagem Bottom-Up (de baixo para cima)

2.1 Primeiro crie um novo Dynamic Web Project (File > New > Other…) e selecione Web > Dynamic Web Project.

2.2 Sete o Apache Tomcat como o Target Runtime e clique em Modify para instalar o Axis2 Web Services no Project Facet.

2.3 Selecione o Axis2 Web Services

2.4 Clique em OK e Próximo. Então você pode escolher as pastas e clique em Finalizar quando estiver feito.

3. Criando a Classe Web Service

Agora você pode criar uma classe Java que você queira expor como Web Service. Eu vou criar uma nova classe chamada FirstWebService e criar um método public chamado addTwoNumbers que recebe 2 inteiros como parâmetro e retorna a adição dos mesmos.

3.1 Clique com o botão direito em  MyFirstWebService no Project Explorer e selecione New > Class e dê  um nome adequado ao pacote e a classe. Eu coloquei o nome do pacote de com.sencide e FirstWebService ao nome da classe.

package com.sencide;
public class FirstWebService {
 public int addTwoNumbers(int firstNumber, int secondNumber){
  return firstNumber + secondNumber;
 }
}

3.2 Agora, selecione File > New > Other e escolha Web Service.

3.3 Selecione a classe FirstWebService como service implementation e para ter certeza que a configuração está correga, clique em Server runtime.

3.4 Selecione Web Service runtime como Axis2 (o default é Axis) e clique em Ok.

3.5 Clique em Next e certifique-se que selecionou a opção Generate a default service.xml file.

3.6 Clique em Next e em Start Server e depois que o servidor for startado você pode finalizar, se você não quizer publicar o Web service no teste de repositório UDDI.

Você pode ir ao link http://localhost:8888/MyFirstWebService/services/listServices para visualizar o seu serviço rodando que foi implantado pleo Axis2. Você pode visualizar o WSDL clicando no link FirstWebService.

A Porta utilizada na URL deve ser de acordo com a porta utilizada pelo seu TomCat !!!

Nós precisamos utilizar o Eclipse toda vez que nós quisermos rodar o serviço, se nós não criarmos o arquivo .aar (Axis Archive) e implantar dentro do servidor (Tomcat). Bom, vamos ver como podemos criar isso.

4. Criando o arquivo .aar (Axis Archive) e implantando o serviço

4.1 Vá ao seu workspace do Eclipse, na pasta MyFirstWebService e lá você pode encontrar seu Web service dentro da pasta de serviços. Vá até este diretório pelo prompt de comando e dê o seguinte comando. Ele vai criar o arquivo FirstWebService.aar lá.

jar cvf FirstWebService.aar com META-INF

4.2 Então copie o arquivo axis2.war, você pode encontralo dentro da pasta do Apache Axis2 (Que você fez o download no primeiro passo) para o diretório webapps do Apache Tomcat. Agora pare o  servidor Apache Tomcat que você está rodando na IDE Eclipse.

4.3 Utilizando o prompt de comando, starte o Apache Tomcat (Vá ao diretório bin e rode o arquivo startup.bat). Agora nós vamos ter um diretório chamado axis2 dentro do diretório webapps. Agora se você acessar o http://localhost:8080/axis2/ você poderá ver a página inicial da Aplicação Web do Axis2.

4.4 clique no link Administration e faça o login utilizando o usário: admin e a senha: axis2. Aqui você pode ver o link do serviço upado no topo esquerdo e lá você pode efetuar o upload do arquivo FirstWebService.aar que criamos.  Isto é igual copiar manualmente o arquivo FirstWebService.aar para o diretório webapps\axis2\WEB-INF\services.

4.5 Agora quando você listar os serviços pelo http://localhost:8080/axis2/services/listServices você deverá conseguir ver o nosso novo serviço adicionado.

5. Criando um cliente Web Service

5.1 Selecione File > New > Other… e escolha Web Service > Web Service Client

5.2 Insira o endereço (WSDL) do nosso serviço (http://localhost:8080/axis2/services/FirstWebService?wsdl) no campo Service definition. Então configure servidor como fizemos anteriormente e clique em finish.

5.3 Isso gerará duas novas classes chamadas FirstWebServiceStub.java e FirstWebServiceCallbackHandler.java. Agora nós podemos criar uma lcasse de teste para o cliente utilizar o nosso web service. Crie uma nova classe chamada TestClient.java e cole o seguinte código.

package com.sencide;
import java.rmi.RemoteException;
import com.sencide.FirstWebServiceStub.AddTwoNumbers;
import com.sencide.FirstWebServiceStub.AddTwoNumbersResponse;
public class TestClient {
 public static void main(String[] args) throws RemoteException {
  
  FirstWebServiceStub stub = new FirstWebServiceStub();
  AddTwoNumbers atn = new AddTwoNumbers();
  atn.setFirstNumber(5);
  atn.setSecondNumber(7);
  AddTwoNumbersResponse res = stub.addTwoNumbers(atn);
  System.out.println(res.get_return());
  
 }
}

Agora nós podemos rodar o código acima como java application e vamos ter a saída “12” desde que adicionarmos “7” e “5”.

Faça o download do projeto do Eclipse com o Exemplo acima clicando aqui!!! (Senha : sara)

Fonte: Sencide – Saranga Rathnayaka

Descrevendo um Web Service – WSDL

Depois de estudarmos o protocolo de transporte SOAP, aprenda agora como descrever um Web Services.

WSDL

Web Service Definition Language define um sistema para a descrição de serviços. Através dela, descrevemos os serviços externos, ou interfaces que são oferecidos por uma determinada aplicação, independente de sua plataforma ou linguagem de programação.

A especificação da linguagem, em XML, descreve a estrutura da XML que cada documento WSDL deve obedecer (http://www.w3.org/XML/Schema/).
A WSDL se encontra atualmente na versão 2.0, disponibilizada no web site http://www.w3.org/TR/wsdl20/. Submetida a W3C, foi definida em esforço conjunto entre Microsoft, IBM e Ariba.

O seu principal objetivo é descrever as interfaces apresentadas e apontar a localização dos seus serviços, disponíveis em um local previsível e bem conhecido, na rede, o qual permite que o cliente acesse de maneira confiável. Por ser um documento XML, sua leitura se torna fácil e acessível.

Componentes

Através dos componentes, é possível uma maior flexibilidade dos WSDL, estes podem ser reutilizados para definir diferentes serviços.
Os componentes são:

. Tipos de dados: Denominados de tipos <types>.

. Parâmetros de entrada e saída de um serviço: Denominados de mensagem <message>.

. O relacionamento entre parâmetros de entrada e saída: Assinatura do método, denominada de operações <operation>.

. Agrupamento lógico de operações: Denominado de tipo de porta <portType>.

. O protocolo a ser usado para acessar os métodos de um objeto: Denominado de vínculo, define o protocolo a ser usado para acessar os métodos de um objeto (SOAP, HTTP ou MIME).

. Endereço do serviço. Além dos componentes acima, define um serviço.

O diagrama a seguir mostra os principais elementos da WDSL que podem ocorrer e um documento.


Figura 1. Principais elementos de um WSDL.

Namespaces

Os namespaces são espaços para nomes, definidos no interior dos documentos XML. Um documento WSDL é um XML, que utiliza os namespaces para maximizar a taxa de reutilização dos componentes de um documento WSDL, utilizando-se de atributos para fazer referência a outros elementos, seja dentro ou fora do documento.

Abaixo uma tabela com os principais namespaces de um documento WSDL:

Prefixo

URI do namespace

Descrição

WSDL

http://schemas.xmlsoap.org/wsdl

Namespace de WSDL para framework WSDL

SOAP

http://schemas.xmlsoap.org/wsdl/soap

Namespace de WSDL para vinculo de SOAP e WSDl

HTTP

http://schemas.xmlsoap.org/wsdl/http

Namespace de WSDL para WSDL http GET & vinculo POST

Mime

http://schemas.xmlsoap.org/wsdl/mime

Namespace de WSDL para vinculo MIME de WSDL

Soapenc

http://schemas.xmlsoap.org/soap/encoding

Namespace de codificação conforme definido pelo SOAP 1.1

Soapenv

http://schemas.xmlsoap.org/soap/envelope

Namespace de codificação conforme definido pelo SOAP 1.1

Xsi

http://www.w3.org/2001/XMLSchema-instance

Namespace da instância conforme definido pelo esquema de XML

xsd

http://www.w3.org/2001/XMLShema

Namespace do esquema conforme definido pelo esquema de XML


Elemento <definitions>

É o elemento raiz de qualquer documento WSDL. Ele contém atributos que servem para definir os namespaces utilizados no documento WSDL.

Elemento <types>

O elemento types contém os tipos de dados que estão presentes na mensagem. Exemplo:

<wsdl:part name=”endereco” type=”xsd:string”/>
<wsdl:part name=”numero” type=”xsd:int” /> 

Elemento <message>

O elemento message define os dados a serem transmitidos. Cada elemento message recebe um ou mais elementos <part>, que formam as partes reais da mensagem.
O elemento <part> define o conteúdo da mensagem representando os parâmetros que são passados e a resposta que o serviço retorna.

<wsdl:message name=”getCidade”>
<wsdl:part name=”cidade” type=”xsd:string” />
</wsdl:message>
<wsdl:message name=”getCidadeResponse”>
<wsdl:part name=”getCidadeReturn” type=”xsd:string” />
</wsdl:message

Elemento <import>

O elemento import funciona como separação entre as várias partes de uma definição WSDL. Ele possui dois atributos, os quais definem a localização do documento importado e o seu namespace.

<import namespasce=”http://www.cidade.com/definitions/CidadeRemoteInterface
location=”http://localhost/esdl/Cidade-interface.wsdl/” />

Certifique-se sempre que o atributo location aponte para o arquivo correto.

Elementos <operation> e <portType>

Os elementos portType possuem um conjunto de operações (<operation>), as quais possuem um atributo name e um atributo opcional para especificar a ordem dos parâmetros usados nas operações.

Existem quatro diferentes tipos de mensagens de operações, segundo:

. Operação unidirecional: Define uma mensagem enviada de um cliente para um serviço, sem resposta.

. Solicitação-Resposta: O mais utilizado. O cliente envia uma solicitação a um serviço, e recebe como resultado uma mensagem de resposta com o resultado dessa solicitação. Pode ser vista como um RPC (remote procedure call).

. Pedido-Resposta: Não utilizada freqüentemente. Define uma mensagem enviada do serviço para o cliente, resultando em uma mensagem enviada do cliente de volta para o serviço.

. Notificação: É quando o serviço envia uma mensagem para o cliente.

Como você pode ver, o portType corresponde apenas a um agrupamento de operações, onde você pode agrupá-las em um ou vários elementos <portType>.
Caso você utilize uma ferramenta para se criar a WSDL, como por exemplo o Axis em Java ou o nuSOAP no PHP, estas ferramentas poderão tomar esta decisão.

Elemento <binding>

O elemento binding mapeia os elementos operation em um elemento portType, para um protocolo especifico. Ele associa o elemento portType ao protocolo SOAP, utilizando-se de um elemento de extensão SOAP chamado <wsdlsoap:binding>, através de dois parâmentos: protocolo de transporte e o estilo da requisição (rpc ou document).

<wsdl:binding name=”CidadeSoapBinding” type=”impl:Cidade”>
<wsdlsoap:binding style=”rpc” transport=http://schemas.xmlsoap.org/soap/http />

Elementos <service> e <port>

Os elementos service e port definem a localização real do serviço, tendo em vista que o mesmo pode conter varias portas e cada uma delas é especifica para um tipo de ligação, descrita no elemento binding.

<wsdl:service name=”ConsultaCidadeService”>
<wsdl:port binding=”impl:ConsultaCidadeSoapBinding” name=”ConsultaCidade”>
<wsdlsoap:address location=http://localhost/wsdl/ConsultaCidadeServer.php/>
</wsdl:port>
</wsdl:service>

Exemplo de WSDL

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>
<definitions xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/&#8221;
xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/&#8221;
xmlns:tns=”urn:server.hello” xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/&#8221;
xmlns:wsdl=”http://schemas.xmlsoap.org/wsdl/&#8221;
xmlns=”http://schemas.xmlsoap.org/wsdl/&#8221; targetNamespace=”urn:server.hello”>
<types>
<xsd:schema targetNamespace=”urn:server.hello”>
<xsd:import namespace=”http://schemas.xmlsoap.org/soap/encoding/&#8221; />
<xsd:import namespace=”http://schemas.xmlsoap.org/wsdl/&#8221; />
</xsd:schema>
</types>
<message name=”helloRequest”>
<part name=”name” type=”xsd:string” />
</message>
<message name=”helloResponse”>
<part name=”return” type=”xsd:string” />
</message>
<portType name=”server.helloPortType”>
<operation name=”hello”>
<documentation>Retorna o nome</documentation>
<input message=”tns:helloRequest” />
<output message=”tns:helloResponse” />
</operation>
</portType>
<binding name=”server.helloBinding” type=”tns:server.helloPortType”>
<soap:binding style=”rpc” transport=”http://schemas.xmlsoap.org/soap/http&#8221; />
<operation name=”hello”>
<soap:operation soapAction=”urn:server.hello#hello” style=”rpc” />
<input>
<soap:body use=”encoded” namespace=”urn:server.hello”
encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/&#8221; />
</input>
<output>
<soap:body use=”encoded” namespace=”urn:server.hello”
encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/&#8221; />
</output>
</operation>
</binding>
<service name=”server.hello”>
<port name=”server.helloPort” binding=”tns:server.helloBinding”>
<soap:address location=”http://localhost/imasters2/nuSOAP/server2.php&#8221; /> </port>
</service>
</definitions>

_________________________________

Fonte: iMasters – Mauricio Reckziegel