Árvore de páginas

Versões comparadas

Chave

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

...

Você também pode fazer a codificação da chamada dos métodos dos serviços, fazendo com quem um dataset faça a inicialização da solicitação ou mesmo caso a opção sem codificação não atenda as suas necessidades. Para lhe ajudar, criamos este exemplo com mais documentação do que está sendo feito.: 

Bloco de código
languagejs
firstline1
titleExemplo de integração via codificação
linenumberstrue
collapsetrue
//configure os dados do seu usuário integrador
var INTEGRADOR = {
	matricula: 'integrador',
	senha: '9a411f45fcea479ffb839a3ee605c18d',
	empresa: 1
};

// conforme o cadastro do fluig
var SERVICOS = {
	workflowEngineService: "ECMWorkflowEngineService"
}

/**
 * Função que cria uma solicitação via Soap no Fluig
 * 
 */
function startProcess() {
    var serviceHelper = getECMWorkflowEngineServiceHelper();
    var service = getECMWorkflowEngineService(serviceHelper);
    
    
    // Nome do processo a ser iniciado
    var processId = "processoASerIniciado";
        function startProcess() {
	var serviceHelper = ServiceManager.getService("ECMWorkflowEngineService").getBean();
    var serviceLocator = serviceHelper.instantiate("com.totvs.technology.ecm.workflow.ws.ECMWorkflowEngineServiceService");
    var service = serviceLocator.getWorkflowEngineServicePort();
    
    // Lista das matrículas de usuários que irão receber a atividade. Normalmente é um usuário, mas no caso de um consenso podem ser vários
    var colleagueIds = serviceHelper.instantiate('net.java.dev.jaxb.array.StringArray');
    colleagueIds.getItem().add("adm");
    
    // AtividadeChama parao qualserviço serápara movimentadainiciar a solicitação
 e recebe  var choosedState = 2;o retorno
    
    /// ListaO dasretorno matrículas de usuários que irão receber a atividade. Normalmentedo startProcess é um usuárioString[][], masou no casoSoap, de um consenso podem ser váriosStringArrayArray
    var colleagueIdsretornoStartProcess = createStringArray(serviceHelper);service.startProcess(
    colleagueIds.getItem().add("adm");
    
   		'integrador', // matrícula do usuário integrador
    		'9a411f45fcea479ffb839a3ee605c18d', // Comentáriosenha dado movimentaçãousuário
    var comments = "Iniciado via ws";
    		1, // código da empresa
    		"processoASerIniciado", // código do processo
    		2, // Usuáriocódigo queda ficará atividade para qual a solicitação vai ser movimentada
    		colleagueIds, 
    		"Iniciado via ws", // Comentário da movimentação
    		'integrador', // Usuário que ficará como o inicializador da solicitação. O usuário integrador precisa ter personificação caso seja um usuário diferente do integrador
    var userId = INTEGRADOR.matricula;
    
    		true, // Se vai completar a tarefa inicial (true) ou não, vai apenas salvar a solicitação para gerar um código e preencher o formulário, anexos e comentários
    var completeTask = true;
    
    		serviceHelper.instantiate('com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray'), // Lista de anexos. Mesmo que não seja enviado nenhum, é necessário enviar a lista vazia
    var attachments = createProcessAttachmentDtoArray(serviceHelper);

    		serviceHelper.instantiate('net.java.dev.jaxb.array.StringArrayArray'), // Dados do formulário. Mesmo que não tenha formulário ou não seja preenchido, é necessário enviar a lista vazia
    var cardData = createStringArrayArray(serviceHelper);
    
    		serviceHelper.instantiate('com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray'), // Apontamentos da solicitação. Não é mais utilizado, mas por compatibilidade é necessário enviar a lista vazia
    var appointments = createProcessTaskAppointmentDtoArray(serviceHelper);
    
    // Se a 		false // Se a movimentação é feita como usuário responsável pela atividade ou como gestor do processo
	);
    
    var managerModeretorno = falsestringArrayArrayToSimpleObject(retornoStartProcess);
    
    // Chama o serviço para iniciar a solicitação e recebe o retorno
    // O retorno do startProcess é um String[][], ou no Soap, um StringArrayArray
    var retornoStartProcess = service.startProcess(
    		INTEGRADOR.matricula, if (retorno.ERROR) {
    	// Interrompe a execução ou movimentação e retorna um erro com a resposta do serviço
    	throw "Solicitação não iniciada: " + retorno.ERROR;
    } else {
    		INTEGRADOR.senha, 
    		INTEGRADOR.empresa, 
    		processId, 
    		choosedState, // Imprime o código da solicitação criada pelo serviço e depois imprime todos os dados que foram retornados
    		colleagueIds, 
    		comments, log.info("Solicitação " + retorno.iProcess + " criada com sucesso");
    		userId, log.dir(retorno)
    		completeTask,} 
    		attachments, 
    		cardData, 
    		appointments, 
    		managerMode
	);
    
    var retorno = stringArrayArrayToSimpleObject(retornoStartProcess);
    
    if (retorno.ERROR) {
    	// Interrompe a execução ou movimentação e retorna um erro com a resposta do serviço
    	throw "Solicitação não iniciada: " + retorno.ERROR;
    } else {
    	// Imprime o código da solicitação criada pelo serviço e depois imprime todos os dados que foram retornados
    	log.info("Solicitação " + retorno.iProcess + " criada com sucesso");
    	log.dir(retorno)
    }    
}

function getECMWorkflowEngineServiceHelper() {
    return ServiceManager.getService(SERVICOS.workflowEngineService).getBean();
}

function getECMWorkflowEngineService(serviceHelper) {
	var serviceLocator = serviceHelper.instantiate("com.totvs.technology.ecm.workflow.ws.ECMWorkflowEngineServiceService");
    return serviceLocator.getWorkflowEngineServicePort();
}

/**
 * Cria uma variável similar ao String[] que é utilizado pelo Soap
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo net.java.dev.jaxb.array.StringArray
 * @returns Um objeto do tipo net.java.dev.jaxb.array.StringArray conforme o mapeamento do wsdl
 */
function createStringArray(serviceHelper) {
	return serviceHelper.instantiate('net.java.dev.jaxb.array.StringArray');
}


/**
 * Cria uma variável similar ao String[][] que é utilizado pelo Soap
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo net.java.dev.jaxb.array.StringArrayArray
 * @returns Um objeto do tipo net.java.dev.jaxb.array.StringArrayArray conforme o mapeamento do wsdl
 */
function createStringArrayArray(serviceHelper) {
	return serviceHelper.instantiate('net.java.dev.jaxb.array.StringArrayArray');
}


/**
 * Cria uma variável similar ao ProcessAttachmentDto[] que é utilizado pelo Soap
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray
 * @returns Um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray conforme o mapeamento do wsdl
 */
function createProcessAttachmentDtoArray(serviceHelper) {
	return serviceHelper.instantiate('com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray');
}

/**
 * Cria uma variável similar ao ProcessTaskAppointmentDto[] que é utilizado pelo Soap. 
 * 
 * Estes apontamentos não são mais usados, mas como não devemos mexer na assinatura dos métodos Soap para não quebrar os stubs já gerados é obrigatório mandar, ainda que vazio
 * 
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray
 * @returns Um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray conforme o mapeamento do wsdl
 */
function createProcessTaskAppointmentDtoArray(serviceHelper) {
	return serviceHelper.instantiate('com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray');
}

/**
 * Transforma um objeto do tipo StringArrayArray (String[][]) em um objeto Javascript
 * 
 * <item>
 *   <item>campo</item>
 *   <item>valor</item>
 * </item>
 * 
 * Vira:
 * 
 * {'campo': 'valor'}
 * 
 * @param stringArrayArray
 * @returns Um objeto do tipo javascript 
 */
function stringArrayArrayToSimpleObject(stringArrayArray) {
	var objeto = {};
	for(var i = 0; i < stringArrayArray.getItem().size(); i++) {
		var item = stringArrayArray.getItem().get(i).getItem();
		objeto[item.get(0)] = item.get(1);
	}
	
	return objeto;
}

Objetivo

O objetivo deste documento é descrever a utilização de Webservices, mostrar e explicar todos seus métodos, disponibilizar exemplos de classes que utilizam esses Webservices e mostrar exemplos de geração de stubs que são necessários para que os clients possam se comunicar com o serviço.

Pré-requisitos

Para que se tenha uma compreensão completa destas informações, alguns conhecimentos são considerados pré-requisitos, entre eles:

  • Visão geral sobre o fluig
  • Visão geral sobre integração de sistemas
  • WebServices
Dica
titleDica!

A equipe TOTVS Fluig recomenda a utilização da API em exemplos que utilizam o método SOAP, pois seu uso é mais complexo em comparação com a API e está caindo em desuso.

Como acessar

Para acessar os webservices do TOTVS Fluig Plataforma, é preciso acessar o URL https://<endereco_fluig:porta>/webdesk/services.

Criar Stubs

Os stubs são necessários para que os clients que utilizam os métodos dos Webservices possam se comunicar com o serviço.

Para criar um stub é necessário que o serviço do fluig esteja inicializado. Depois de iniciar o serviço, deve-se abrir o Prompt de comando e utilizar a sintaxe: wsimport -d <output_directory> <wsdl_url>, onde output_directory é o diretório onde o stub será criado e wsdl_url é a url de acesso ao serviço. Após isso, basta apertar Enter e o resultado aparecerá conforme mostra a figura 1. 

Nota
titleObservação
Foi criado um facilitador para gerar todos os stubs, basta baixar o documento Cliente Web Service.zip. Basta descompactá-lo e executar o arquivo "fluig-ws.sh", informe o nome e porta do servidor. Após executar, será gerado o "fluig-ws-client.jar". Importe o .jar para acesso ao serviço. Aqui você encontra um exemplo (ws-soap e webservice) prático de utilização em artefatos publicados no fluig.

Image Removed

Figura 1: Exemplo de criação de stub

...

visibletrue
titleLista de webservices

No Quadro 1 (abaixo) são listados os comandos necessários para a criação de stubs de cada serviço disponível no fluig.

...

Webservices (WSDL)

...

Comando

...

ECMAttributionMecanismService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMAttributionMecanismService?wsdl

...

ECMBusinessPeriodService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMBusinessPeriodService?wsdl

...

ECMCardIndexService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMCardIndexService?wsdl

...

ECMCardService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMCardService?wsdl

...

ECMColleagueGroupService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMColleagueGroupService?wsdl

...

ECMColleagueReplacementService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMColleagueReplacementService?wsdl

...

ECMColleagueService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMColleagueService?wsdl

...

ECMCompanyService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMCompanyService?wsdl

...

ECMCustomFieldsService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMCustomFieldsService?wsdl

...

ECMDashBoardService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMDashBoardService?wsdl

...

ECMDataServiceService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMDataServiceService?wsdl

...

ECMDatasetService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMDatasetService?wsdl

...

ECMDocumentService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMDocumentService?wsdl

...

ECMFavoritesService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMFavoritesService?wsdl

...

ECMFolderService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMFolderService?wsdl

...

ECMGlobalParamService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMGlobalParamService?wsdl

...

ECMGroupService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMGroupService?wsdl

...

ECMOutstandingService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMOutstandingService?wsdl

...

ECMReportService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMReportService?wsdl

...

ECMSearchDocumentService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMSearchDocumentService?wsdl

...

ECMSignalService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMSignalService?wsdl

...

ECMTokenService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMTokenService?wsdl

...

ECMWorkflowEngineService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMWorkflowEngineService?wsdl

...

ECMWorkflowRoleService

...

wsimport -d C:\Webservices\tmp http://<SERVER>:<PORT>/webdesk/ECMWorkflowRoleService?wsdl


}


function stringArrayArrayToSimpleObject(stringArrayArray) {
	var objeto = {};
	for(var i = 0; i < stringArrayArray.getItem().size(); i++) {
		var item = stringArrayArray.getItem().get(i).getItem();
		objeto[item.get(0)] = item.get(1);
	}
	
	return objeto;
}


Ou, se preferir um exemplo um pouco maior, mas contendo mais detalhes sobre o que é cada parâmetro e desenvolvido para ser melhor re-utilizável, você pode conferir este exemplo que faz o mesmo que o exemplo anterior

Bloco de código
languagejs
firstline1
titleExemplo de integração via codificação
linenumberstrue
//configure os dados do seu usuário integrador
var INTEGRADOR = {
	matricula: 'integrador',
	senha: '9a411f45fcea479ffb839a3ee605c18d',
	empresa: 1
};

// conforme o cadastro do fluig
var SERVICOS = {
	workflowEngineService: "ECMWorkflowEngineService"
}

/**
 * Função que cria uma solicitação via Soap no Fluig
 * 
 */
function startProcess() {
    var serviceHelper = getECMWorkflowEngineServiceHelper();
    var service = getECMWorkflowEngineService(serviceHelper);
    
    // Nome do processo a ser iniciado
    var processId = "processoASerIniciado";
        
    // Atividade para qual será movimentada a solicitação
    var choosedState = 2;
    
    // Lista das matrículas de usuários que irão receber a atividade. Normalmente é um usuário, mas no caso de um consenso podem ser vários
    var colleagueIds = createStringArray(serviceHelper);
    colleagueIds.getItem().add("adm");
    
    // Comentário da movimentação
    var comments = "Iniciado via ws";
    
    // Usuário que ficará como o inicializador da solicitação. O usuário integrador precisa ter personificação caso seja um usuário diferente do integrador
    var userId = INTEGRADOR.matricula;
    
    // Se vai completar a tarefa inicial (true) ou não, vai apenas salvar a solicitação para gerar um código e preencher o formulário, anexos e comentários
    var completeTask = true;
    
    // Lista de anexos. Mesmo que não seja enviado nenhum, é necessário enviar a lista vazia
    var attachments = createProcessAttachmentDtoArray(serviceHelper);

    // Dados do formulário. Mesmo que não tenha formulário ou não seja preenchido, é necessário enviar a lista vazia
    var cardData = createStringArrayArray(serviceHelper);
    
    // Apontamentos da solicitação. Não é mais utilizado, mas por compatibilidade é necessário enviar a lista vazia
    var appointments = createProcessTaskAppointmentDtoArray(serviceHelper);
    
    // Se a movimentação é feita como usuário responsável pela atividade ou como gestor do processo
    var managerMode = false;
    
    // Chama o serviço para iniciar a solicitação e recebe o retorno
    // O retorno do startProcess é um String[][], ou no Soap, um StringArrayArray
    var retornoStartProcess = service.startProcess(
    		INTEGRADOR.matricula, 
    		INTEGRADOR.senha, 
    		INTEGRADOR.empresa, 
    		processId, 
    		choosedState, 
    		colleagueIds, 
    		comments, 
    		userId, 
    		completeTask, 
    		attachments, 
    		cardData, 
    		appointments, 
    		managerMode
	);
    
    var retorno = stringArrayArrayToSimpleObject(retornoStartProcess);
    
    if (retorno.ERROR) {
    	// Interrompe a execução ou movimentação e retorna um erro com a resposta do serviço
    	throw "Solicitação não iniciada: " + retorno.ERROR;
    } else {
    	// Imprime o código da solicitação criada pelo serviço e depois imprime todos os dados que foram retornados
    	log.info("Solicitação " + retorno.iProcess + " criada com sucesso");
    	log.dir(retorno)
    }    
}

function getECMWorkflowEngineServiceHelper() {
    return ServiceManager.getService(SERVICOS.workflowEngineService).getBean();
}

function getECMWorkflowEngineService(serviceHelper) {
	var serviceLocator = serviceHelper.instantiate("com.totvs.technology.ecm.workflow.ws.ECMWorkflowEngineServiceService");
    return serviceLocator.getWorkflowEngineServicePort();
}

/**
 * Cria uma variável similar ao String[] que é utilizado pelo Soap
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo net.java.dev.jaxb.array.StringArray
 * @returns Um objeto do tipo net.java.dev.jaxb.array.StringArray conforme o mapeamento do wsdl
 */
function createStringArray(serviceHelper) {
	return serviceHelper.instantiate('net.java.dev.jaxb.array.StringArray');
}


/**
 * Cria uma variável similar ao String[][] que é utilizado pelo Soap
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo net.java.dev.jaxb.array.StringArrayArray
 * @returns Um objeto do tipo net.java.dev.jaxb.array.StringArrayArray conforme o mapeamento do wsdl
 */
function createStringArrayArray(serviceHelper) {
	return serviceHelper.instantiate('net.java.dev.jaxb.array.StringArrayArray');
}


/**
 * Cria uma variável similar ao ProcessAttachmentDto[] que é utilizado pelo Soap
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray
 * @returns Um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray conforme o mapeamento do wsdl
 */
function createProcessAttachmentDtoArray(serviceHelper) {
	return serviceHelper.instantiate('com.totvs.technology.ecm.workflow.ws.ProcessAttachmentDtoArray');
}

/**
 * Cria uma variável similar ao ProcessTaskAppointmentDto[] que é utilizado pelo Soap. 
 * 
 * Estes apontamentos não são mais usados, mas como não devemos mexer na assinatura dos métodos Soap para não quebrar os stubs já gerados é obrigatório mandar, ainda que vazio
 * 
 * @param serviceHelper O wsdl que contém o mapeamento da estrutura de um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray
 * @returns Um objeto do tipo com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray conforme o mapeamento do wsdl
 */
function createProcessTaskAppointmentDtoArray(serviceHelper) {
	return serviceHelper.instantiate('com.totvs.technology.ecm.workflow.ws.ProcessTaskAppointmentDtoArray');
}

/**
 * Transforma um objeto do tipo StringArrayArray (String[][]) em um objeto Javascript
 * 
 * <item>
 *   <item>campo</item>
 *   <item>valor</item>
 * </item>
 * 
 * Vira:
 * 
 * {'campo': 'valor'}
 * 
 * @param stringArrayArray
 * @returns Um objeto do tipo javascript 
 */
function stringArrayArrayToSimpleObject(stringArrayArray) {
	var objeto = {};
	for(var i = 0; i < stringArrayArray.getItem().size(); i++) {
		var item = stringArrayArray.getItem().get(i).getItem();
		objeto[item.get(0)] = item.get(1);
	}
	
	return objeto;
}

Quadro 1: Comandos para criação de stubs.

Considerações Métodos de Update

Para os métodos de update que recebem objetos complexos é obrigatório passar todos os campos do objeto alterado. Os campos não informados serão substituídos por branco, nulo ou zero, dependendo do seu tipo.

Para evitar esta situação, sugerimos sempre utilizar os métodos get para recuperar o objeto, efetuar as alterações nos campos necessários e enviá-lo para o método update.

Nota
  • Identificação dos atributos: Os atributos de retorno dos métodos são identificados nos objetos. Caso não tenha encontrado o objeto que procura é possível fazer uma pesquisa nos datasets e assim identificar os atributos. Para mais informações sobre como consultar o dataset, acesse a documentação Desenvolvimento de Datasets.
Tratamento de exceção (try/catch): Quando o serviço utilizado não estiver disponível, não haverá retorno. Para esse tipo de caso, é aconselhável realizar o tratamento utilizando Try / Catch.