Caros Amigos, Venho através deste tópico postar uma maneira de consumir um web service via wsdl, e tanto como enviar dados e receber dados..... vou postar aqui como deve ser utilizando.... Primeira mente criar um include wsd.i que irá ser incluída nos dois programas um que será a interface.w e outro que será o que faz a comunicação com web serve wsd.p. bom vamos lá a include criada dever conter os seguintes códigos. define {1} shared temp-table tt-dadosenvio field (nomedocampoque tem no webserve) as char format "x(300)" field (nomedocampoque tem no webserve) as char format "x(300)" . define {1} shared temp-table tt-dadosretorno field (nomedocampoque tem no webserve) as char format "x(40)" field (nomedocampoque tem no webserve)as char format "x(40)" field (nomedocampoque tem no webserve) as char format "x(40)" field (nomedocampoque tem no webserve) as char format "x(40)". Agora vamos ao interface.w que é o programa que chama o programa wsd.p sua include ----- lembrando tem que passar como new aqui neste programa. {include/wsd.i "new"} for each tt-dadosenvio: delete tt-dadosenvio. end. create tt-dadosenvio. assign tt-(nomedocampoque tem no webserve) = "Valores da tag" tt-(nomedocampoque tem no webserve) = 'Valores da tag'. run wsdl.p ( input "x", input "y", input "z", input "d", input "c"). for each tt-dadosretorno: disp tt-(nomedocampoque tem no webserve) tt-(nomedocampoque tem no webserve) tt-(nomedocampoque tem no webserve) format "x(70)" tt(nomedocampoque tem no webserve) end. após isso criamos o que se comunica com web server wsdl.p parâmetros define input param x as char. define input param y as char. define input param z as char. define input param d as char. define input param c as char. {include/wsdl.i " "} include ciriada mas com parâmetro em branco. DEFINE VARIABLE hWebService AS HANDLE NO-UNDO. DEFINE VARIABLE hTMMWebSvcs AS HANDLE NO-UNDO. DEFINE VARIABLE hXdoc AS HANDLE. DEFINE VARIABLE hXnoderef1 AS HANDLE. DEFINE VARIABLE hXnoderef2 AS HANDLE. DEFINE VARIABLE hXnoderef3 AS HANDLE. DEFINE VARIABLE hXtext AS HANDLE. DEFINE VARIABLE cUsername AS CHARACTER INIT "seu usuario". DEFINE VARIABLE cPassword AS CHARACTER INIT "seu passorwd". DEFINE VARIABLE g_header AS HANDLE. DEFINE VARIABLE hConsultaValorPortType AS HANDLE NO-UNDO. DEFINE VARIABLE ConsultaValor AS LONGCHAR NO-UNDO. DEFINE VARIABLE ConsultaValorResponse AS LONGCHAR NO-UNDO. DEFINE VARIABLE ConsultaValorEnvia AS LONGCHAR NO-UNDO. DEFINE VARIABLE hDocxml AS HANDLE NO-UNDO. DEFINE VARIABLE hRootxml AS HANDLE NO-UNDO. DEFINE VARIABLE hRow AS HANDLE NO-UNDO. DEFINE VARIABLE hRow1 AS HANDLE NO-UNDO. DEFINE VARIABLE hRow2 AS HANDLE NO-UNDO. DEFINE VARIABLE hRow3 AS HANDLE NO-UNDO. DEFINE VARIABLE hField AS HANDLE NO-UNDO. DEFINE VARIABLE hText AS HANDLE NO-UNDO. DEFINE VARIABLE hBuf AS HANDLE NO-UNDO. DEFINE VARIABLE hDBFld AS HANDLE NO-UNDO. DEFINE VARIABLE ix AS INTEGER NO-UNDO. DEFINE VARIABLE longstring AS LONGCHAR NO-UNDO. RUN BuildRequestHeader (OUTPUT g_header). CREATE SERVER hWebService. hWebService:CONNECT(seu wsdl). RUN WebServiceGeralSoap SET hConsultaValorPortType ON hWebService. hConsultaValorPortType:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "ReqHandler"). cria o xml de envio... CREATE X-DOCUMENT hDocxml. CREATE X-NODEREF hRootxml. CREATE X-NODEREF hRow. CREATE X-NODEREF hRow1. CREATE X-NODEREF hRow2. CREATE X-NODEREF hRow3. CREATE X-NODEREF hField. CREATE X-NODEREF hText. hBuf = BUFFER tt-dadosenvio:HANDLE. hDocxml:CREATE-NODE(hRootxml,"soapenv:Envelope","ELEMENT"). hDocxml:APPEND-CHILD(hRootxml). hRootxml:set-attribute("xmlns:soapenv","http://schemas.xmlsoap.org/soap/envelope/"). hRootxml:set-attribute("xmlns:tem","http://www.tempuri.org"). hDocxml:CREATE-NODE(hRow,"LinhasList","ELEMENT"). hRootxml:APPEND-CHILD(hRow). FOR EACH tt-dadosenvio: hDocxml:CREATE-NODE(hRow1,"Linha","ELEMENT"). hRow:APPEND-CHILD(hRow1). REPEAT ix = 1 TO hBuf:NUM-FIELDS: hDBFld = hBuf:BUFFER-FIELD(ix). IF hDBFld:NAME = "tt-dadosenvio.RecordType" OR hDBFld:NAME = "Name" THEN NEXT hDocxml:CREATE-NODE(hField, hDBFld:NAME, "ELEMENT"). hRow1:APPEND-CHILD(hField). hDocxml:CREATE-NODE(hText, "", "TEXT"). hField:APPEND-CHILD(hText). hText:NODE-VALUE = STRING(hDBFld:BUFFER-VALUE). END. end. hDocxml:CREATE-NODE(hRow2,"Trailer","ELEMENT"). hRootxml:APPEND-CHILD(hRow2). hDocxml:CREATE-NODE(hRow1,"Usuario","ELEMENT"). hRow2:APPEND-CHILD(hRow1). hDocxml:CREATE-NODE(hText, "", "TEXT"). hRow1:APPEND-CHILD(hText). hText:NODE-VALUE = parametro x. hDocxml:CREATE-NODE(hRow1,"Email","ELEMENT"). hRow2:APPEND-CHILD(hRow1). hDocxml:CREATE-NODE(hText, "", "TEXT"). hRow1:APPEND-CHILD(hText). hText:NODE-VALUE = y. hDocxml:CREATE-NODE(hRow1,"Programa","ELEMENT"). hRow2:APPEND-CHILD(hRow1). hDocxml:CREATE-NODE(hText, "", "TEXT"). hRow1:APPEND-CHILD(hText). hText:NODE-VALUE = parametro z hDocxml:CREATE-NODE(hRow1,"TipoTransacao","ELEMENT"). hRow2:APPEND-CHILD(hRow1). hDocxml:CREATE-NODE(hText, "", "TEXT"). hRow1:APPEND-CHILD(hText). hText:NODE-VALUE = parametro d . hDocxml:CREATE-NODE(hRow3,"Interface","ELEMENT"). hRootxml:APPEND-CHILD(hRow3). hDocxml:CREATE-NODE(hText, "", "TEXT"). hRow3:APPEND-CHILD(hText). hText:NODE-VALUE = parametro c. aqui vem a jogada de enviar o arquivo para o web service em uma longchar hDocxml:SAVE("longchar", ConsultaValorEnvia). se quiser enviar o xml para um diretorio segue o comando /*hDocxml:SAVE("file":U,"e:\luizazevedo\cust.xml":U).*/ DELETE OBJECT hDocxml. DELETE OBJECT hRootxml. DELETE OBJECT hRow. DELETE OBJECT hRow1. DELETE OBJECT hRow2. DELETE OBJECT hField. DELETE OBJECT hText. envia para o webservice e retorna xml RUN Executar IN hConsultaValorPortType(input ConsultaValorEnvia, output ConsultaValorResponse). monta o retorno def var Hdoc as handle. def var Hroot as handle. create x-document HDoc. Hdoc:load("LONGCHAR",ConsultaValorResponse,false). create x-noderef hroot. hDoc:get-document-element(hroot). create x-noderef hc. do loop = 1 to vh:num-children: vh:get-child(hc,loop). run obtemnode (input hc:handle). case vh:name : when "Type" then do: create tt-dadosretorno. if hc:node-value <> "" then assign tt-dadosretorno. campo da sua tabela de retorno = hc:node-value. end. when "recordtype" then do: if hc:node-value <> "" then assign tt-dadosretorno.campo da sua tabela de retorno = hc:node-value. end. when "Texto" then do: if hc:node-value <> "" then assign tt-dadosretorno. campo da sua tabela de retorno = hc:node-value. end. when "Mensagem" then do: if hc:node-value <> "" then assign tt-dadosretorno. campo da sua tabela de retorno = hc:node-value. end. end case. end. run obtemnode (input hroot). procedure obtemnode. def input parameter vh as handle. def var hc as handle. def var loop as int. end. DELETE OBJECT hConsultaValorPortType. hWebServiceISCONNECT(). DELETE OBJECT hWebService. /**************** Internal Procedures ****************/ PROCEDURE ReqHandler: /* Define procedure parameters */ DEFINE OUTPUT PARAMETER hHeader AS HANDLE. DEFINE INPUT PARAMETER cNamespace AS CHARACTER. DEFINE INPUT PARAMETER cLocalNS AS CHARACTER. DEFINE OUTPUT PARAMETER lDeleteOnDone AS LOGICAL. /* Pass in global header reused for every request */ hHeader = g_header. lDeleteOnDone = FALSE. END PROCEDURE. PROCEDURE BuildRequestHeader: /* Define procedure parameter */ DEFINE OUTPUT PARAMETER hHeader AS HANDLE. DEFINE VARIABLE hHeaderEntryref AS HANDLE. DEFINE VARIABLE ClientNS AS CHARACTER initial "http://ServiceHost/SOAPHeader" . assign ClientNS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd". /* Create SOAP header and server objects */ CREATE SOAP-HEADER hHeader. CREATE SOAP-HEADER-ENTRYREF hHeaderEntryref. /* Create x-doc objects to build header */ CREATE X-DOCUMENT hXdoc. CREATE X-NODEREF hXnoderef1. CREATE X-NODEREF hXnoderef2. CREATE X-NODEREF hXnoderef3. CREATE X-NODEREF hXtext. /* Create the header entry */ hHeader:ADD-HEADER-ENTRY(hHeaderEntryref). /* Create the header namespace data */ hXdoc:CREATE-NODE-NAMESPACE(hXnoderef3, ClientNS, "Security", "ELEMENT"). hXdoc:CREATE-NODE-NAMESPACE(hXnoderef1, ClientNS, "UsernameToken", "ELEMENT"). hXdoc:INSERT-BEFORE(hXnoderef1, ?). /* Create the Username/Password data */ hXdoc:CREATE-NODE-NAMESPACE(hXnoderef2, ClientNS, "Username", "ELEMENT"). hXnoderef1:APPEND-CHILD(hXnoderef2). hXdoc:CREATE-NODE(hXtext,"","text"). hXnoderef2:APPEND-CHILD(hXtext). hXtext:NODE-VALUE = cUsername. hXdoc:CREATE-NODE-NAMESPACE(hXnoderef2, ClientNS, "Password", "ELEMENT"). hXnoderef1:APPEND-CHILD(hXnoderef2). hXdoc:CREATE-NODE(hXtext, "", "text"). hXnoderef2:APPEND-CHILD(hXtext). hXtext:NODE-VALUE = cPassword. hXnoderef3:APPEND-CHILD( hXnoderef1 ). /* Fill the header entry using a deep copy */ hHeaderEntryref:SET-NODE(hXnoderef3). hHeaderEntryref:SET-MUST-UNDERSTAND ( TRUE ). /* Procedure/header cleanup */ DELETE OBJECT hXdoc. DELETE OBJECT hXnoderef1. DELETE OBJECT hXnoderef2. DELETE OBJECT hXtext. DELETE OBJECT hHeaderEntryref. END PROCEDURE. Graças as duvidas esclarecidas aqui em alguns foruns que postei me ajudaram a chegar a este resultado, então espero que ajuda a outros. muito obrigado pela ajuda de todos.
Bah que bom .. eu ainda não consegui resolver meu problema com o WEBSERVICE... tanto que foi necessário usar uma muleta com java para resolver. Irei testar .. vlw
Espero que te ajude, esse exemplo é usado até hoje pela antiga empresa que trabalhei, esse modelo é padrão lá, existem varias interfaces que se comunicam via este arquivo com wsdl para um outro programa. demorei bastante para desenvolver o mesmo, e depois que funcionou, putz era só alegria...... abraço
Só uma observação, se me permitem. O método mais rápido pra apagar uma temp-table é: EMPTY TEMP-TABLE nome-da-tabela NO-ERROR. /* ERROR-STATUS pode ser tradado caso a operação falhe */ Nota: Um detalhe é que a TEMP-TABLE tem que ser definida com NO-UNDO. Fiz um teste, uns anos atrás, pra ver qual método era mais rápido pois estava com uma TEMP-TABLE de tamanho considerável que precisava ser apagada e recriada algumas vezes. Testei os três métodos que conhecia àquela época: DELETE OBJECT (Neste caso criei a TEMP-TABLE em um HANDLE primeiro), FOR EACH.. DELETE e EMPTY TEMP-TABLE (se não me engano incorporado à versão 9). Para TEMP-TABLEs pequenas as diferenças são imperceptíveis. Espero ter ajudado. Obrigado.
Olá! Eu consegui acessar um webservice da receita (NF-e) onde retorna uma resposta informando que o schema é inválido. Isso é devido a ter que enviar dados no HEADER da mensagem SOAP. O xml que preciso enviar no HEADER é este: <ns0:nfeCabecMsg xmlns:ns0=" + '"' + "http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico3" + '"' + ">" + "<ns0:cUF>41</ns0:cUF>" + "<ns0:versaoDados>3.10</ns0:versaoDados>" + "</ns0:nfeCabecMsg>. A minha pergunta é... supondo que tenha esse xml em uma longchar, como usa-la na procedure PROCEDURE ReqHandler, que, pelo que entendi, é onde deve-se informar os valores pra ser usado no HEADER!? vlw!