Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Como a grande maioria das ferramentas de desenvolvimento, o Apache Flex® permite criar stubs para o acesso a WebservicesWebServices. Estes stubs encapsulam todas as operações de empacotamento e desempacotamento das informações do padrão XML para os tipos nativos da plataforma.

...

O trecho de código abaixo apresenta um exemplo de invocação do Webservice WebService de acesso aos Datasets do fluig:

...

Nota

Ao utilizar os WebServices via Java™, deve-se atentar para o tipo de cada atributo e para o tipo de retorno do WebService. Por exemplo, para valores do tipo data deve ser utilizado a classe XMLGregorianCalendar:

Bloco de código
languagejava
themeEclipse
firstline1
linenumberstrue
DocumentDto document = new DocumentDto();

XMLGregorianCalendar date = DatatypeFactory.newInstance().newXMLGregorianCalendar();
date.setYear(2013);
date.setMonth(10);
date.setDay(16);
date.setHour(0);
date.setMinute(0);
date.setSecond(0);

document.setExpirationDate(date);

 

Via Progress® 4GL

Assim como nos exemplos anteriores, o primeiro passo para consumir um Webservice WebService em Progress® é utilizar usar um utilitário que irá ler o endereço WSDL e gerar as informações necessárias para acessá-lo. Diferente do Java™ e Flex®, o Progress® não gera objetos de stub, mas apenas uma documentação sobre como consumir os serviços descritos no arquivo WSDL. Embora em algumas situações seja possível utilizar manipular os tipos nativos do Progress® como parâmetros, dependendo do tipo de dado utilizado é preciso manipular o XML SOAP para extrair ou enviar uma informação.

Para gerar a documentação de um serviço, deve-se utilizar empregar o utilitário bprowsdldoc como no exemplo abaixo:

...

Com a execução deste utilitário, serão gerados alguns arquivos HTML com as informações sobre como consumir o serviço. Esta documentação apresenta informações e exemplos de como realizar a conexão com o serviçoe serviço e a utilizar as os métodos e datatypes do serviço. 

...

Bloco de código
languagejavafx
themeEclipse
firstline1
titlewsECMDatasetService.p
linenumberstrue
/* Parte I - Invocar o WebService */
DEFINE VARIABLE hWebService     AS HANDLE NO-UNDO.
DEFINE VARIABLE hDatasetService AS HANDLE NO-UNDO.

DEFINE VARIABLE cFields  AS CHARACTER EXTENT 0 NO-UNDO.
DEFINE VARIABLE cOrder   AS CHARACTER EXTENT 0 NO-UNDO.
DEFINE VARIABLE cDataset AS LONGCHAR NO-UNDO.

DEFINE TEMP-TABLE item NO-UNDO
    NAMESPACE-URI ""
    FIELD contraintType AS CHARACTER
	FIELD fieldName     AS CHARACTER
	FIELD finalValue    AS CHARACTER
	FIELD initialValue  AS CHARACTER.
 
DEFINE DATASET dConstraints NAMESPACE-URI "http://ws.dataservice.ecm.technology.totvs.com/"
	FOR item.

CREATE SERVER hWebService.
hWebService:CONNECT("-WSDL 'http://localhost:8080/webdesk/ECMDatasetService?wsdl'").
RUN DatasetService SET hDatasetService ON hWebService.

RUN getDataset IN hDatasetService(INPUT 1,
                                  INPUT "adm",
                                  INPUT "adm",
                                  INPUT "colleague",
                                  INPUT cFields,
                                  INPUT DATASET dConstraints,
                                  INPUT cOrder,
                                  OUTPUT cDataset).

DELETE OBJECT hDatasetService.
hWebService:DISCONNECT().
DELETE OBJECT hWebService.

/* Parte II - Faz o parser do XML e criar um arquivo texto separado por tabulacao */
DEFINE VARIABLE iCount  AS INTEGER   NO-UNDO.
DEFINE VARIABLE iCount2 AS INTEGER   NO-UNDO.
DEFINE VARIABLE hDoc    AS HANDLE    NO-UNDO.
DEFINE VARIABLE hRoot   AS HANDLE    NO-UNDO.
DEFINE VARIABLE hValues AS HANDLE    NO-UNDO.
DEFINE VARIABLE hEntry  AS HANDLE    NO-UNDO.
DEFINE VARIABLE hText   AS HANDLE    NO-UNDO.
DEFINE VARIABLE cValue  AS CHARACTER NO-UNDO.

OUTPUT TO c:\dataset.txt.

CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.
CREATE X-NODEREF hEntry.
CREATE X-NODEREF hText.
CREATE X-NODEREF hValues.

hDoc:LOAD("longchar", cDataset, FALSE).
hDoc:GET-DOCUMENT-ELEMENT(hRoot).

/* Percorre as colunas <columns> */ 
DO iCount = 1 TO hRoot:NUM-CHILDREN WITH 20 DOWN:
    hRoot:GET-CHILD(hEntry, iCount).
    IF hEntry:NAME <> "columns" THEN
        NEXT.

    hEntry:GET-CHILD(hText, 1).
    PUT UNFORMATTED hText:NODE-VALUE "~t".
    DOWN.
END.
PUT UNFORMATTED SKIP.

/* Percorre os registros <values> */
DO iCount = 1 TO hRoot:NUM-CHILDREN WITH 20 DOWN:
    hRoot:GET-CHILD(hValues, iCount).
    IF hValues:NAME <> "values" THEN
        NEXT.

    /* Percorre os campos <value> */
    DO iCount2 = 1 TO hValues:NUM-CHILDREN:
        hValues:GET-CHILD(hEntry, iCount2).

        IF hEntry:NUM-CHILDREN = 0 THEN
            cValue = "".
        ELSE DO:
            hEntry:GET-CHILD(hText, 1).
            cValue = hText:NODE-VALUE.
        END.
        PUT UNFORMATTED cValue "~t".
    END.

    PUT UNFORMATTED SKIP.
END.

OUTPUT CLOSE.

DELETE OBJECT hValues.
DELETE OBJECT hText.
DELETE OBJECT hEntry.
DELETE OBJECT hRoot.
DELETE OBJECT hDoc.

Acessando WebServices a partir do

...

fluig

O Fluig fluig permite fazer chamadas a WebServices de terceiros através do cadastro de Serviços na Visualização de Serviços do Fluig Studio fluig Studio.

Nota
titleAtenção

Para que um usuário que não é administrador da empresa possa criar, editar e remover serviços é necessário que ele possua a permissão "Configurar Serviços". Esta permissão pode ser concedida pelo administrador através do item "Permissões" disponível na aba "Gerais" do Painel de Controle do fluig.

Saiba como realizar esse procedimento clicando aqui.

Para adicionar um novo WebService, é preciso clicar na opção Incluir Serviço, abrindo o assistente Novo Serviço, e informar o servidor do Fluig fluig onde será adicionado o serviço, um  um código identificador para ele, a sua descrição, a URL para o WSDL e o seu tipo (neste caso WebService).   No exemplo abaixo, será utilizado um WebService público para consulta à tabela periódica, cujo endereço do WSDL é é http://www.webservicex.com/periodictable.asmx?wsdl.


Com base nestas informações, o Fluig fluig irá extrair as informações sobre o WebService informado WebService informado e finalizará o cadastro deste serviço. 

Uma vez que o serviço esteja cadastrado, é possível visualizar as classes e métodos disponíveis neste serviço e que serão utilizados nos códigos JavaScript que farão uso do mesmo. A tela abaixo apresenta um exemplo de visualização de WebService.

Os serviços adicionados no Fluig podem fluig podem ser instanciados e utilizados nos pontos onde o produto permite personalização utilizando-se JavaScript, como nos scripts para eventos globais, eventos de processos, eventos de definição de formulário ou Datasets. No  No exemplo a seguir, será criado um Dataset que fará uso deste serviço para trazer os dados da tabela periódica.

O código abaixo apresenta uma implementação de exemplo do uso de um serviço na construção de um Dataset:

Bloco de código
languagejavascript
themeEclipse
firstline1
titleperiodicTable.js
linenumberstrue
function createDataset(fields, constraints, sortFields) {
	// Cria o dataset
	var dataset = DatasetBuilder.newDataset();
	dataset.addColumn("Element Name");
	dataset.addColumn("Symbol");
	dataset.addColumn("Atomic Number");
	dataset.addColumn("Atomic Weight");
	// Conecta o servico e busca os livros
	var periodicService = ServiceManager.getService('PeriodicTable');
	var serviceHelper = periodicService.getBean();
	var serviceLocator = periodicService.instantiate('net.webservicex.Periodictable');
	var service = serviceLocator.getPeriodictableSoap();
	// Invoca o serviço
	try {
		var result = service.getAtomicNumber("sodium"); // O termo "sodium" corresponde ao parâmetro do tipo String esperado na assinatura do método getAtomicNumber
		var xml = new XML(result);
		for ( var index in xml.Table) {
			var element = xml.Table[index];
			dataset.addRow(new Array(element.ElementName.toString(), element.Symbol.toString(), element.AtomicNumber
				.toString(), element.AtomicWeight.toString()));
		}
	} catch (erro) {
		dataset.addRow(new Array(erro));
	}
	return dataset;
}

O primeiro passo para invocar o serviço é solicitar ao Fluig fluig que carregue o serviço, a partir do método ServiceManager.getService('PeriodicTable'). O valor passado como parâmetro, deve ser o código utilizado quando cadastrado o serviço.

...

Informações
titleFique atento

Caso o Web Service WebService seja construído viaAxisvia Axis, o modo de chamar o método muda um pouco. Para acessar o método getAtoms é necessário recuperar a instância de PeriodictableSoap através do ServiceLocator, conforme exemplo abaixo:

Bloco de código
languagejs
	var periodicService = ServiceManager.getService('PeriodicTable');
    var serviceHelper = periodicService.getBean();
    var serviceLocator = serviceHelper.instantiate('NET.webserviceX.www.PeriodictableLocator');
    var service = serviceLocator.getperiodictableSoap();
    log.info(service.getAtoms());

...

Para percorrer o XML e extrair o dados disponíveis, são utilizadas as funcionalidades de tratamento de XML do JavaScript que facilita a manipulação de dados deste tipo. Para mais informações sobre esta funcionalidade, acesse: http://www.ecma-international.org/publications/standards/Ecma-357.htm ou http://www.xml.com/pub/a/2007/11/28/introducing-e4x.html.

O exemplo abaixo apresenta o código utilizado para percorrer o XML retornado:

...

Abaixo segue outro exemplo de utilização de serviços, utilizando empregando campos complexos na passagem de parâmetros. Este serviço é responsável por alterar o valor do campo de um registro de formulário:

Bloco de código
languagejavascript
themeEclipse
firstline1
titleperiodicTable.js
linenumberstrue
		//Servico "<url_fluig>/webdesk/ECMCardService?wsdl"cadastrado com o código "CardService"
        var cardServiceProvider = ServiceManager.getServiceInstance("CardService");
        var cardServiceLocator = cardServiceProvider.instantiate("com.totvs.technology.ecm.dm.ws.ECMCardServiceServiceLocator");
        var cardService = cardServiceLocator.getCardServicePort();
        var cardFieldDtoArray = cardServiceProvider.instantiate("com.totvs.technology.ecm.dm.ws.CardFieldDtoArray");
        var cardField = cardServiceProvider.instantiate("com.totvs.technology.ecm.dm.ws.CardFieldDto");
     
        //Seta valor no campo com name = 'nome'
        cardField.setField("nome");
        cardField.setValue("Valor alterado via WS dentro de um evento workflow");
 
        var vetCardFields = new Array();
        vetCardFields.push(cardField);
        cardFieldDtoArray.setItem(vetCardFields);
     
        //Altera o(s) campo(s) do registro de formulário.
        //updateCardData(tenantId, login, senha, codRegistroForm, cardFieldDtoArray);
        cardService.updateCardData(1, "adm", "adm", 8, cardFieldDtoArray);

 

WebServices com Autenticação Básica
Nota
titleAtenção

Esta opção é válida apenas para serviços criados utilizando a API CXF.

WebServices com Autenticação Básica no acesso ao WSDL

Para criar serviços de WebServices que utilizam Autenticação Básica no acesso ao seu WSDL, é necessário marcar a opção Requer Autenticação no cadastro de serviços do fluig, conforme exemplo abaixo:

...

Para finalizar o cadastro será apresentada a janela para autenticação abaixo:

Consumindo WebServices com Autenticação Básica

Para consumir WebServices que fazem uso de autenticação básica, é necessário utilizar o método getBasicAuthenticatedClient localizado no provider do serviço (o mesmo que é obtido via ServiceManager). Este método disponibiliza um client autenticado.

...

Os parâmetros que devem ser informados no método seguem a ordem abaixo:

  1. Instância do serviço;
  2. Nome da classe do serviço;
  3. Usuário para a autenticação;
  4. Senha para a autenticação.

Utilizando o exemplo do serviço PeriodicTable apresentado anteriormente, o código da chamada teria as alterações abaixo:

Bloco de código
languagejavascript
themeEclipse
firstline1
linenumberstrue
var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
var service = serviceLocator.getPeriodictableSoap();
var authenticatedService = serviceHelper.getBasicAuthenticatedClient(service, "net.webservicex.PeriodictableSoap", 'usuario', 'senha');
var result = authenticatedService.getAtoms();

WebService com client personalizado
Nota
titleAtenção

Esta técnica é válida para o Fluig fluig 1.3.7 ou superior.

Em integrações que utilizem serviços criados com o CXF com sistemas que não suportam o protocolo HTTP/1.1 (Protheus, por exemplo), é necessário utilizar este método configurando o parâmetro "disable.chunking" com o valor "true".

Para personalizar o client que acessa os serviços, é necessário utilizar o método getCustomClient, localizado no provider do serviço (o mesmo que é obtido via ServiceManager). Esta configuração exige a criação de um mapa de parâmetros com seus respectivos valores para passar ao método, conforme snippet conforme snippet abaixo:

Bloco de código
languagejs
themeEclipse
		var properties = {};
		properties["basic.authorization"] = "true";
		properties["basic.authorization.username"] = "username";
		properties["basic.authorization.password"] = "password";
		properties["disable.chunking"] = "true";
		properties["log.soap.messages"] = "true";
		//A propriedade receive.timeout está disponível a partir da versão 1.4.10
		properties["receive.timeout"] = "60000";
		
		var serviceLocator = serviceHelper.instantiate('net.webservicex.Periodictable');
		var service = serviceLocator.getPeriodictableSoap();
		var customClient = serviceHelper.getCustomClient(service, "net.webservicex.PeriodictableSoap", properties);
		var result = customClient.getAtoms();

...

Nota
titleImportante

O tempo de timeout de requisição padrão do fluig deveria ser suficiente para a realização de uma integração convencional. Antes de aumentar o tempo de timeout de integrações do Fluig fluig verifique o fato que levou a esta decisão.

Por exemplo, revise códigos e dimensionamento do servidor que recebe as integrações. Otimizações de códigos podem reduzir o tempo necessário para realizar uma transação e oferecer as pessoas que utilizam o fluig uma navegação mais fluida.

Resolvendo conflitos utilizando arquivos de bind JAXB
Nota
titleAtenção

Esta técnica é válida apenas para serviços criados utilizando a API CXF.

Ao criar serviços no Fluig fluig podem ocorrer alguns conflitos impedindo a geração dos stubs. Normalmente isso ocorre quando temos um elemento do schema do WSDL com duas ou mais propriedades com o mesmo identificador ou nome, o que impede a criação da Classe Java desse elemento.

...