É possível utilizar o appServer para conexões, da forma como usamos o webspeed configurando um servidor web? Minha intenção é usar o webservice padrão do totvs para gerar um xml que vai ser consultado numa página web. Pelo webspeed eu acesso algo como o abaixo: 'http://Servidor/cgi-bin/WService=teuServiço/Programa.p' O programa.p gera um xml apresentado num navegador. Minha intenção é fazer isso pelo appServer.
Pelo que entendo, um AppServer não responde o protocolo Http. Portanto, se você abrir seu navegador (ou Postman) e tentar acessar o endereço do AppServer (http://servidor:5162/nome-appserver), não vai funcionar. No caso do WebSpeed, você consegue acessar porquê o request que você faz cai em um IIS ou Tomcat, que faz a intermediação entre o seu navegador e o o WebSpeed. Pode olhar aí no seu servidor, que você verá um IIS ou Tomcat, e dentro dele haverá um CGI. Dá para montar um web service SOAP usando o AppServer, mas se você quer só retornar um XML, o mais simples é criar um programa .p e disponibiliza-lo no WebSpeed. O programa, por exemplo, retorna um xml. Salve e compile-o no diretório do webspeed, e invoque a url: http://servidor/cgi-bin/wspd_cgi.sh/WService=NOME_DO_SEU_WEBSPEED/meuprograma?formato=xml Observação: Na url acima "meuprograma" é o nome do programa, e não precisa escrever na url a extensão do programa. Lá na pasta do webspeed haverá um arquivo "meuprograma.p" e outro "meuprograma.r" Código: /* Esta include contem funcoes que só funcionam no webspeed; exemplo: get-field(), que pega os parametros do request. */ {src/web/method/cgidefs.i} DEF TEMP-TABLE tt-response NO-UNDO SERIALIZE-NAME "Resumo" FIELD cd-status-request AS INT INIT 200 SERIALIZE-NAME "status" FIELD ds-message AS CHAR INIT "OK" SERIALIZE-NAME "message" FIELD qt-bancos AS INT SERIALIZE-NAME "QuantidadeBancos". DEF TEMP-TABLE tt-tabela NO-UNDO SERIALIZE-NAME "tabelas" FIELD nm-banco AS CHAR SERIALIZE-NAME 'banco' FIELD recid-tabela AS RECID SERIALIZE-HIDDEN FIELD nm-tabela AS CHAR SERIALIZE-NAME "tabela" FIELD ds-tabela AS CHAR SERIALIZE-NAME "descricao" INDEX idx-id IS UNIQUE nm-banco recid-tabela INDEX idx-primario IS PRIMARY nm-tabela. DEF DATASET resposta FOR tt-response, tt-tabela. RUN pr-inicio. PROCEDURE pr-inicio: DEF VAR ix AS INT NO-UNDO. /* Já cria registro de saída. */ CREATE tt-response. ASSIGN tt-response.qt-bancos = NUM-DBS. RUN pr-obter-tabelas-do-banco (INPUT get-field('banco'), INPUT (get-field('systemTables') = 'TRUE'), INPUT-OUTPUT TABLE tt-tabela). END PROCEDURE. /* pr-inicio */ PROCEDURE pr-obter-tabelas-do-banco: DEF INPUT PARAMETER nm-banco-in AS CHAR NO-UNDO. DEF INPUT PARAMETER system-tables-in AS LOG NO-UNDO. DEF INPUT-OUTPUT PARAMETER TABLE FOR tt-tabela. DEF VAR h-buffer AS HANDLE NO-UNDO. DEF VAR h-query AS HANDLE NO-UNDO. DEF VAR ix AS INT NO-UNDO. // Se nenhum banco foi informado, busca todos os bancos. IF nm-banco-in = '' THEN DO: DO ix = 1 TO NUM-DBS: IF NOT system-tables-in AND LDBNAME(ix) = '_progress' THEN NEXT. RUN pr-obter-tabelas-do-banco (INPUT LDBNAME(ix), INPUT system-tables-in, INPUT-OUTPUT TABLE tt-tabela). END. RETURN. END. CREATE BUFFER h-buffer FOR TABLE nm-banco-in + '._file'. CREATE QUERY h-query. h-query:SET-BUFFERS(h-buffer). h-query:QUERY-PREPARE('FOR EACH ' + nm-banco-in + '._file NO-LOCK:'). h-query:QUERY-OPEN. DO WHILE h-query:IS-OPEN: h-query:GET-NEXT(). IF h-query:QUERY-OFF-END THEN LEAVE. IF NOT system-tables-in AND h-query:GET-BUFFER-HANDLE():BUFFER-FIELD('_File-Name'):BUFFER-VALUE BEGINS '_' THEN NEXT. CREATE tt-tabela. ASSIGN tt-tabela.nm-banco = nm-banco-in tt-tabela.recid-tabela = h-query:GET-BUFFER-HANDLE():RECID tt-tabela.nm-tabela = h-query:GET-BUFFER-HANDLE():BUFFER-FIELD('_File-Name'):BUFFER-VALUE tt-tabela.ds-tabela = h-query:GET-BUFFER-HANDLE():BUFFER-FIELD('_Desc'):BUFFER-VALUE. END. FINALLY: IF VALID-HANDLE(h-query) THEN DO: h-query:QUERY-CLOSE. DELETE OBJECT h-query NO-ERROR. END. END FINALLY. END PROCEDURE. // pr-obter-tabelas-do-banco PROCEDURE pr-gera-pagina-html: DEF VAR ix AS INT NO-UNDO. FIND tt-response. {&out} '<head>' '<title>Consulta Registro</title>' '<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">' '</head>' '<body>' '<div class="container-fluid">'. {&out} '<h4 class="text-left">Lista de Tabelas</h4>' '<table class="table table-hover table-sm">' '<thead><tr><th>Banco</th><th>Tabela</th><th>Descricao</th></tr></thead>' '<tbody>'. FOR EACH tt-tabela: {&out} '<tr>' '<td>' tt-tabela.nm-banco '</td>' '<td>' tt-tabela.nm-tabela '</td>' '<td>' tt-tabela.ds-tabela '</td>' '</tr>'. END. {&out} '</tbody>' '</table>'. FINALLY: {&out} '</div>' '<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>' '<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>' '<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>' '</body>'. END FINALLY. END PROCEDURE. // pr-gera-pagina-html FINALLY: FIND FIRST tt-response NO-ERROR. /* * This procedure must be executed before the output-content-type function. */ IF AVAIL tt-response THEN output-http-header("Status":U, STRING(tt-response.cd-status-request)). ELSE output-http-header("Status":U, "500"). output-http-header('Access-Control-Allow-Origin', '*'). output-http-header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'). output-http-header('Access-Control-Allow-Headers', '*'). /** * O comando abaixo escreverá no header do response o "Content-Type". * O "Content-Type" diz para o cliente o tipo do conteúdo, e sem ele ocorrerá erro. * Exemplos de "Content-type": * output-content-type("text/html; charset=utf-8"). * output-content-type("text/plain; charset=iso-8859-1"). * output-content-type("application/json; charset=iso-8859-1"). * output-content-type("application/javascript; charset=iso-8859-1"). * Referencia: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types */ CASE get-field('formato'): WHEN 'xml' THEN DO: output-content-type("application/xml"). DATASET resposta:WRITE-XML("STREAM", /* target-type */ "WEBSTREAM", /* target */ NOT (get-field('pretty') = "false")). /* formatted */ END. WHEN 'json' THEN DO: output-content-type("application/json"). DATASET resposta:WRITE-JSON("STREAM", /* target-type */ "WEBSTREAM", /* target */ NOT (get-field('pretty') = "false")). /* formatted */ END. OTHERWISE DO: output-content-type("text/html; charset=windows-1252"). RUN pr-gera-pagina-html. END. END CASE. END FINALLY.