Você está na página 1de 32

TUDO SOBRE WEBSERVICE

WebService
Passo a Passo
O primeiro passo é configurar o webservice, uma maneira simples é utilizando o TotvsWizard que se localiza na pasta smartclient
dentro do diretório bin. O exemplo abaixo nos mostra como deve ser realizado o processo de configuração no TotvsWizard.

Outra forma de configurar o webservice seria de forma manual, segundo estudiosos é menos recomendado, mas se ainda sim
preferir pode ser configurado direto no totvsappserver.ini dentro da pasta appserver do diretório bin.

Totvswizard

Inclua na aba Módulos Web uma instancia Ws.

Em seguida relacione a empresa com o host


TotvsWizard
E no final aparecerá uma tela para confirmar o host virtual de acordo com as configurações passadas anteriormente.

TotvsWizard
Pronto já possui uma configuração de webservice no seu totvsappserver.ini.
Agora provavelmente seu totvsappserver.ini esta conforme descrito abaixo:

(Lembrando que refere apenas a parte sobre webservice).

Código
[HTTP]
1
2 enable=1

4 path=C:\Protheus10\ajuda\Protheus10help\

5
port=81
6

7
[ONSTART]
8

9
JOBS=JOB_WS_9901
10

11
[Localhost:81]
12

13
ENABLE=1
14

15 PATH=C:\Protheus10\Protheus_Data\web\ws\
16

17 ENVIRONMENT=PROTHEUS
18

19 INSTANCENAME=Ws

20

21 RESPONSEJOB=JOB_WS_9901

22

23 DEFAULTPAGE=wsindex.apw

24
[JOB_WS_9901]
25

26
TYPE=WEBEX
27

28
ENVIRONMENT=PROTHEUS
29

30
INSTANCES=1,20
31

32
SIGAWEB=WS
33

34 INSTANCENAME=Ws
35
36 ONSTART=__WSSTART

37

38 ONCONNECT=__WSCONNECT

39
PREPAREIN=99,01
40

41

42

43

Se mantiver da forma descrita acima seu help vai para de funcionar então configure assim:

Código
[HTTP]
1

2
enable=1
3

4
port=81
5

6
[Localhost:81/help]
7

8 ENABLE=1
9

10 path=C:\Protheus10\ajuda\Protheus10help\

11

12 DEFAULTPAGE=menuprotheus10.htm

13

14 [ONSTART]

15
JOBS=JOB_WS_9901
16

17
[Localhost:81/ws]
18

19
ENABLE=1PATH=C:\Protheus10\Protheus_Data\web\ws
20

21
ENVIRONMENT=PROTHEUS
22

23
INSTANCENAME=Ws
24

25 RESPONSEJOB=JOB_WS_9901

26

27 DEFAULTPAGE=wsindex.apw

28
[JOB_WS_9901]
29

30
TYPE=WEBEX
31

32
ENVIRONMENT=PROTHEUS
33

34
INSTANCES=1,20
35

36
SIGAWEB=WS
37

38 INSTANCENAME=Ws
39

40 ONSTART=__WSSTART

41

42 ONCONNECT=__WSCONNECT

43

44 PREPAREIN=99,01

45

46

47

Pronto seu totvsappserver.ini está configurado corretamente.

Agora vamos verificar se o webservice foi habilitado.

Digite no browser a url ( http://localhost:81/ws/WSINDEX.apw ) e aparecerá a seguinte imagem:


WebService
Pronto seu Webservice está habilitado.
Vamos agora iniciar a criação de um código fonte voltado ao desenvolvimento de um webservice.

Primeiramente abra o IDE do Protheus que se encontra na pasta SmartClient e cole o seguinte fonte:

Código

1 #INCLUDE "APWEBSRV.CH"

3 #INCLUDE "PROTHEUS.CH"

5 WSSERVICE WSADVPLBRASIL DESCRIPTION "Serviço com a finalidade de mostrar um exemplo


de webservice"
6

7
WSDATA cString as String
8

9 WSMETHOD RetornaUrl DESCRIPTION "Método que retorna a url do site"


10

11 ENDWSSERVICE
12

13 WSMETHOD RetornaUrl WSRECEIVE NULLPARAM WSSEND cString WSSERVICE WSADVPLBRASIL

14

15 ::cString := "http://advplbrasil.com.br/"

16

17 Return .T.

Compile e em seguida abra o browser e digite a url ( http://localhost:81/ws/WSINDEX.apw ) verifique se já esta disponível o
webservice criado como mostra a figura abaixo:
WebService AdvplBrasil
Agora uma das partes mais importante de um clique em cima do webservice WSADVPLBRASIL e aparecerá uma tela
descrevendo os métodos e informando o WSDL a ser utilizado.

Wsdl AdvplBrasil
Segundo Outras Documentações:
O WSDL( Web Services Description Language ) : Trata-se de um documento, em formato de acordo com as definições de Web
Services, através do qual um provedor de um serviço provê a discriminação detalhada das funcionalidades de um serviço. Este
documento em geral é fornecido através de uma URL, apontando para o servidor que provê o serviço. Utilizando este documento,
o Protheus é capaz de gerar automaticamente um ‘Fonte Client’ para estabelecer a conexão e utilização do serviço, através da
geração de uma classe ‘Client’ em Advpl.

Parabéns seu Webservice está criado e pronto para ser utilizado.


Consumindo um Webservice
Iniciamos agora a segunda etapa gerar um client do webservice que criamos.
Para isso basta pegar o wsdl que vimos acima e colocar no IDE Protheus especificamente em Menu Ferramentas – Gerar Cliente
Webservices…

A proposito não esqueça de colocar a url com o localhost pois senão ocorrerá erro:

http://localhost:81/ws/WSADVPLBRASIL.apw?WSDL
Url AdvplBrasil
Em seguida verifique como ficou o código fonte.
O código fonte tem que ficar com as seguintes características:

Código
#INCLUDE "PROTHEUS.CH"
1

2
#INCLUDE "APWEBSRV.CH"
3

4
/* ===============================================================================
5

6
WSDL Location http://localhost:81/ws/WSADVPLBRASIL.apw?WSDL
7

8 Gerado em 04/19/11 09:53:12


9

10 Observações Código-Fonte gerado por ADVPL WSDL Client 1.090116

11

12 Alterações neste arquivo podem causar funcionamento incorreto

13

14 e serão perdidas caso o código-fonte seja gerado novamente.

15
=============================================================================== */
16

17
User Function _MGVQMBQ ; Return // "dummy" function - Internal Use
18

19
/* -------------------------------------------------------------------------------
20

21
WSDL Service WSWSADVPLBRASIL
22

23
------------------------------------------------------------------------------- */
24

25 WSCLIENT WSWSADVPLBRASIL

26

27 WSMETHOD NEW

28
WSMETHOD INIT
29

30
WSMETHOD RESET
31

32
WSMETHOD CLONE
33

34
WSMETHOD RETORNAURL
35

36
WSDATA _URL AS String
37

38 WSDATA cRETORNAURLRESULT AS string


39

40 ENDWSCLIENT

41

42 WSMETHOD NEW WSCLIENT WSWSADVPLBRASIL

43

44 ::Init()

45

46 If !FindFunction("XMLCHILDEX")

47
UserException("O Código-Fonte Client atual requer os executáveis do Protheus Build [7.00.
48
novamente utilizando o Build atual.")
49

50 EndIf
51

52 Return Self

53

54 WSMETHOD INIT WSCLIENT WSWSADVPLBRASIL

55

56 Return

57
58 WSMETHOD RESET WSCLIENT WSWSADVPLBRASIL

59

60 ::cRETORNAURLRESULT := NIL

61
::Init()
62

63
Return
64

65
WSMETHOD CLONE WSCLIENT WSWSADVPLBRASIL
66

67
Local oClone := WSWSADVPLBRASIL():New()
68

69
oClone:_URL := ::_URL
70

71 oClone:cRETORNAURLRESULT := ::cRETORNAURLRESULT
72

73 Return oClone
74

75 // WSDL Method RETORNAURL of Service WSWSADVPLBRASIL

76

77 WSMETHOD RETORNAURL WSSEND NULLPARAM WSRECEIVE cRETORNAURLRESULT WSCLIENT WSWSADVPLBRASIL

78

79 Local cSoap := "" , oXmlRet

80
BEGIN WSMETHOD
81

82
cSoap += '<RETORNAURL xmlns="http://localhost:81/">'
83

84
cSoap += "</RETORNAURL>"
85

86
oXmlRet := SvcSoapCall( Self,cSoap,;
87

88
"http://localhost:81/RETORNAURL",;
89

90 "DOCUMENT","http://localhost:81/",,"1.031217",;
91
92 "http://localhost:81/ws/WSADVPLBRASIL.apw")

93

94 ::Init()

95
::cRETORNAURLRESULT := WSAdvValue( oXmlRet,"_RETORNAURLRESPONSE:_RETORNAURLRESULT:TEXT","
96

97
END WSMETHOD
98

99
oXmlRet := NIL
100

101
Return .T.
102

103

104

105

106

107

Agora salve o arquivo com o código acima, adicione no gerenciador de projetos no IDE Protheus e compile.

Por fim chegamos a ultima etapa a criação do código fonte para consumir o webservice criado.

Ainda no IDE Protheus abra um novo e utilize o código abaixo:

Código

1
#INCLUDE 'PROTHEUS.CH'
2

3 User Function TesteWs()


4

5 Local oWs := NIL

7 oWs := WSWSADVPLBRASIL():New()

9 If oWs:RETORNAURL()

10
alert('Url do Site : '+ oWs:cRETORNAURLRESULT)
11

12
Else
13
14

15 alert('Erro de Execução : '+GetWSCError())

16

17 Endif

18
Return
19

Compile e execute dentro do Protheus o resultado será:

Se chegar até aqui já pode se considerar um vencedor !!!

Parabéns …

Webservice no Protheus de verdade


Criando um Webservice no Protheus e utilizando no C# ou no PLSQL.

Boa noite, faz um tempo que não posto nada, ando meio ocupado por isso parei de postar. Nem sei se alguém
acessa este blog, mesmo assim pra quem der azar de cair aqui, vou postar um exemplo completo e muito bem
detalhado de como montar um WebService no Protheus desde a configuração até a publicação e consumo pelo o
Protheus ou pelo C#.

Como é um artigo muito longo, vou postando durante a semana e farei por partes.

Na primeira parte, vou postar como montar o serviço do WebService e sua configuração.

Em que situação devo utilizar o WebService


Para quem é novo e não conhece, o WebService tem uma enorme utilidade para integração, compartilhamento de
informações, troca de dados, etc.

Não vou detalhar o que é já que no google existem diversos artigos, páginas que explicam com muito mais detalhe
o que é, mas de forma muito resumida, é uma forma de troca de dados e acesso á métodos entre sistemas
diferentes.
Exemplificando... como se beneficiar do WebService no Protheus .

Cenário 1

Tenho uma empresa que compra e distribui produtos de um segmento qualquer. Esta possui um portal onde expõe
seus produtos.

Outras empresas de varejo também possuem portais onde vendem desta vez para o consumidor final.

A empresa de varejo não mantem estoque e nem o prazo de entrega da mercadoria.

Para que o consumidor final deste portal saiba do estoque e prazo de entrega, seria necessário acessar a base de
dados do fornecedor de origem para consultar estes dados.

Então entra o WebService. O site da empresa varejista, acessa o banco de dados da empresa fornecedora através
de acesso aos métodos que estão armazenados no WebService.

A programação deste serviço não importa. Pode ser feita em Delphi, C#, ADVPL, PLSQL, etc... O importante é a
troca de dados que é feita através do protocolo SOAP que é padrão para todos estes sistemas.

A possibilidade de consultar ou executar um comando no banco de dados entre a empresa A e a empresa B viabiliza
o uso.

Cenário 2

Possuo o ERP Protheus em minha empresa. Para envio das notas fiscais eletrônicas, é necessário consumir o
WebService do Governo. O Governo por sua vez, não permite e não confia que as empresas possam jogar, consultar
e manipular as informações deste cadastro.

Desta forma o Governo disponibiliza um WebService, onde o Protheus acessa de forma INDIRETA e CONTROLADA o
banco de dados e os métodos armazenados neste WebService.

De uma forma mais tosca de explicar, é poder trocar informações entre múltiplos sistemas sem que eu acesse de
forma direta o banco de dados ou aplicação.

Cenário 3

Uma empresa possui um sistema legado e precisa acessar funções padrão do Protheus ou outro ERP qualquer. O
sistema legado não sabe como chegar em uma determinada informação, mas sabe que determinada função dentro
do Protheus faz isso.

O sistema legado não tem como acessar o Protheus e chamar determinada função.

Como solução, é criado um WebService no Protheus que disponibiliza esta função. Esta função pode ser acessada
pelo sistema legado, pelo próprio Protheus ou qualquer outro que utilize o protocolo SOAP.

Resumindo, esta troca de dados pode ser utilizada em SmartPhones, portais, aplicações Desktop, etc.

Para os que tem alguma duvida de como funciona e até mesmo o que é, no do Wikipedia explica de forma bem
intuitiva o seu funcionamento.
Webservice no Protheus - Parte 1 - Configurando o Protheus
Configurando o WebService no Protheus

Antes de iniciarmos o estudo do WebService, é imprescindível a configuração do serviço do Protheus.

Para isto devemos ter um serviço separado dos outros. A separação é recomendada mas não é obrigatória.

Não estou explicando de forma detalhada cada linha da configuração abaixo, devido a documentação estar
disponível no portal TDN da Totvs. Estou focando no uso geral da aplicação WebService.

Abaixo, segue um modelo do WebService que utilizo

[WEBSERVICE]

SourcePath=E:\PROTHEUS11\APO\WEBSERVICE

RootPath=E:\PROTHEUS11\Protheus_Data

StartPath=\system\

x2_path=

RpoDb=Top

RpoLanguage=portuguese

RpoVersion=110

LocalFiles=ads

Trace=0

localdbextension=.dbf

PictFormat=AMERICAN

DateFormat=DEFAULT

RegionalLanguage=BRA

Note que no trecho acima, não tem nada de diferente do que utilizamos normalmente.

[192.168.14.33:82/ws]

ENABLE=1

PATH=e:\Protheus11\Protheus_Data\web\ws

ENVIRONMENT=WEBSERVICE

INSTANCENAME=Ws

RESPONSEJOB=JOB_WS_9901

DEFAULTPAGE=wsindex.apw
No trecho acima, estamos configurando o endereço, nome do ambiente, nome dos jobs e página de índice com os
nomes dos serviços disponíveis do nosso WebService.

[JOB_WS_9901]

TYPE=WEBEX

ENVIRONMENT=WEBSERVICE

INSTANCES=1,80

SIGAWEB=WS

INSTANCENAME=Ws

ONSTART=__WSSTART

ONCONNECT=__WSCONNECT

No trecho acima, mencionamos o nome do Job, ambiente, quantidade de instâncias simultâneas.

[TopConnect]

DataBase=ORACLE

Server=NOMESERVIDOR

ALIAS=PROTHEUS

PROTHEUSONLY=0

[Drivers]

Active=TCP

[TCP]

TYPE=TCPIP

Port=1255

[General]

InstallPath=E:\PROTHEUS11

[LICENSECLIENT]

SERVER=SERVIDORLICENCA

port=5555

[HTTP]

enable=1

port=82

PATH=e:\PROTHEUS11\PROTHEUS_DATA\web\ws
ENVIRONMENT=WEBSERVICE

[MAIL]

Protocol=POP3

Webservice no Protheus - Parte 2 - Montando uma aplicação básica


A partir deste post, você vera como testar uma aplicação básica

Montagem da classe do Webservice


Este Webservice terá a finalidade retornar os dados do cliente no Protheus, a aplicação .NET ira enviar uma
solicitação que poderia ser no formato de um XML ou por passagem simples por parâmetros.

Para não complicar muito, o primeiro exemplo de passagem de parâmetros é mais indicado.

O resultado final é o retorno do Nome do cliente, endereço, bairro, cidade, uf e CEP.

A passagem de parâmetros será o código do cliente e a loja.

No exemplo abaixo, não fiz nenhum tipo de validação e não estou preocupado com isso neste momento, fica a
cargo de meus leitores corrigir o programa.
Em meus projetos consulto usuários, bloqueio senhas, envio estruturas complexas de XML, etc.

Então, mão na massa.

Primeiro, crie um arquivo no seu projeto, no meu caso criei com o nome MeuPrimeiroWebService.PRW

#INCLUDE 'PROTHEUS.CH'

#INCLUDE "XMLXFUN.CH"

#INCLUDE "APWEBSRV.CH"

#include "topconn.ch"

#INCLUDE "RWMAKE.CH"

#INCLUDE "TBICONN.CH"

#INCLUDE "ERROR.CH"

// Estrutura de dados. Montagem do Array de retorno

// Não necessariamente retorna-se em um Array, pode ser possível retornar em uma string
simples,

// neste caso não utilizaria uma Estrutura

WSSTRUCT AWSRTDados

WSDATA ClienteNome AS String

WSDATA ClienteEndereco AS String

WSDATA ClienteBairro AS String

WSDATA ClienteCidade AS String


WSDATA ClienteUF AS String

WSDATA ClienteCEP As String

ENDWSSTRUCT

// WebService
WSSERVICE MeuPrimeiroWebService DESCRIPTION "Descrição do meu primeiro WebService"

// Passagem dos parâmetros de entrada

WSDATA ClienteCodigo AS string

WSDATA ClienteLoja AS string

// Retorno de um array que deve retornar a COLUNA 1, COLUNA 2

WSDATA aRetornoCliente AS ARRAY OF AWSRTDados

// Descrição dos métodos que o WEBSERVICE pode possuir

/*WSMETHOD ExcluiOrdem DESCRIPTION "Efetua a exclusão de uma ordem de


faturamento"

WSMETHOD DeletaNfSaida DESCRIPTION "Consulta ou exclui uma nota fiscal de


vendas"

WSMETHOD DeletaNfEntrada DESCRIPTION "Consulta ou exclui uma nota fiscal de


compras"

WSMETHOD AtualizaProduto DESCRIPTION "Inclui / Altera um produto no Microsiga


SB1"

WSMETHOD MeuXML DESCRIPTION "Meu XML"

WSMETHOD SenhaProtheus DESCRIPTION "Teste se a senha esta Ok"*/

WSMETHOD ConsultarCliente DESCRIPTION "Retorna os dados do cliente"

ENDWSSERVICE

/************************************************************************************

** Consulta os dados do cliente

** Abaixo, separei o que se refere do webservice da aplicação que realmente ira

** processar os dados. Lembrando que não é obrigatório

************************************************************************************/
WSMETHOD ConsultarCliente WSRECEIVE ClienteCodigo, ClienteLoja WSSEND aRetornoCliente W
SSERVICEMeuPrimeiroWebService

Local aRetFuncao := {}

aRetFuncao := u_xxRtCliente(::ClienteCodigo,::ClienteLoja) // Passagem de


parâmetros para rotina
aAdd(::aRetornoCliente, WSClassNew("AWSRTDados") )

::aRetornoCliente[01]:ClienteNome := aRetFuncao[1][1]

::aRetornoCliente[01]:ClienteEndereco:= aRetFuncao[2][1]

::aRetornoCliente[01]:ClienteBairro := aRetFuncao[3][1]

::aRetornoCliente[01]:ClienteCidade := aRetFuncao[4][1]

::aRetornoCliente[01]:ClienteUF := aRetFuncao[5][1]

::aRetornoCliente[01]:ClienteCEP := aRetFuncao[6][1]

Return .T.

/*************************************************************

** Retorna os dados do cliente

**************************************************************/

User Function xxRtCliente(pClienteCodigo, pClienteLoja)

Local aRetornoDados := {}

Local aTables := { "SA1","SM0" }

Conout(dtoc( Date() )+" "+Time()+ " == Abrindo ambiente TOP CONNECT =======")

RPCSetType( 3 )

RpcSetEnv ( "01", "01", Nil, Nil, "FAT", Nil, aTables )

SA1->(DbSetOrder(1))

SA1->(DbGoTop())

If SA1->(DbSeek(xFilial("SA1") + pClienteCodigo+ pClienteLoja))

aAdd(aRetornoDados ,{SA1->A1_NOME }) // 1

aAdd(aRetornoDados ,{SA1->A1_END }) // 2

aAdd(aRetornoDados ,{SA1->A1_BAIRRO }) // 3

aAdd(aRetornoDados ,{SA1->A1_MUN }) // 4

aAdd(aRetornoDados ,{SA1->A1_EST }) // 5

aAdd(aRetornoDados ,{SA1->A1_CEP }) // 6

Else

aAdd(aRetornoDados ,{Nil}) // 1

aAdd(aRetornoDados ,{Nil}) // 2

aAdd(aRetornoDados ,{Nil}) // 3

aAdd(aRetornoDados ,{Nil}) // 4

aAdd(aRetornoDados ,{Nil}) // 5
aAdd(aRetornoDados ,{Nil}) // 6

Endif

Return aRetornoDados

Feito isto, vamos verificar se não existe nenhum erro na compilação pesquisando pelo o endereço ja configurado. A
configuração expliquei na Parte 1

http://192.168.15.86:889/ws/WSINDEX.apw

Ao clicar no link, aparece a configuração que deve ser utizada no Visual Studio ou qualquer outra aplicação
Vamos agora no Visual Studio...

Em adicionar referência, colar o link MEUPRIMEIROWEBSERVICE.apw?WSDL conforme figura abaixo :

No visual Studio vamos montar uma telinha


Agora, vamos montar um código simples, quero deixar claro que não sou especialista em c#, sou um mero fuçador.

private void button1_Click(object sender, EventArgs e)

// Instanciamos a nossa referência com o WebService do Protheus

ClientWSProtheus.MEUPRIMEIROWEBSERVICESOAPClient aleksandro
= newClientWSProtheus.MEUPRIMEIROWEBSERVICESOAPClient();

// Montamos uma ILIST, poderia ser uma string qualquer, existem diversas formas de fazer

IList<AWSRTDADOS> aRetorno;

// Chamo o método e retorno em um array

aRetorno = aleksandro.CONSULTARCLIENTE(ParamCodigo.Text, ParamLoja.Text);

// Jogo nos campos os dados da empresa

textBox3.Text = aRetorno[0].CLIENTENOME.ToString();

textBox4.Text = aRetorno[0].CLIENTEENDERECO.ToString();

textBox5.Text = aRetorno[0].CLIENTEBAIRRO.ToString();

textBox6.Text = aRetorno[0].CLIENTECIDADE.ToString();

textBox7.Text = aRetorno[0].CLIENTECEP.ToString();

textBox8.Text = aRetorno[0].CLIENTEUF.ToString();

Executando o programa, vejamos o que o Protheus ira retornar


Pronto, a consulta foi feita unicamente pelo WEBSERVICE sem se conectar diretamente na base de dados.

Da mesma forma que podemos fazer uma consulta, também é possível fazer um programa EXECAUTO, ou rodar
rotinas padrão do Protheus.

Esta foi uma forma de fazer, mas existem diversas maneiras. Queria somente ilustrar uma delas.

Webservice no Protheus - Parte 3 - Final


Notas do WebService

Algumas pessoas questionaram porque em alguns casos o Webservice não esta ativo ou porque retorna mensagens
de erro.

No exemplo, quando o WebService não esta HABILITADO procure verificar se existe algum erro na compilação do
programa.
Mesmo compilado com sucesso não quer dizer que a rotina esta correta. Como sabemos, o Protheus não é
fortemente tipado, ou seja, qualquer coisa ele deixa passar.

Se no meio do código escrever PARALELEPÍPEDO e compilar, esta compilação sera feita com sucesso.

Outra coisa, caso retorno Nulo e ocorra um erro, é devido eu não ter tido tempo de fazer a tratativa das exceções,
ando meio corrido e sem tempo para fazer publicações.

Uma correção :
Em NameSpace onde o nome esta ServiceReference1, troquei para ClientWSProtheus.

Vale lembrar que o WebService MeuPrimeiroWebService é possível adicionar diversos métodos.

Sempre que fizer alguma alteração em métodos, na aplicação do Visual Studio ou Java, é necessário atualizar a
referência.

Como premissa, você deve conhecer alguma coisa de ADVPL e do Visual Studio.

Se você gostou do artigo, clique nos links patrocinados.

Saudações.

###############################################################################################

Consumindo web service do Protheus


com JAX-WS
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_PROPE

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.

- See more at: http://www.oslunaticos.com.br/2011/10/consumindo-web-service-do-protheus-com-jax-


ws/#sthash.p6g9iPK0.dpuf

###############################################################################################
Olá, desculpem a pergunta de iniciante.
Sou mais da área de WEB - Java e Dot.net, onde criar um webservice não é bicho de 7 cabeças.
segui passo a passo o descrito no manual online da TOTVS,
http://tdn.totvs.com/home#21324
que diz claramente ser possivel criar um servidor WEBSERVICE a partir de um protheus.
as páginas dos webservices padroes estão funcionando no meu ambiente de teste.
Mas quando vou compilar o exemplo que esta na pagina acima ... segue:

1 #INCLUDE 'PROTHEUS.CH'
2 #INCLUDE 'APWEBSRV.CH'
3
4 WSSERVICE SERVERTIME
5 WSDATA Horario as String
6 WSMETHOD GetServerTime
7 ENDWSSERVICE
8
9 WSMETHOD GetServerTime WSRECEIVE NULLPARAM WSSEND Horario WSSERVICE SERVERINFO
10 ::Horario := TIME()
11 Return .T.

--------
dá este erro:
Erro de compilação:
WSERV.PRW(0) Funções comuns não permitidas no código. Utilize USER FUNCTION ou STATIC FUNCTION.
--------
Por favor , quem for responder, não pergunte porque eu quero saber a hora do servidor, isso é apenas um "exemplo" para testar o
WSMETHOD , ou testar a capacidade se se criar um webservice, a aplicação seria bem mais complexa que isso. Mas se este básico não
compilar, não adianta anexar um código enorme para ser analisado.

Atenciosamente.

Hummm, testes ok, mas o problema não era a extensão do arquivo.

Era no código mesmo ....

WSMETHOD -> deve aparecer duas vezes,


1) na definição do serviço. ( linha 6 )
2) na definição do Methodo ( linha 9 )
---
na linha nove ( 9 ) o parametro WSSERVICE deve ser igual ao nome do serviço, na documentação mal revisada da totus está com o
nome do serviço ERRADO ...
deve ser SERVERTIME e não SERVERINFO.

a extensão deve ser .PRW mesmo, ou PRX como está do object explorer os outros webservices ( eu nao sei a diferença ... )

a extensão .aph, trata-se de página ADVPL - ASP que aceita qualquer coisa , pois trata como html - texto e nunca da erro de compilação
o que esta fora das chaves <% .... %>

Compilei ( como .PRW , e testei por outro programa o acesso e mostrou a data do servidor ) .

##############################################################################################

CONSUMINDO WEBSERVICE DO PROTHEUS EM C# (ARRAY)

Tenho dois webservices desenvolvidos no Protheus(TOTVS) que serão consumidos em minha aplicação em C#
no VS2013(Windows form).

O primeiro sempre retorna uma string e está funcionando perfeitamente, já o segundo retorna um array e esse
eu não consigo consumir de jeito nenhum.

Não é conexão, porque se eu alterar o retorno do segundo webservice para uma string tudo funciona
normalmente, porém como array não consigo fazer o Visual Studio 2013 entender nem a pau.

Ele fica me retornando um erro de "Cannot implicitly convert type" e nada resolve.

Segue o método do webservice publicado e o erro gerado:

WEBSERVICE REQUEST:

<?xml version="1.0" encoding="utf-8"?"


<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<_CFILIAL>STRING</_CFILIAL>
</soap:Body>
</soap:Envelope>
WEBSERVICE RESPONSE

<?xml version="1.0" encoding="utf-8"?"


<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TARRAY>
<TESTEARRAY>
<_CCONTIGENCIA>STRING</_CCONTIGENCIA>
<_CDIGITAL01>STRING</_CDIGITAL01>
<_CDIGITAL02>STRING</_CDIGITAL02>
<_CMATRICULA>STRING</_CMATRICULA>
<_CNOME>STRING</_CNOME>
<_CSITUACAO>STRING</_CSITUACAO>
</TESTEARRAY>
<TESTEARRAY>
<_CCONTIGENCIA>STRING</_CCONTIGENCIA>
<_CDIGITAL01>STRING</_CDIGITAL01>
<_CDIGITAL02>STRING</_CDIGITAL02>
<_CMATRICULA>STRING</_CMATRICULA>
<_CNOME>STRING</_CNOME>
<_CSITUACAO>STRING</_CSITUACAO>
</TESTEARRAY>
</TARRAY>
</soap:Body>
</soap:Envelope>

CONSUMINDO:

WS_FUNCSPONTO.FUNCSPONTO Recebe_Cadastro = new WS_FUNCSPONTO.FUNCSPONTO();


WS_FUNCSPONTO.TESTEARRAY qwert = new WS_FUNCSPONTO.TESTEARRAY();
qwert = Recebe_Cadastro.PEGAINFORM("00");

Consegui resolver! Era quase isso! Ficou assim: WS_FUNCSPONTO.TESTEARRAY[] qwert = new
WS_FUNCSPONTO.TESTEARRAY[50];

Você também pode gostar