Oracle BPM com JSP e Ajax
Nos projetos de BPM que tenho participado utilizando o Oracle BPM como solução BPMS, dificilmente faço o uso de presentations, é muito mais comum eu optar em utilizar páginas JSP como camada de apresentação dos meus processos. Isso se dá pelo fato de que as presentations são bastante limitadas, e quando se faz por necessário ter interfaces mais elaboradas e customizadas, o JSP passa a ser a melhor opção.
Usando JSP, um novo leque de opções passou a existir e uma dessas opções passou a ser a possibilidade de usar Ajax. Ajax, para quem nunca ouviu falar, não é uma linguagem, uma API, tão pouco um framework, Ajax é o acrônimo de Asynchronous Javascript And XML e nada mais é que um conjunto de técnicas usadas para criar aplicações web interativas (RIA). Um dos pilares do Ajax é permitir comunicação assíncrona entre cliente e servidor utilizando requisições HTTP.
O Oracle BPM oferece uma maneira bem interessante de usar Ajax nas páginas JSP, mesmo não sendo nativa e também não tendo nada a respeito dizendo na documentação, é possível fazer a integração da camada de apresentação de um processo BPM com o próprio processo de uma maneira bem tranquila.
Para exemplificar isso melhor, criei um projeto bem simples no Oracle BPM, que na verdade só serve para mostrar como funciona essa integração entre páginas JSP e métodos dentro de um BPM Object através de Ajax.
Primeiros passos
Para começar, criei um BPM Object bem simples, que possui 3 atributos: name (String), mail (String), documents (String[]). Os dois primeiros atributos, que representam o nome e o email de alguém, são do tipo String e o terceiro atributo, que no caso representa os documentos de uma pessoa, é do tipo Array de String. Chamei esse objeto de: BpmObject.
Nesse mesmo objeto (BpmObject), criei ainda um método, esse método será responsável por retornar os documentos de um usuário. Na verdade esse é o método que irei chamar via requisição Ajax através de uma página JSP. O nome desse método ficou definido como getDocuments().
No futuro precisarei alterar esse objeto, mas eu explico depois.
Criando a página JSP
No Oracle BPM, para informar que a apresentação de determinado BPM Object deva se dar por meio de uma página JSP, se faz por necessário a utilização de Screenflows. Screenflow é um fluxo semelhante ao de um processo normal, mas a principal diferença é que o mesmo é executado por um participante único, ou seja, dentro de um Screenflow não existem lanes.
Após ter criado um processo normal, apenas com uma atividade do tipo Global Creation (para criar uma instância do processo) e também com uma Interactive Activity (para apontar para o Screenflow), parti para criação do Screenflow de fato. O Screenflow em questão, será tão simples quanto o processo no qual ele está associado, no caso contará apenas com uma única atividade do tipo Interactive Component Call, que será a responsável por “chamar” uma página JSP associando-a ao BPM Object criado no passo anterior.
Para chamar uma página JSP, se faz por necessária associar um BPM Object a mesma, então nesse caso criei um váriavel de instância do tipo BpmObject (o mesmo criado no primeiro passo) e dei o seu nome de bpmObject. Após isso, criei uma página JSP dentro de: /projetoBPM/webRoot/customJSP/ajaxPage.jsp.
O nome da página em questão é ajaxPage.jsp, e por enquanto ela irá possuir o seguinte código:
| Java | | copiar código | | ? |
| 01 | |
| 02 | <%@ page session="true"%> |
| 03 | <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> |
| 04 | <%@ taglib uri="http://fuego.com/jsp/ftl" prefix="f"%> |
| 05 | |
| 06 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| 07 | <html xmlns="http://www.w3.org/1999/xhtml"> |
| 08 | <head> |
| 09 | <title>Teste Ajax/title> |
| 10 | <script type="text/javascript" src="<f:webResources relativePath='js/prototype-1.6.0.3.js'/>"></script> |
| 11 | </head> |
| 12 | <body leftmargin="0" topmargin="0"> |
| 13 | |
| 14 | Teste Ajax |
| 15 | <br/><br/> |
| 16 | Nome: <c:out value="${bpmObject.nome}" /> |
| 17 | <br/><br/> |
| 18 | |
| 19 | <div id="teste"></div> |
| 20 | |
| 21 | </body> |
| 22 | |
| 23 | </html> |
Então, relembrando os passos até aqui:
1) Criação de BPM Object com 3 atributos e um método;
2) Criação de processo com uma atividade do tipo Global Creation e outra do tipo Interactive Activity;
3) Criação de Screenflow;
4) Associação (Implementation Type) da Interactive Activity do processo ao Screenflow criado;
5) Criação de atividade do tipo Interactive Component Call no Screenflow;
6) Criação de váriavel de instância no Screenflow com o tipo sendo o mesmo do BPM Object que foi criado no primeiro passo;
7) Definição do Implementation Type da Interactive Component Call como BPM Object Interactive Call;
8) Associação do BPM Object criado como váriavel de instância da Interactive Component Call do Screenflow;
9) Definição da página ajaxPage.jsp como JSP Presentation da Interactive Component Call do Screenflow.
Feito os passos acima, a estrutura do processo está pronta para criação da página JSP que irá fazer a requisição via Ajax a um método do BPM Object que foi criado no primeiro passo.
Fazendo a requisição Ajax e explicando alguns components da taglib do Oracle BPM
Para criação do mecanismo que irá fazer a requisição Ajax, se faz por necessário a utilização da taglib do Oracle BPM, sem ela não seria possível usar Ajax, ou então seria bastante árduo fazer tal integração.
Por exemplo, para incluir a biblioteca Prototype, que no caso será a responsável por fazer o “trabalho sujo” e criar o objeto XMLHttpRequest para fazer a requisição assíncrona, utilizei a tag f:webResources (linha 10). Esta tag inclui os resources inclusos no projeto BPM, sem que seja necessário informar explicitamente o context path da aplicação para inclusão de imagens, CSS ou Javascripts.
Outra tag importante é a f:invokeUrl, que no caso irá gerar a URL para execução de um método dentro de um BPM Object. Dessa forma, a página JSP precisa ser alterada, pois agora irá contar com uma função Javascript que irá fazer a chamada via Ajax ao método getDocuments() do BPM Object criado no primeiro passo, retornando o output do método para div teste.
Página JSP alterada:
| Java | | copiar código | | ? |
| 01 | |
| 02 | <%@ page session="true"%> |
| 03 | <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> |
| 04 | <%@ taglib uri="http://fuego.com/jsp/ftl" prefix="f"%> |
| 05 | |
| 06 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| 07 | <html xmlns="http://www.w3.org/1999/xhtml"> |
| 08 | <head> |
| 09 | <title>Teste Ajax/title> |
| 10 | <script type="text/javascript" src="<f:webResources relativePath='js/prototype-1.6.0.3.js'/>"></script> |
| 11 | <script> |
| 12 | function callAjaxMethod () { |
| 13 | var bpmUrl ='<f:invokeUrl var="bpmObject" methodName="getDocuments" />'; |
| 14 | return bpmUrl; |
| 15 | } |
| 16 | |
| 17 | new Ajax.Updater('teste', callAjaxMethod()); |
| 18 | </script> |
| 19 | </head> |
| 20 | <body leftmargin="0" topmargin="0"> |
| 21 | |
| 22 | Teste Ajax |
| 23 | <br/><br/> |
| 24 | Nome: <c:out value="${bpmObject.nome}" /> |
| 25 | <br/><br/> |
| 26 | |
| 27 | <div id="teste"></div> |
| 28 | |
| 29 | </body> |
| 30 | |
| 31 | </html> |
| 32 |
Repare que foi criada a função JS callAjaxMethod. Abaixo dessa função existe ainda a função JS Ajax.Updater, que no caso é uma função da biblioteca Prototype que irá fazer a chamada ao método do BPM Object, retornando seu output para a div teste.
Criando um output para o método getDocuments do BPM Object
Finalmente essa é a última parte desse pequeno tutorial. Agora a única coisa que falta é criar um output para o método do BPM Object que irá ser chamado via requisição Ajax.
Antes de mais nada, preciso dizer algo a respeito da tag f:invokeUrl, pois para ela funcionar corretamente existem algumas peculiariades.
Para um método de um BPM Object ser reconhecido por esta tag, ele deve ter uma das quatro assinaturas abaixo:
- methodName(Fuego.Net.HttpRequest request, Fuego.Net.HttpResponse response)
- methodName(java.util.Map requestParameters, java.util.Map requestHeaders)
- methodName(java.util.Map requestParameters)
- methodName()
No caso, eu optei por utilizar a primeira opção, pois para usar a função Ajax.Updater da Prototype, eu preciso escrever diretamente no output do método, ao invés de setar as informações necessárias através dos seus atributos.
Em virtude disso, o método getDocuments do objeto BpmObject agora passará a ter a seguinte assinatura:
| Java | | copiar código | | ? |
| 1 | |
| 2 | getDocuments(Fuego.Net.HttpRequest request, Fuego.Net.HttpResponse response) |
| 3 |
Agora, finalmente o código do método getDocuments, que ficará da seguinte maneira:
| Java | | copiar código | | ? |
| 1 | |
| 2 | for (String doc : documents) { |
| 3 | response.bodyTextContent(arg1 : doc); |
| 4 | } |
| 5 |
No código acima, estou percorrendo o atributo documents (array) e imprimindo no output todos os documentos definidos para aquele atributo, dessa forma, quando a função callAjaxMethod é chamada na página JSP, ela automaticamente chama (assincronamente) este método contido dentro do BPM Object, imprimindo todos os documentos definidos para dentro da div com o ID teste.
Conclusão
Utilizando os recursos corretos do Oracle BPM, como sua taglib e seus componentes, não é muito difícil fazer uma tela de apresentação mais interativa usando Ajax. No exemplo acima, foi criado um projeto bem simples, apenas para ilustrar, com o intuito de mostrar a atualização do conteúdo de uma div feita assincronamente através de uma requisição Ajax.
Se você gostou desse tópico, por favor considere deixar um comentário ou se inscreva no feed e tenha no futuro todos os tópicos entregues diretamente no seu agregador.






Marcus, muito bom e interessante. Isso dá uma boa visão da flexibilidade que podemos alcançar com um UI em JSP. Em breve quero postar umas dúvidas sobre essa utilização. Parabéns
Excelente iniciativa Marcos.
Marcos estou com uma dúvida sobre o seu wizard.
Realizei todas as etapas descritas por você, mas no momento de escrever o metodo getDocuments() o editor do BPMStudio 10.1.3… não reconheceu o código que você deixou como exemplo. Existe alguma coisa a mais para ser feita? Existe a necessidade de criar alguma variável? Existe algum passo que não foi descrito e que eu deveria ter feito?
Obrigado!
Marcos, o editor do BPMStudio não reconheceu a assinatura do método getDocuments(), também não reconheceu o comando for. Existe algo mais a ser feito?
Agradeço desde já sua ajuda.
Claudio,
Veja na sua ferramenta se o seu código (method editor) está como Java ao invés de PBL, é muito provável que o erro esteja aí.
Abraço,
Marcus, o problema é que o nome do metodo tem o mesmo nome da variavel (java beans), sendo assim não sei como alterar a assinatura no “read access”.
Abs
Muito bom artigo e de boa iniciativa…
Estou com outro problema… usar Ajax para acessar WebServices, ainda não sei o porque não funciona quando uso o mesmo mecanismo para acessar em método de WebService externo…
Se alguém já passou pelo problema e sabe o motivo de não funcionar, por favor, poste aqui, se eu descobrir algo deixo aqui para consulta.