segunda-feira, 4 de março de 2013

Java - Testando Web Services (SOAP) manualmente

É muito comum para desenvolvedores que trabalham com WebService utilizar a ferramenta soapUI para testar um WebService que utilize o protocolo SOAP. Afinal trata-se de uma ferramenta poderosa e muito útil para testar seus WebServices.

A grosso modo a ferramenta soapUI, funciona enviando um XML via HTTP e recebendo uma resposta também em XML, ou seja, utilizando o WebService em sua forma mais "pura". Normalmente os desenvolvedores utilizam algum framework capaz de converter objetos em XML e XML em objetos,  diminuindo consideravelmente a complexibilidade do código. Pois, torna desnecessário escrever os XMLs manualmente.

O que vamos ver neste post é um exemplo de utilização de WebServices em sua forma "pura", ou seja , sem a conversão para objetos, tanto para o envio bem como para recuperação dos dados. O código a seguir apresenta como realizar essa operação.

/**
  * @param args
  */
 public static void main(String[] args) {

  try {

   URL url = new URL("[URL DO SERVIÇO SEM (?wsdl): Exemplo: http://localhost/WebServiceTest/DataAtualService"]);

   URLConnection urclConnection = url.openConnection();

   HttpURLConnection connection = (HttpURLConnection) urclConnection;

   connection.setDoOutput(true);

   connection.setDoInput(true);

   connection.setAllowUserInteraction(true);

   connection.setRequestMethod("POST");

   /**
    * Necessário quando se trata da versão 1.1 do protocolo SOAP
    */
   connection.setRequestProperty("SOAPAction", "");

   connection.setRequestProperty("Host", "http://localhost");

   connection.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");

   OutputStreamWriter infWebSvcReqWriter = new OutputStreamWriter(connection.getOutputStream());

   String infWebSvcRequestMessage = [XML];

   infWebSvcReqWriter.write(infWebSvcRequestMessage);

   infWebSvcReqWriter.flush();

   BufferedReader reader = null;

   /**
    * Verifica sucesso da requisição, em caso positivo obtém XML esperado em caso negativo
    * obtém XML de Erro
    */
   if (connection.getResponseCode() == 200) {

    reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

   } else {

    reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
   }

   String line;

   String infWebSvcReplyString = "";

   while ((line = reader.readLine()) != null) {

    infWebSvcReplyString = infWebSvcReplyString.concat(line);

   }
   
   infWebSvcReqWriter.close();

   reader.close();

   connection.disconnect();
   
   /**
    * Apresenta no console do Java o XML de recuperado
             */
   System.out.println(infWebSvcReplyString);

  } catch (Exception e) {

   System.out.println(e);
   
  }
 }

No código apresentado, a linha 33 String infWebSvcRequestMessage = [XML]; representa que o conteúdo de um XML é passado para a váriavel infWebSvcRequestMessage. Esse conteúdo pode ser escrito diretamente na variável ou pode ser lido através de um arquivo. O XML abaixo representa um exemplo do que poderia ser passado para a variável infWebSvcRequestMessage.

 <SOAP-ENV:Envelope xmlns:
  SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
  
  </SOAP-ENV:Header/>
  <SOAP-ENV:Body>
      <m:recuperaDataAtual>
       <format>dd/MM/yyyy HH:mm:ss</format>
   </m:recuperaDataAtual>
  </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>


Uma vez que o código é executado com o XML acima, é possível obter um retorno positivo ou negativo da requisição, afinal, trata-se de uma requisição HTTP. Assim o desenvolvedor pode receber um XML com o retorno esperado assim como um XML representando uma ocorrência de erro. Abaixo apresento exemplos de retorno para as duas situações.

 <SOAP-ENV:Envelope xmlns:
  SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 </SOAP-ENV:Header/>
   <SOAP-ENV:Body>
     <m:recuperaDataAtualResponse>
        <string>14/05/1986 22:37:00</string>
     </m:recuperaDataAtualResponse>
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>
XML com retorno esperado


 <soap:Envelope 
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
  </SOAP-ENV:Header/>
  <soap:Body>
      <soap:Fault>
         <faultcode>1234</faultcode>
         <faultstring>Não foi possível chamar o método recuperaDataAtual</faultstring>
      </soap:Fault>
    </soap:Body>
 </soap:Envelope>

XML de erro

Um comentário:

  1. Olá Allan, você teria um exemplo de como integrar um aplicativo android no WebService REST?

    Grato
    rrobsonmonteiro@gmail.com

    ResponderExcluir