O que é web service?

De acordo com a W3C, web service é um software projetado para suportar interação máquina-máquina de forma interoperável através de uma rede. Ele tem uma interface descrita em um formato máquina-processável (especificamente WSDL). Sistemas que interagem com o web service de uma maneira prescrita por sua descrição, utilizam mensagens SOAP, normalmente transmitidas através de HTTP com uma serialização XML em conjunto com outros padrões web.

 

O caminho.

Para a integração com outros sistemas, o ERP Protheus da Totvs provê uma série de web services e ainda existe a possibilidade de desenvolver e publicar serviços customizados dentro da plataforma.

Figura 1 – Página com a descrição dos serviços disponíveis do Protheus.

 

O problema.

Ao iniciar o desenvolvimento de uma aplicação em Java 6, utilizando o Netbeans 7.0 como IDE e a biblioteca JAX-WS para o consumo dos serviços, foi exibida a mensagem “WEBSERVICE ERROR : Soap Prefix Missing : USERPORTAL : PRTLOGIN : Formato do Pacote Soap DESCONHECIDO.” ao tentar executar uma chamada simples ao serviço USERPORTAL, método PRTLOGIN.

 

A solução.

Será demostrado um passo-a-passo de como iniciar um projeto até o consumo com sucesso do web service especificado.

No Netbeans, clique no menu Arquivo, seguido por Novo Projeto. Na tela que irá abrir, selecione em Categorias: “Java” e em Projetos: “Aplicativo Java”. Clique em Próximo.

Figura 2 – Novo projeto.

 

Informe o nome do projeto (neste caso SigaWS), faça modificações caso ache necessário e clique em Finalizar.

Figura 3 – Novo Aplicativo Java

 

Com o projeto criado, deverá ser criada a classe para consumo do serviço USERPORTAL, para isto clique em Arquivo, seguido por Novo Arquivo.

Figura 4 – Arquivo, Novo Arquivo.

 

Na tela de Novo Arquivo selecione em Categorias: “Serviços Web” e em Tipos de arquivos: “Cliente para serviço Web”, clicando em Próximo.

Figura 5 – Novo arquivo.

 

Na próxima tela deverá ser selecionada a opção WSDL URL e informado o caminho do arquivo de definição do serviço de acordo com o publicado no Protheus. Clique em Finalizar.

Figura 6 – Novo cliente para serviço Web.

 

Voltando para a tela principal do Netbeans, vá na aba Projetos e abra os nós de Referência de serviços Web até localizar o método PRTLOGIN.

Selecione o nó PRTLOGIN, arraste-o e solte dentro da classe SigaWS, isto fará com que o código de chamada ao método seja gerado automaticamente. Em seguida defina os parâmetros para execução da chamada do serviço.

Figura 7 – Definição da classe de execução do Web Service.

 

Executando o projeto neste momento, será verificado o erro citado no início do artigo.

Figura 8 – Erro na execução.

 

Para solucionar o problema, o proposto é adicionar um manipulador de mensagem SOAP e realizar algumas modificações nos dados retornados pelo serviço, assim possibilitando a serialização.

Clique em Arquivo, seguido por Novo Arquivo. Na tela seguinte, selecione em Categorias: “Serviços Web” e em Tipos de arquivos: “Manipulador de mensagens”, clique em Próximo.

Figura 9 – Novo arquivo – Manipulador de mensagens.

 

Informe o nome para o arquivo, neste caso SigaHandler, clique em Finalizar.

Figura 10 – Novo manipulador de mensagens.

 

Com o arquivo gerado o código deverá ficar desta forma:

package sigaws.ws;
 
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
 
/**
 *
 * @author Eduardo Folly
 */
public class SigaHandler implements SOAPHandler {
 
    @Override
    public boolean handleMessage(SOAPMessageContext messageContext) {
        boolean outbound = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
 
        if (outbound) {
            try {
                SOAPMessage msg = messageContext.getMessage();
 
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                msg.writeTo(baos);
                String teste = baos.toString(getMessageEncoding(msg));
                teste = teste.replaceAll("S:", "soap:");
                teste = teste.replaceAll("S=", "soap=");
 
                Source src = new StreamSource(new java.io.StringReader(teste));
                msg.getSOAPPart().setContent(src);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return true;
    }
 
    @Override
    public Set getHeaders() {
        return Collections.EMPTY_SET;
    }
 
    @Override
    public boolean handleFault(SOAPMessageContext messageContext) {
        return true;
    }
 
    @Override
    public void close(MessageContext context) {
    }
 
    private String getMessageEncoding(SOAPMessage msg) throws SOAPException {
        String encoding = "utf-8";
        if (msg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING) != null) {
            encoding = msg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING).toString();
        }
        return encoding;
    }
}

 

Assim o resultado final da classe é apresentado.

Figura 11 – Classe SigaHandler.

 

Agora é necessário relacionar o manipulador de mensagens com o serviço USERPORTAL. Para isto na aba Projetos clique com o botão direito do mouse no serviço USERPORTAL, seguido por Configurar manipuladores…

Figura 12 – Configurar manipuladores…

 

Na próxima tela, clique em Adicionar.

Figura 13 – Configurar os manipuladores de mensagens.

 

Selecione o arquivo manipulador, neste caso o arquivo SigaHandler.java, e clique em OK.

Figura 14 – Selecionar classe de manipuladores de mensagens.

 

Após a confirmação será exibido o manipulador de mensagens associado ao serviço. Clique em OK.

Figura 15 – Associação do manipulador de mensagens.

 

Desta forma a execução do programa funciona perfeitamente.

Figura 16 – Execução do programa.

 

Considerações finais.

Até o presente momento a Totvs não disponibilizou uma modificação no padrão do retorno da mensagem do serviço Web para o Protheus 10.

Gostaria de agradecer a Vicente de Paula (vicenterecife@gmail.com) por ter originado os questionamentos que deram origem a este artigo.