Tecnologia da Informação. Desenvolvimento de Software. Tendências. Linguagem de programação. Metodologias.
segunda-feira, 2 de janeiro de 2012
Deixando a compilação do GWT mais rápida
A demora da compilação é porque o GWT efetua iterações para cada motor de HTML existente (Gecko, Webkit, etc). Mas no desenvolvimento vocẽ pode testar em apenas um browser, sendo que o GWT garante a compatibilidade com os demais. Então basta incluir no módulo a ser compilado a seguinte configuração:
<set-property name="user.agent" value="gecko1_8" ></set-property>
Mude o valor para o motor do web browser que você está utilizando. Quando terminar de desenvolver basta remover esta propriedade que a compilação efetuará todas as iterações.
Abraços.
Implementando em Java Web Services Fácil
domingo, 1 de janeiro de 2012
Tutorial - AOP (Orientação a aspectos) com Spring
package org.springframework.aop.sample;
public class Monitorable implements IMonitorable{
@Overridepublic void execute(){
System.out.println("Executing method");
}
}
|
package org.springframework.aop.sample;
public class Monitor implements IMonitor{
@Override
public void after(){
System.out.println("Aspecto - after");
}
@Overridepublic void afterThrowing(){
System.out.println("Aspecto - after-throwing");
}
@Overridepublic void before(){
System.out.println("Aspecto - before");
}
}
|
xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
">
<aop:config>
<aop:aspect ref="sampleMonitor">
<aop:pointcut id="daoExec" expression="execution(* org.springframework.aop.sample.IMonitorable.*(..))"/>
<aop:before method="before" pointcut-ref="daoExec"/>
<aop:after method="after" pointcut-ref="daoExec"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="daoExec"/>
aop:aspect>
aop:config>
<bean id="sampleMonitor" class="org.springframework.aop.sample.Monitor"/>
<bean id="sampleMonitorable" class="org.springframework.aop.sample.Monitorable"/>
beans>
|
package org.springframework.aop.sample;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
BeanFactory ctx = new ClassPathXmlApplicationContext("hello.xml");
IMonitorable monitorable = (IMonitorable) ctx.getBean("sampleMonitorable");
monitorable.execute();
}
}
|
Um tutorial utilizando Liferay e Struts
O Liferay é um gerenciador de portais que se beneficia da tecnologia Java. No Liferay, as aplicações são divididas em Portlets. O conceitos e funcionalidades dos Portlets são definidas nas JSR 168 e JSR 286.
Também, nesse gerenciador de portais, utiliza-se o conceito de aplicações dritribuidas em plugins. Como vamos ver logo mais, as aplicações desenvolvidas não ficam atreladas diretamente ao Liferay, elas são carregadas separadamente como se fossem aplicações web independentes. Mas o Liferay consegue executar as funções das outras aplicações como plugins. Assim, pode-se dividir as aplicações por funcionalidade, cada uma em um WAR diferente e combina-las de forma diferente. No liferay existem plugins para Temas, Struts, Spring, Tapestry, entre vários outros. Na verdade estes plugins já estão prontos, podemos apenas alterar a lógica a carrega-los no Liferay. Mas podemos criar nosso próprios plugins.
Para este exemplo vamos utilizar o Liferay 5.1.2, para tanto vamos baixar o servidor tomcat com o liferay já configurado. Está disponível no endereço abaixo:
ou no link abaixo na sessão download procure por Bundled with tomcat 5.5:
Também vamos precisar da aplicação de exemplo do Struts que está disponível no link abaixo:
Download Projeto Struts Liferay
ou através do site www.liferay.com na área download/communit plugins procure por Sample Struts.
Depois de baixar o plugin para Struts, descompacte. Nesse plugin utiliza-se do Struts 1.3.9. Ao verificar a estrutura do arquivo descompactado temos a seguinte:
Vamos analisar alguns dos descritores que estão contidos na pasta WEB-INF:
struts-confi.xml:
É arquivo onde estarão disponíveis as configurações principais do Struts. Tais como mapeamentos para as Actions, mapeamentos para as ActionForms, plugins para Strus, etc.
tiles-defs.xml:
Este arquivo de configuração define alguns templates utilizando-se o framework Tiles, o qual pode ser integrado com Struts através de um plugin. Será interessante utilizar esta funcionalidade para não ficar repetindo as mesmas declarações nos JSP's que iremos criar.
portlet.xml:
Arquivo onde vamos declarar os nossos portlets. Nesse arquivo vão informações como nome do portlet, qual a página principal, pagina de ajuda, etc. São as configurações iniciais dos portlets.
liferay-display:
Este descritor define uma categoria, ou sub-categoria, onde os portlets da aplicação estarão disponíveis para carga dentro do Liferay.
Vamos então criar um portlet. Primeiro vamos criar um portlet simples, sem a utilização de uma classe Action. Não significa que não vamos utilizar o arquivo de configuração do Struts ou do Tiles neste exemplo.
Vamos começar criando nosso jsp. Segue abaixo o nosso JSP:
Hello World! |
Este JSP vai se chamar sample.jsp e ficará armazenado dentro do diretório /html/sample/samplejspportlet do nosso projeto.
Agora nós vamos criar uma pasta denominada common em /html/sample e vamos copiar o arquivo init.jsp da pasta /html/sample_struts_liferay_portlet para dentro dela. Este arquivo vem com as configurações iniciais de importação de tags e importações mais utilizadas. Depois de copiar o arquivo init.jsp com as configurações iniciais vamos criar a página de template. A seguir será listada página template.jsp contendo as definições do nosso template.
<%@ include file="/html/portlet/sample_struts_portlet/init.jsp" %> <tiles:useAttribute id="tilesPortletContent" name="portlet_content" classname="java.lang.String" ignore="true" /> <div> <jsp:include page='<%="/html" + tilesPortletContent %>' flush="true" /> div> |
Analisando a página podemos ver que o template inclui a página init.jsp que copiamos. Significa que não vamos precisar fazer as mesmas importações para cada página que criarmos. Podemos observar que existe uma tag tiles. Esta tag está criando uma variável chamada tilesPortletContent (através da propriedade id) dentro do jsp, mas que para o tiles vai ser chamada de portlet_content (definido através da propriedade name). Também nesta tag podemos ver que o tipo da valor que a variável receberá será uma String.
Com a página criada vamos mexer nas configurações dos descritores xml.
TILES-DEFS:
O Tiles, como mencionado anteriormente funciona como um gerenciador de template. Vou mostrar o xml de configuração do nosso template e depois vou explicar os itens contidos nele. Segue o xml:
<definitionname="portlet.sample.template" path="/html/portlet/sample/common/template.jsp"/> |
No xml anterior temos duas propriedades, name e path. A propriedade name representa uma identificador único para nosso template. A propriedade path indica o diretório de nosso template.
Com nosso tempalte pronto, vamos configurar a nossa página sample.jsp. As configurações da página no descritor tiles-defs segue abaixo:
<definition name="portlet.sample.samplejspportlet.sample" extends="portlet.sample.template"> <put name="portlet_content" value="/portlet/sample/samplejspportlet/sample.jsp" /> definition> |
Vemos aqui a utilização do nosso template, pois criamos uma nova definição estendendo do template que criamos anteriormente. O que difere da definição do template é que temos uma tag put. Esta tag vai incluir na variável portlet_content (que está definida em nosso template através da tag tiles:useAttribute) o valor “/portlet/sample/samplejspportlet/sample.jsp”. Se voltar ao nosso template vamos perceber que vamos dar um include na página situada no diretório /html/portlet/sample/samplejspportlet/sample.jsp.
STRUTS-CONFIG:
Com o nosso tempalte criado vamos criar um FowardAction que vai redireconar uma determinada url para o nosso mapeamento definido no Tiles. Segue o mapeamento do nosso action:
<action path="/sample/samplejspportlet/sample" forward="portlet.sample.samplejspportlet.sample"/> |
Aqui podemos ver que criamos um identificador para no FowardAction (atributo path) e uma URL para onde será redirecionada a requisição. No caso, cada requisição direcionada ao Servlet do Strtus com a URL “/sample/samplejspportlet/sample” será redirecionada a URL “portlet.sample.samplejspportlet.sample”. O valor contido no atributo não é realmente uma URL, mas sim uma identificador de qual será a página mapeada no Tiles que irá ser carregada. No caso nossa página sample.jsp.
Uma informação interessante, é que o exemplo baixado do site do Liferay já inclui o plugin de integração Struts/Tiles no arquivo struts-config.xml. Para ver como é a inclusão do plugin é só dar uma olhada no final da arquivo strtus-config.xml.
PORTLET:
Vamos incluir agora a declaração do nosso portlet no descritor portlet.xml. Segue abaixo o mapeamento que vamos incluir:
<portlet> <portlet-name>sample.samplejspportlet.sampleportlet-name> <display-name>Struts Testdisplay-name> <portlet-class>org.apache.portals.bridges.struts.StrutsPortletportlet-class> <init-param> <name>ServletContextProvidername> <value>com.liferay.util.bridges.struts.LiferayServletContextProviderWrappervalue> init-param> <init-param> <name>ViewPagename> <value>/portlet_action/sample/samplejspportlet/samplevalue> init-param> <expiration-cache>0expiration-cache> <supports> <mime-type>text/htmlmime-type> supports> <portlet-info> <title>XXXXXXXtitle> portlet-info> portlet> |
Vamos ver as principais tag de mapeamento.
Agora pegue todas as pastas contidas na raís do projeto (WE-INF e html) e zipe-as em um arquivo. Depois altere a extenção para war.
Com estas etapas prontas vamos carregar nossa aplicação no Liferay. Primeiro deve-se incializar o servidor (na pasta bin/startup.sh ou bin/startup.bat). Vamos abrir um browser e ir para url http://localhost:8080/. Então você verá algo como a imagem a seguir:
O login padrão do liferay é “test@liferay.com” e a senha é “test”. Após efetuar o login vamos selecionar no menu onde está dizendo “Welcome Joe Blogs” a opção “Add Application”. Vai aparecer o menu flutuante na janela, abra expanda a categoria “Admin” e adicione o portlet Admin.
No portlet que for carregado clique em “plugins” e depois em “Install more Portlet”. Selecione a opção Upload File e no botão “Arquivo...” selecione o arquivo war onde zipamos nossa aplicação. Depois clique em “install”.
Agora vamos ver nossa aplicação. Clique na página Welcome. Depois vá ao menu novamente e selecione “Add Application”. Então selecione a categoria “Sample” e adicione o portlet “XXXXXXX”.
Nosso portlet estará na página principal dizendo “Hello World!”.
Em outra oportunidade vou criar o parte II do tutorial para incluir uma action. Na verdade, não é muito complexo agora que já criamos um FowardAction dentro Struts, bastaria seguir a mesma linha de raciocínio para criar uma classe action.
Injeção de dependências com Spring
Vamos ver o seguinte caso. O senhor Bilbo possui uma loja de roupas e quer identificar qual a profissão de cada indivíduo que entra na sua loja. Poderíamos ter diversos tipos de trabalhadores que trabalham de forma diferente, então vamos criar uma interface para que suporte as diferentes implementações dos trabalhadores. Nossa interface vai se chamar IWorker:
Interface IWorker:
packageorg.samples.spring.injection; publicinterfaceIWorker{ publicvoidwork(); } |
Basicamente é um trabalhador e ele trabalha. Agora vamos a uma implementação mais específica, vamos implementar uma classe trabalhador. Conversando com o Sr. Bilbo, descobrimos que ele adora programadores. Então, como é de preferência do dono da loja, vamos implementar o trabalhador programador.
Classe Programmer:
packageorg.samples.spring.injection.programmer; importorg.samples.spring.injection.IWorker; publicclassProgrammerimplementsIWorker{ privateStringlanguage; publicStringgetLanguage(){ returnlanguage; }
publicvoidsetLanguage(Stringlanguage){ this.language=language; }
@Override publicvoidwork(){ System.out.println("Programando em "+this.getLanguage()); }
}
|
Em outra conversa com o cliente, ficamos chocados quando nos contou que sua loja foi arrombada varias vezes. Então para ajudá-lo a verificar quais são os arrombadores criamos a classe concreta:
Classe Burglar:
packageorg.samples.spring.injection.burglar; importorg.samples.spring.injection.IWorker; publicclassBurglarimplementsIWorker{ privateStringtool; publicBurglar(Stringtool){ this.tool=tool; } publicStringgetTool(){ returntool; }
publicvoidsetTool(Stringtool){ this.tool=tool; }
@Override publicvoidwork(){ System.out.println("Arrombando com "+this.getTool()); }
}
|
Depois de estipular as principais necessidades, vamos verificar o trabalho dos cliente da loja do Sr. Bilbo.
Vimos que as implementações até o momento foram desenvolvidas sobre interfaces. Isso é importante e já veremos o porque. O Spring necessita de um arquivo de configuração onde ficam mapeadas as classes a serem injetadas. Essas classes serão carregadas no container do Spring mas só serão instanciadas a partir da primeira requisição a classe desejada. Abaixo segue o xml utilizado no projeto.
hello.xml
<?xml version="1.0" encoding="UTF-8"?> DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean id="programmer" class="org.samples.spring.injection.programmer.Programmer"> <property name="language" value="Java"/> bean> <bean id="burglar" class="org.samples.spring.injection.burglar.Burglar"> <constructor-arg value="pé-de-cabra"/> bean> beans> |
Agora que criamos o arquivo de configuração, vamos a ação. Depois vamos verificar o que significa cada item da mapeamento.
Segue abaixo a implementação da classe Main:
Class Main:
packageorg.samples.spring; importorg.samples.spring.injection.IWorker; publicclassMain{ /** *@paramargs */ publicstaticvoidmain(String[]args){ BeanFactoryfactory=newXmlBeanFactory(newFileSystemResource("hello.xml")); IWorkerworker1=(IWorker)factory.getBean("programmer"); worker1.work(); IWorkerworker2=(IWorker)factory.getBean("burglar"); worker2.work(); }
} |
E quando executamos esse código temos a seguinte saida:
Programando em Java Arrombando com pé-de-cabra |
Anteriormente mencionei que a programação para interfaces é muito importante. Podemos ver uma pequena parte do benefício que esta técnica nos traz. No nosso exemplo recuperamos dois beans do container Spring, mas nossa classe Main, faz a menor idéia de que classes são, apenas que implementam a interface IWorker.
Pode parecer simples, mas abstraimos toda a parte de implementação de um componente específico de nosso exemplo para uma interface. Assim nossa classe Main não precisa se preocupar em qual classe foi retornada pelo container, mas apenas em executar o serviço. Se fosse necessário criar uma nova classe para substituir a classe Programmer, esta classe implementaria a interface IWorker e nossa classe Main nunca ficaria sabendo.
Bom, agora vamos dar uma olhada no código do descritor que criamos para nossa aplicação.
<bean id="programmer" class="org.samples.spring.injection.programmer.Programmer"> <property name="language" value="Java"/> bean> |
Ao criarmos inserirmos a tag bean em nosso descritor, definimos que vamos declarar um bean que será carregado no container. A propriedade id define um identificador para o nosso bean e a propriedade class define qual classe será carregada.
Logo depois temos a tag property. Esta tag define que estamos setando um valor a um atributo de nosso bean. Ou seja, no caso, a tag name referência qual a atributo será setado, e a propriedade value, o valor propriamente dito que será setado.
Agora vamos ver nosso outro bean.
<bean id="burglar" class="org.samples.spring.injection.burglar.Burglar"> <constructor-arg value="pé-de-cabra"/> bean> |
Podemos perceber que é praticamente igual ao bean anterior. O que diferencia é a tag constructor-arg. Bom, essa tag nos diz que será setado um valor no construtor da nossa classe, no caso, Burglar.
Agora vamos ver uma situação interessante. O Spring possui escopos para a carga de sua classes. Ou seja, podemos dizer que nossas classes são carregadas de formas diferentes. Por default, o Spring utiliza o escopo Singleton. Então o bean será carregado apenas uma vez, e será uma para toda a aplicação. Vamos fazer um teste.
Inclua as seguintes linha no método main anteriormente listado:
((Programmer)worker1).setLanguage("Ruby"); IWorkerworker3=(IWorker)factory.getBean("programmer"); worker3.work(); |
Se rodar o exemplo novamente vamos ter a seguinte saida:
Programando em Java Arrombando com pé-de-cabra Programando em Ruby |
Bom, nós alteramos o estado de um bean adquirimos do BeanFactory, mas como o escopo é Singleton, só existe uma instância do bean Programmer.
Podemos alterar esse comportamento incluindo a propriedade scope=”prototype” na tag bean de nosso bean Programmer. Prototype diz que para cada chamada para recuperar uma instância do bean Programmer, temos uma nova instância.
O novo resultado será:
Programando em Java Arrombando com pé-de-cabra Programando em Java |
Existem outros escopos para Spring (request, session e global-session), mas os restantes são para Conteiners Web.
Ficamos por aqui com este tutorial, mas em breve estarei de volta com novos tutos.