Академический Документы
Профессиональный Документы
Культура Документы
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
TotvsWizard
Pronto já possui uma configuração de webservice no seu totvsappserver.ini.
Agora provavelmente seu totvsappserver.ini esta conforme descrito abaixo:
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
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"
7
WSDATA cString as String
8
11 ENDWSSERVICE
12
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.
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
11
13
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
40 ENDWSCLIENT
41
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
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
76
78
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.
Código
1
#INCLUDE 'PROTHEUS.CH'
2
7 oWs := WSWSADVPLBRASIL():New()
9 If oWs:RETORNAURL()
10
alert('Url do Site : '+ oWs:cRETORNAURLRESULT)
11
12
Else
13
14
16
17 Endif
18
Return
19
Parabéns …
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.
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.
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
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.
[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
[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
Para não complicar muito, o primeiro exemplo de passagem de parâmetros é mais indicado.
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.
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"
// Não necessariamente retorna-se em um Array, pode ser possível retornar em uma string
simples,
WSSTRUCT AWSRTDados
ENDWSSTRUCT
// WebService
WSSERVICE MeuPrimeiroWebService DESCRIPTION "Descrição do meu primeiro WebService"
ENDWSSERVICE
/************************************************************************************
************************************************************************************/
WSMETHOD ConsultarCliente WSRECEIVE ClienteCodigo, ClienteLoja WSSEND aRetornoCliente W
SSERVICEMeuPrimeiroWebService
Local aRetFuncao := {}
::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.
/*************************************************************
**************************************************************/
Local aRetornoDados := {}
Conout(dtoc( Date() )+" "+Time()+ " == Abrindo ambiente TOP CONNECT =======")
RPCSetType( 3 )
SA1->(DbSetOrder(1))
SA1->(DbGoTop())
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...
ClientWSProtheus.MEUPRIMEIROWEBSERVICESOAPClient aleksandro
= newClientWSProtheus.MEUPRIMEIROWEBSERVICESOAPClient();
// Montamos uma ILIST, poderia ser uma string qualquer, existem diversas formas de fazer
IList<AWSRTDADOS> aRetorno;
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();
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.
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.
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.
Saudações.
###############################################################################################
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.
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.
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.
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.
Executando o projeto neste momento, será verificado o erro citado no início do artigo.
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.
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();
@Override
public Set getHeaders() {
return Collections.EMPTY_SET;
}
@Override
public boolean handleFault(SOAPMessageContext messageContext) {
return true;
}
@Override
public void close(MessageContext context) {
}
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…
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.
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.
###############################################################################################
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.
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 ) .
##############################################################################################
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.
WEBSERVICE REQUEST:
CONSUMINDO:
Consegui resolver! Era quase isso! Ficou assim: WS_FUNCSPONTO.TESTEARRAY[] qwert = new
WS_FUNCSPONTO.TESTEARRAY[50];