Você está na página 1de 14

Desenvolvendo Portlets com

Apache Pluto
Criando portlets em ambiente OpenSource
Conheça a especificação e aprenda como criar, empacotar e instalar portlets
no ambiente referência da especificação

GUSTAVO CONCON E ALEX BARBOSA COQUEIRO


Quando falamos em portal, logo vem a cabeça grandes sites com inúmeros conteúdos de
diferentes assuntos, como por exemplo, terra.com.br ou uol.com.br. Imagine o quão
complexo seria o desenvolvimento e manutenção desses portais se não houvesse uma
arquitetura componentizada e baseada em serviços. Dessa necessidade, a especificação Java
passou a contemplar API’s para o desenvolvimento de portais, e a partir disso os
fornecedores de software trabalharam no desenvolvimento de servidores otimizados para
suportar toda infra-estrutura necessária.
O principal objetivo de um portal é agregar conteúdos de diferentes fontes em uma única
página da web, permitindo que o usuário tenha acesso completo a tudo que o site tem a
oferecer.
Para agregar esses conteúdos, a tecnologia permite o particionamento da página em
elementos reutilizáveis. Estes elementos denominam-se Portlets.
Portlets são componentes plugáveis que podem ser colocados em uma ou várias páginas
de um portal. Neste artigo, vamos entender o que são os portlets, como e quando usá-los.
Alguns artigos já abordaram portlets em edições anteriores da revista, por isso vamos
apenas rever alguns conceitos e partir para implementação e deploy de portlets no Pluto
Container.
Para nosso exemplo, usaremos o Eclipse e o framework Apache Pluto, um portlet
container que implementa a especificação de portlets, a JSR 168 (Veremos mais sobre ela à
frente). Utilizaremos também o Maven 2, um utilitário utilizado para criação, assembly e
deploy de projetos.
No atual estágio de maturidade dessa tecnologia, há ferramentas comerciais que
desenvolvem portlets em um formato totalmente visual, como o WebSphere Portlet
Factory, ganhando com isso produtividade, mas este tipo de estudo está fora do escopo
deste artigo.

O que são portlets afinal?


Primeiro devemos ter o conceito de três componentes principais da arquitetura:
• Os portais, que são aplicações que agregam aplicações portlets em uma única página de
apresentação;
• O portlet container, que é um mediador entre as aplicações portlets e o portal, provendo
todo o ambiente para a execução dos portlets e controlando seu ciclo de vida;
• E os portlets, que são aplicações de interface gráfica simples, geralmente pequenas,
disponibilizadas em páginas Portais. Ou seja, um portlet é uma entre várias outras
aplicações que fornecem ao usuário um conteúdo, que em conjunto à outros portlets
formam uma página de portal, veja a Figura 1.

Figura 1. Portlets em uma página de portal

Para compreender melhor a relação entre esses três componentes, vamos ver como é o
fluxo de requisição de uma página de portal (Figura 2).
Quando é feita a requisição de uma página, o servidor de portal a encaminha para o portlet
container, que tem a lista de portlets necessários para atender a requisição; essa lista são os
portlets que formam a página do portal, geralmente configurada por um administrador. Em
seguida, cada portlet processa a requisição e gera a resposta na forma de markup1,
devolvendo-a ao container que encaminha o conteúdo gerado ao portal para exibição ao
cliente, como ilustrado na Figura 2.

Figura 2. Fluxo da requisição de uma página de portal

É importante frisar que os portlets não são como os servlets, apesar de terem algumas
semelhanças, como pode ser visto na Tabela 1.

Semelhanças Ambos são baseados na tecnologia Java.


Seu ciclo de vida é gerenciado por um container específico.
Geram conteúdos dinâmicos.
Interagem com o cliente utilizando o paradigma Request/Response.
Diferenças Portlets geram apenas fragmentos de markup, pois o Portal agrupa os
fragmentos dos portlets em uma página completa.
Portlets não são diretamente acionados via URL.
1
Markup: Linguagem declarativa para montagem de um conteúdo na Web, por exemplo:
HTML, WML, xHTML, cHTML.
Os clientes interagem com os portlets através do Portal.
Portlets possuem alguns modos e estados de janela (veremos adiante).
Portlets podem existir várias vezes em uma página de Portal.
Tabela 1. Semelhanças e diferenças entre portlets e servlets

Quanto à padronização
Em 2003, membros do Java Community Process resolveram estabelecer um padrão para o
desenvolvimento de portlets, e criaram uma especificação, a JSR 168. Esta, estabelecia uma
série de conceitos e padronizações tanto no próprio desenvolvimento dos portlets, quanto
na arquitetura envolvida (segurança, caching, interface gráfica e etc).
O tempo passou e a tecnologia amadureceu muito com os inúmeros produtos no mercado,
levando então a necessidade de uma atualização. Na data de escrita desse artigo, temos em
andamento a JSR 286, que é a versão 2.0 da primeira especificação, onde a proposta inclui
muitas correções da primeira versão e outros componentes como filtros, melhoramentos em
caching, gerenciamento, implementação de portlets remotos, etc.

O ciclo de vida dos Portlets


A especificação define um ciclo de vida a ser gerenciado pelo portlet container, contendo
as seguintes fases:
1. Instanciação: É onde o portlet container instancia a classe que representa o portlet,
definida pela implementação da interface javax.portlet.Portlet;
2. Inicialização: Onde o container inicializará os recursos que podem ser utilizados pelo
portlet. Geralmente são recursos como conexões ou abertura de arquivos, portanto é
uma operação custoza, efetuada apenas uma vez durante todo seu ciclo de vida. Após
essa fase, o portlet está pronto para atender os requests dos clientes;
3. Gerenciamento do request: Fase em que o portlet irá processar uma requisição de
usuário, tratando o request e gerando um response para a ação solicitada do cliente;
4. Renderização do response: Com os dados processados na fase anterior
(Gerenciamento do request) o portlet irá montar o markup para exibição das
informações ao cliente;
5. Finalização: Fase em que o portlet será destruído, removido da memória. Demarca o
fim do ciclo de vida dos portlets.

Para atender ao ciclo de vida dos portlets, a interface Portlet possui os seguintes métodos:
• init(PortletConfig config): Chamado apenas uma vez. Utilizado para tarefas de
inicialização de recursos e recebe as configurações do portlet, que são meta-
informações como parâmetros de inicialização, nome, informações sobre o contexto do
portlet container e um arquivo de propriedades para internacionalização (Resource
bundle);
• processAction(ActionRequest request, ActionResponse response): Executado a cada
requisição de um cliente. Neste método são executadas as regras de negócio do portlet;
• render(RenderRequest request, RenderResponse response): Executado logo após o
processAction. É onde o markup será montado, sendo a camada de apresentação do
portlet. Geralmente utiliza as informações processadas no método processAction();
• destroy(): Método executado logo antes do portlet ser coletado pelo Garbage Collector.
Deve ser utilizado para liberar os recursos adquiridos nos métodos anteriores. Marca o
fim do ciclo de vida dos portlets.

A Figura 3 exibe a sequência dos métodos invocados pelo portlet container no ciclo de
vida do portlet.

Figura 3. Sequência de métodos invocados pelo portlet container

Portlet Modes e Window States


Além de gerenciar o ciclo de vida, o portlet container gerencia o estado de um portlet, os
chamados modos de portlet (portlet modes) e estados de janela (window state).
Os modos dos portlets definem o tipo de conteúdo exibido. A especificação define três
modos padrão: visualização, edição e ajuda. Porém, é possível implementar mais modos.
Os estados de janela definem como os portlets serão exibidos na página do portal. Os três
estados definidos são: maximizado, o portlet será exibido ocupando toda área de portlets da
página; normal, deixando as configurações de página do portal definirem o tamanho do
portlet; minimizado, exibindo apenas uma pequena informação do portlet ou geralmente
nenhum conteúdo.
Os modos de portlet e estados de janela podem ser acessados durante todo ciclo de vida
dos portlets, porém só podem ser escritos na fase de gerenciamento do request (método
processAction).

Portlet Taglibs
Algumas taglibs foram definidas para auxílio no desenvolvimento das páginas JSP, a
Tabela 2 descreve cada uma delas:

<portlet:defineObjects/> Define e instancia as seguintes variáveis no JSP:


• RenderRequest renderRequest
• RenderResponse renderResponse
• PortletConfig portletConfig
<portlet:actionURL/> Cria uma URL apontando para o portlet corrente, disparando
seu método processAction(). Parâmetros podem ser passados
declarando a tag <portlet:param/> no corpo da tag.
<portlet:renderURL/> Cria uma URL apontando para o portlet corrente, disparando
seu método renderRequest(). Parâmetros podem ser passados
declarando a tag <portlet:param/> no corpo da tag.
<portlet:namespace/> Retorna um identificador único para o portlet, muito útil
para nomear elementos na página, evitando conflitos com
outros portlets.
Tabela 2. Taglibraries definidas pela especificação
Sobre o Pluto
O Pluto é um projeto mantido pela Apache Software Foundation, opensource e que é
referência na implementação da especificação de portlets - JSR 168. A versão atual não foi
designada para ser um portal de produção, mas sim apenas uma ferramenta de suporte ao
desenvolvimento e um container que pode ser agregado a um portal mais completo, como
acontece com o Jetspeed, também da Apache, que possui o Pluto como portlet container.
Usaremos a versão 1.1.4, que possui o portal e uma suite de testes de portlets, além da
versão 5.5 do Tomcat, tudo integrado e pronto para uso. Essa versão pode ser encontrada
em http://portals.apache.org/pluto, com o nome pluto-current-bundle.zip.

Criando a estrutura do projeto


Neste exemplo utilizaremos o Maven 2 para criação do projeto e assembly do portlet. O
Maven é um projeto também da Apache utilizado para criação, construção e agrupamento
de projetos determinados por um XML descritor de projetos – Project Object Model. Para
mais informações e download do utilitário, veja a seção Links no final do artigo.
Para criação do projeto de portlet, vamos executar o seguinte comando do Maven:
mvn archetype:create -DgroupId=cadusu.portlet -DartifactId=CadastroUsuario
-DarchetypeArtifactId=maven-archetype-portlet

Um novo diretório, abaixo do diretório onde foi executado o comando, será criado com o
nome “CadastroUsuario” com a estrutura, arquivos e bibliotecas necessárias. Na raiz do
diretório haverá o arquivo pom.xml, onde estão as definições do Maven para assembly do
projeto, que por default é no ambiente do Jetspeed (Projeto de portal da Apache). Devemos
alterá-lo incluindo as definições para o Pluto. Para isso, insira o código da Listagem 1 no
arquivo.

Listagem 1. Fragmento do arquivo de configuração de projetos do Maven


<profiles>
...
<profile>
<id>pluto</id>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>${project.build.directory}/pluto-resources/web.xml</webXml>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.pluto</groupId>
<artifactId>maven-pluto-plugin</artifactId>
<version>1.1.4</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
...
</profiles>

Construindo o projeto no Eclipse


Para gerar o projeto no formato do Eclipse, entre no diretório criado pelo comando do
Maven no passo anterior e execute:
mvn -Declipse.workspace=<caminho-workspace-eclipse> eclipse:add-maven-repo
mvn -Dwtpversion=1.0 -DdownloadSources=true eclipse:eclipse

Via Eclipse, importe o projeto com o Wizard “Importar projeto existente” e apontando
para o diretório do portlet criado.
Temos então todo o ambiente para desenvolvimento criado, com a estrutura apresentada
na Figura 4.

Figura 4. Estrutura de arquivos do projeto no Eclipse

Vamos criar um projeto simples, de cadastro e detalhamento de usuários. Definiremos


então a classe representando o Usuário. Crie uma nova classe no pacote cadusu.dados
chamada Usuario, como na listagem 2:

Listagem 2. Classe representando o Usuário no projeto


package cadusu.dados;

public class Usuario {


private String nome;
private String endereco;
private String sexo;
private Integer idade;

//Setters e Getters públicos


}

E vamos as classes que implementam a interface Portlet. A API nos fornece uma
implementação básica da interface javax.portlet.Portlet, a classe GenericPortlet, do mesmo
pacote. Essa classe provê também alguns métodos para tratamento dos modos dos portlets
como o doView() (modo de visualização), doEdit() (modo de edição) e doHelp() (modo de
ajuda). Crie as classes CadastroPortlet e DetalhePortlet no pacote cadusu.portlet, com os
códigos da listagem 3 e 4 respectivamente, essas classes representam os portlets de
cadastramento e detalhamento dos usuários:

Listagem 3: Classe CadastroPortlet, responsável pela chamada da interface e regra de negócio


do cadastro de usuários
package cadusu.portlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.portlet.*;

import cadusu.dados.Usuario;

public class CadastroPortlet extends GenericPortlet {

protected void doView(RenderRequest request, RenderResponse response)


throws PortletException, IOException {
PortletRequestDispatcher prd = getPortletContext()
.getRequestDispatcher("/WEB-INF/jsp/cadastroUsuario.jsp");
prd.include(request, response);
}

public void processAction(ActionRequest request, ActionResponse response)


throws PortletException, IOException {

String acao = request.getParameter("acao");


PortletSession session = request.getPortletSession();
List listaUsuarios = (List) session.getAttribute("usuarios");

if ("salvar".equalsIgnoreCase(acao)) {

if (listaUsuarios == null) {
listaUsuarios = new ArrayList();
session.setAttribute("usuarios", listaUsuarios);
}

Usuario usuario = new Usuario();


usuario.setNome(request.getParameter("nome"));
usuario.setEndereco(request.getParameter("endereco"));
usuario.setSexo(request.getParameter("sexo"));
usuario.setIdade(new Integer(request.getParameter("idade")));
listaUsuarios.add(usuario);
} else if ("detalhar".equalsIgnoreCase(acao)) {
String strCodigo = request.getParameter("codigo");
int codigo = new Integer(strCodigo).intValue();
Usuario usuario = (Usuario) listaUsuarios.get(codigo - 1);
request.getPortletSession().setAttribute("usuario", usuario,
PortletSession.APPLICATION_SCOPE);
}
}
}

Listagem 4: Classe DetalhePortlet, responsável pela chamada da interface e regra de negócio


do detalhamento de usuários
package cadusu.portlet;

import java.io.IOException;

import javax.portlet.*;

public class DetalhePortlet extends GenericPortlet {

protected void doView(RenderRequest request, RenderResponse response)


throws PortletException, IOException {
PortletRequestDispatcher prd = getPortletContext()
.getRequestDispatcher("/WEB-INF/jsp/detalheUsuario.jsp");
prd.include(request, response);
}

As classes das listagens 4 e 5 serão referenciadas aos portlets de cadastro e detalhamento


de usuários no arquivo portlet.xml, que veremos mais à frente.
O método processAction() da classe CadastroPortlet trata a ação feita pelo usuário através
do formulário de cadastro, armazenando os registros em um List caso o usuário submita um
novo cadastro ou, se for solicitado um detalhamento do registro, atribui o objeto informado
via parâmetro na sessão do portlet para que o portlet de detalhamento consiga acessá-lo e
exibir suas informações, atividade feita no método processAction() da classe
DetalhePortlet.
Após processar a requisição do cliente, o portlet container executa o método
renderRequest(), conforme vimos na seção sobre o ciclo de vida dos portlets. Em nosso
exemplo, estamos apenas despachando a requisição para as respectivas JSPs. Crie no
diretório /WEB-INF/jsp/ os arquivos cadastroUsuario.jsp, representando a apresentação do
portlet Cadastro de Usuários conforme a listagem 5 e o arquivo detalheUsuario.jsp
representando o portlet Detalhamento de Usuários conforme a listagem 6.

Listagem 5: Página cadastroUsuario.jsp, contendo o formulário de cadastro


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

<portlet:defineObjects/>

<% //Adiciona o objeto em pageContext para acesso via EL


pageContext.setAttribute("usuarios",
renderRequest.getPortletSession().getAttribute("usuarios")); %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Cadastro de Usuários</title>
</head>
<body>
<center><h2>Cadastro de Usuários</h2></center>
<form method="post" action="<portlet:actionURL/>">
<input type="hidden" name="acao" value="salvar">
<table border="0">
<tr>
<td width="100" align="right">Nome:</td><td><input name="nome" type="text"
size="40"/></td>
</tr>
<tr>
<td width="100" valign="top" align="right">Endereço:</td><td><textarea name="endereco"
cols="30" rows="3"></textarea></td>
</tr>
<tr>
<td width="100" align="right">Sexo:</td><td><input type="radio" name="sexo" value="M"
checked="checked"/> M <input name="sexo" type="radio" value="F"/> F</td>
</tr>
<tr>
<td width="100" align="right">Idade:</td><td><input name="idade" type="text" size="3"
maxlength="3"/></td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit" value="Salvar"/></td>
</tr>
</table>
</form>

<%-- A tag <portlet:actionURL/> cria uma URL para execução da ação do portlet
(processAction()) --%>
<form method="post" action="<portlet:actionURL/>" name="<portlet:namespace/>frmDetalhar">
<input type="hidden" name="acao" value="detalhar">
<input type="hidden" name="codigo">

<table border="1" width="90%" align="center">


<thead>
<tr>
<td>Código</td><td>Nome</td>
</tr>
</thead>
<tbody>
<c:forEach items="${usuarios}" var="usuario" varStatus="rowNum">
<tr>
<td><a href="javascript:<portlet:namespace/>_enviar('<c:out value="$
{rowNum.count}"/>')"><c:out value="${rowNum.count}"/></a></td><td><c:out value="$
{usuario.nome}"/></td>
</tr>
</c:forEach>
</tbody>
</table>
<script type="text/javascript">
<%-- A tag <portlet:namespace/> define um identificador único para o portlet, lembre-se de
que
em uma página podem existir vários portlets, a tag previne conflitos entre declarações --
%>
function <portlet:namespace/>_enviar(codigo) {
<portlet:namespace/>frmDetalhar.codigo.value = codigo;
<portlet:namespace/>frmDetalhar.submit();
}
</script>
</form>
</body>
</html>

Listagem 6: Página detalheUsuario.jsp, contendo o layout de exibição dos dados do registro


selecionado
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

<portlet:defineObjects/>

<%
//Adiciona o objeto em pageContext para acesso via EL
pageContext.setAttribute("usuario",
renderRequest.getPortletSession().getAttribute("usuario",
javax.portlet.PortletSession.APPLICATION_SCOPE));
//Limpa o objeto da sessão após consumí-lo
renderRequest.getPortletSession().setAttribute("usuario", null,
javax.portlet.PortletSession.APPLICATION_SCOPE);
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Detalhar Usuários</title>
</head>
<body>
<center><h2>Detalhes do Usuário</h2></center>
<br/>
<c:if test="${usuario == null}">
<h4>Selecione um usuário para exibir seus detalhes...</h4>
</c:if>
<c:if test="${usuario != null}">
<table border="1" width="90%" align="center">
<tr>
<td align="right" width="100">Nome:</td><td><c:out value="${usuario.nome}"/></td>
</tr>
<tr>
<td align="right">Endereço:</td><td><c:out value="${usuario.endereco}"/></td>
</tr>
<tr>
<td align="right">Sexo:</td><td><c:out value="${usuario.sexo}"/></td>
</tr>
<tr>
<td align="right">Idade:</td><td><c:out value="${usuario.idade}"/></td>
</tr>
</table>
</c:if>
</body>
</html>

Com os arquivos criados, precisamos agora informar ao portlet container que nosso
projeto possui 2 portlets e referenciar suas respectivas classes. O arquivo responsável por
isso é o portlet.xml, no diretório WEB-INF. Esse arquivo especifica cada portlet disponível
no projeto, assim como o arquivo web.xml especifica os servlets em um servlet container. A
tag <portlet> representa um portlet no projeto, para mais detalhes sobre cada tag no
documento, vide a especificação de portlets, para acessá-la veja a seção de links no final do
artigo. O arquivo portlet.xml do projeto deve ficar igual ao exibido na listagem 7.

Listagem 7: Arquivo descritor de portlets: portlet.xml


<?xml version="1.0" encoding="UTF-8"?>

<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">

<portlet>
<description>Formulário de cadastramento de usuários no sistema</description>
<portlet-name>CadastroPortlet</portlet-name>
<display-name>Cadastro Portlet</display-name>

<portlet-class>cadusu.portlet.CadastroPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>

<supported-locale>en</supported-locale>

<portlet-info>
<title>Cadastro de Usuarios</title>
<short-title>Cadastro de Usuarios</short-title>
<keywords>cadastro usuario</keywords>
</portlet-info>
</portlet>

<portlet>
<description>Portlet para exibição dos detalhes do usuário</description>
<portlet-name>DetalhePortlet</portlet-name>
<display-name>Detalhe Portlet</display-name>

<portlet-class>cadusu.portlet.DetalhePortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>

<supported-locale>en</supported-locale>

<portlet-info>
<title>Detalhamento de Usuarios</title>
<short-title>Detalhamento de Usuarios</short-title>
<keywords>detalhe usuario</keywords>
</portlet-info>
</portlet>
</portlet-app>

Finalizamos a implementação de nosso exemplo, precisamos agora descompactar e


instanciar o Pluto Portal. Esse portal foi desenvolvido apenas para testes do portlet
container do Pluto. O arquivo para download informado na seção Sobre o Pluto é uma
versão do servidor de aplicação Tomcat já com o Pluto Portal configurado e pronto para
uso.
Descompacte o zip baixado em um diretório à sua escolha e execute:
Windows:
<diretório onde o arquivo foi descompactado>/pluto-{versão}/bin/startup.bat

Unix/Linux:
<diretório onde o arquivo foi descompactado>/pluto-{versão}/bin/startup.sh

Com isso, o Tomcat será iniciado (certifique-se de já não ter outra aplicação utilizando a
porta 8080). Agora, acesse o Pluto Portal pela URL http://localhost:8080/pluto/portal, a tela
de login será exibida, conforme ilustrado na figura 5. Por padrão, o usuário é pluto e a
senha também.

Figura 5. Pluto Portal

O deploy com o Pluto é dividido em duas partes:


1. Assembly: Nessa fase vamos criar o arquivo WAR para efetivar o deployment no Pluto
Portal. No diretório do projeto, vamos executar o Maven para criar o arquivo:
mvn package –P pluto
Executado com sucesso, será criado um diretório Target com o arquivo WAR do
projeto já com as configurações do Pluto para o deploy;
2. Deploy: No Pluto Portal, navegue na página Pluto Admin. No portlet Pluto Page
Administration haverá um link Upload and deploy a new portlet war, que lhe
redirecionará para o gerenciador de aplicações do Tomcat, faça o deploy do WAR.

Feito o deploy vamos adicionar os portlets em uma página do Pluto Portal. No portlet
Pluto Page Administration, adicione uma nova página chamada “Minha Página” e em
Portlet Applications, adicione os dois portlets que criamos nela, como na figura 6.

Figura 6 Adicionando portlets nas páginas do Pluto

Note que após criada a página “Minha Página”, um link para ela foi criado no menu
superior. Ao adicionar portlets nas páginas do Pluto Portal, eles automaticamente são
arranjados, conforme exibido na figura 7. A maioria dos portais comerciais como o IBM
Websphere Portal ou JBOSS Portal permitem a configuração da disposição dos portlets na
página, como a intenção do Pluto Portal é apenas permitir testes essa funcionalidade não foi
implementada.
Figura 7. Página do Pluto com os portlets criados

Conclusão
A especificação padronizada de portlets ainda está em sua primeira versão, ao contrário da
evolução das API proprietárias, como da IBM, BEA, Oracle, que são implementadas desde
2002. Muita coisa ainda precisa ser definida e já está em andamento a JSR 286 (segunda
versão da especificação) que promete muita coisa nova, adicionando maturidade ao
framework.
Dentro desta evolução a API já permite adicionar outros frameworks de desenvolvimento,
como JavaServer Faces e Struts, assim a migração de aplicações com esta arquitetura pode
ser devidamente realizadas em um container de portlet.
O desenvolvimento orientado a portlets é uma realidade nas grandes corporações no Brasil
e no mundo, portanto, leve em consideração os benefícios desta arquitetura em seus futuros
projetos.

Links
http://portals.apache.org/pluto/install.html
Site com download e documentação do Apache Pluto
http://www-
128.ibm.com/developerworks/websphere/library/techarticles/0403_hepper/0403_hepper.html
Best pratices de desenvolvimento de portlets
http://jcp.org/aboutJava/communityprocess/final/jsr168/
Especificação JSR168 para portlets
http://maven.apache.org/
Site com download e documentação do Maven
http://www.ibm.com/developerworks/websphere/library/tutorials/0606_coqueiro/0606_coquei
ro.html
Desenvolvendo portlet com ferramenta gráfica
http://www.ibm.com/developerworks/websphere/zones/portal/
Portal especializado em conteúdo destinado a portlets
Gustavo Concon (gconcon@br.ibm.com) é desenvolvedor Java/Java EE especialista
em tecnologias para desenvolvimento em portal e web. Tem as certificações SCJP,
SCWCD, SCBCD.

Alex Barbosa Coqueiro (alexbc@br.ibm.com) é especialista em portais corporativos


na IBM com experiência de mais de dez anos no desenvolvimento OO e professor na
FIAP. Tem as certificações SCJP, SCWCD e SCEA, e em WebSphere Portal Server,
WebSphere Portlet Factory, WebSphere Application Server e Rational Application
Developer.

Você também pode gostar