springframework2-5-anexo1-diegopacheco-100808102945-phpapp02

Page 1

Adendo - Spring Framework (2.5) Framework para Desenvolvimento de Aplicações em Java

Diego Pacheco Set/2009

Apostila desenvolvida especialmente para a Crom Microsystems. Sua cópia ou reprodução é livre.



Sobre o Autor

Diego Pacheco Técnico em Processamento de Dados e graduando em Ciências da Computação (7º sem.) na Ulbra. Já trabalhou com desenvolvimento de software em VB, ASP, .NET e PHP. Atualmente é Arquiteto de Software, certificado pela Sun, atua desenvolvendo soluções corporativas em arquitetura JEE, provendo coaching/mentoring em software e processo de desenvolvimento de software. Gosta muito de música, tocar guitarra, jogar PSP, Bloggar, Ler - principalmente as incríveis histórias do Conan -. Mantem o blog < http://diego-pacheco.blogspot.com/> a mais de 3 anos.


Spring Framework – Framework para Desenvolvimento de Aplicações Java

Sumário Sobre o Autor .................................................................................................................................. 3

6. Anotações e Web .............................................................................................................. 1 Objetivos ...................................................................................................................................... 2 Anotações no Java.................................................................................................................. 3 Anotações no Spring Framework .................................................................................... 7 Anotações para injeção ........................................................................................................ 9 Testes Unitários com TestNG ........................................................................................... 14 Integração com JSF ............................................................................................................... 18 Expondo os seus beans via JMX ................................................................................... 29 Espaço para anotações ....................................................................................................... 33

Diego Pacheco – http://diego-pacheco.blogspot.com

I


Spring Framework – Framework para Desenvolvimento de Aplicações Java

6. Anotações e Web

Diego Pacheco – http://diego-pacheco.blogspot.com


Spring Framework – Framework para desenvolvimento de aplicações java

Objetivos •

Conhecer os recursos básicos de anotações do Spring Framework;

Saber construir testes unitários utilizando TestNG com anotações e Spring Framework.

Saber como integrar o Spring Framework a uma aplicação Web com JSF.

Saber como expor um bean do Spring como um JMX.

Diego Pacheco – http://diego-pacheco.blogspot.com

2


Spring Framework – Framework para desenvolvimento de aplicações java

Anotações no Java

Com o lançamento da versão 5 do Java, ganhamos um poderoso recurso, as anotações. Antes do Java 5 a comunidade já tinha inventado algumas maneiras de trabalhar com metadados, isto era feito com o Xdoclet e outras soluções similares, mas a abordagem tinha alguns problemas. Dentre os diversos problemas, destaco a propenção a erros, pois o recurso nada mais era do que algumas tags em um bloco de documentação do Javadoc. Além disso, a documentação ficava misturada com metadados e sempre era necessário executar uma task ant para realizar a leitura das informações e aplicar o processamento necessário. Agora com as anotações é possivel ter estes recursos de forma nativa e com muito mais beneficios, porque este recurso já vem com o Java e o compilador do Java - o Javac - verifica sintática e semânticamente a validade das anotações. Quando trabalhamos com anotações podemos definir em que tempo do programa vamos utilizar este recurso, os valores possíveis são definidos pela enumeração java.lang.annotation.RetentionPolicy conforme segue a baixo: • SOURCE • CLASS • RUNTIME A retenção do tipo SOURCE é descartada pelo compilador, ou seja, só é valida em tempo de design. A retenção do tipo CLASS é a padrão, o compilador marca na classe mas a JVM não mantem essa informação acessível em tempo de runtime. Se você deseja acessar a anotação em tempo de runtime, precisa utilizar a retenção do tipo RUNTIME e com isso você pode acessar o elemento anotado via reflection. Além das informação sobre o tipo de retenção das anotações, quando criamos este tipo de recurso ainda precisamos especificar qual é o alvo da anotação, ou seja, em que tipo de elemento ela vai estar atuando. Os elementos suportados são definidos pela enumeração java.lang.annotation.ElementType, que segue abaixo: • TYPE • FIELD • METHOD • PARAMETER • CONSTRUCTOR Diego Pacheco – http://diego-pacheco.blogspot.com

3


Spring Framework – Framework para desenvolvimento de aplicações java

• LOCAL_VARIABLE • ANNOTATION_TYPE • PACKAGE

Os recursos mais utilizados em termos de elementos são para interfaces e classes através do TYPE, para métodos o elemento METHOD e para anotar pacotes o PACKAGE. As anotações são úteis para diversos motivos, pois conseguimos definir um modelo de metaprogramação de forma fácil e verificável. Confira um exemplo de utilização de anotações abaixo.

package com.blogspot.diegopacheco.springframework25.annotations.java; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Anotação que infica que um campo de uma classe nada pode ser nulo ou vazio. <br> * Logo você é obrigado a informar um valor ao campo que for anotado com esta anotação. * * @author Diego Pacheco * @version 1.0 * @since 26/09/2009 * */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface CampoObrigatorio { }

Código 6.1 CampoObrigatorio.Java – Anotação do Java 5 O código acima se refere a uma anotação, repare que para criar uma anotação foi utilizado mais 3 anotaões, duas você já conhece, são referentes a política de retenção e ao tipo de elemento anotadado. A anotação @Documented indica que esta anotação possui Javadoc. Repare também que para criar a anotação foi utilizado o @interface, isto é o que indica que é uma anotação para o compilador do Java. Diego Pacheco – http://diego-pacheco.blogspot.com

4


Spring Framework – Framework para desenvolvimento de aplicações java

Agora vamos colocar esta anotação em um objeto, confira o código abaixo: package com.blogspot.diegopacheco.springframework25.annotations.java; public class Pessoa { @CampoObrigatorio private Integer id; private String nome;

public Pessoa() { } public Pessoa(Integer id, String nome) { super(); this.id = id; this.nome = nome; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } @Override public String toString() { return "id: " + id + ",Nome: " + nome; } }

Código 6.2 Pessoa.Java – Pojo com anotação Repare que este é um pojo normal com dois atributos, sendo um nome do tipo String e um id do tipo Integer, além dos construtores vazio e full e seus métodos getters e setters. Perceba que o campo id está anotado, a anotação criada acima chamada @CampoObrigatório, agora vamos ao código que processa a anotação e manipula as informações da mesma, confira o código abaixo:

Diego Pacheco – http://diego-pacheco.blogspot.com

5


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.annotations.java; import java.lang.reflect.Field; public class TestaAnotacaoMain { public static void main(String[] args) { Pessoa p = new Pessoa(); p.setNome("Diego Pacheco"); try{ validate(p); System.out.println("Objeto válido!"); }catch(Exception e){ System.out.println("Objeto inválido!"); e.printStackTrace(); } } @SuppressWarnings("unchecked") public static void validate(Pessoa p) throws Exception { Class<Pessoa> clazz = (Class<Pessoa>) p.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(CampoObrigatorio.class)) { field.setAccessible(true); if (field.get(p) == null){ throw new RuntimeException("O campo obrigatório não foi informado. Objeto inválido! "); } } } } }

Código 6.3 TestaAnotacaoMain.Java – Pojo com anotação

No código acima, o objeto Pessoa é instânciado para a memória e apenas a propriedade nome é informada, perceba que o id não é informado em momento algum no código a cima. O método validate processa a validação do objeto Pessoa utilizando a API de reflecation do Java e é verificado se o campo anotado com a anotação @CampoObrigatorio tem valor, caso ele seja nulo uma exception é levantada informando este erro.

Diego Pacheco – http://diego-pacheco.blogspot.com

6


Spring Framework – Framework para desenvolvimento de aplicações java

Anotações no Spring Framework

O Spring é conhecido pela utilização de arquivos xml para configuração de injeção de dependências (DI) e bem como inversão de controle (IoC), utilizar xml é bom porque possibilita ao desenvolvedor ter em um único lugar todas as configurações de injeções do seu sistema, além de ser mais extensivél, porque podemos modificar o comportamento da aplicação sem abrir o código e sem ter que recompilar o código. Porém a utilização de xml tem desvantagens, como por exemplo, ser mais propença a erros de digitação e de configuração, além de ser menos produtivo do que as anotações, as anotações dão muito mais produtividade e simplicidade para o desenvolvedor. Apartir do Spring Framework 2.5 várias anotações ficaram disponíveis para facilitar o trabalho e prover um leque de opções maior do que existia nas outras versões da solução. Esta versão do Spring implementa a JSR-250 que é sobre anotações padrão do Java como @Resource, @PostConstruct, and @PreDestroy. Confira o código abaixo: package com.blogspot.diegopacheco.springframework25.annotations.spring; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.stereotype.Component; @Component public class AnotacoesJava { @PostConstruct public void init(){ System.out.println("Código de inicialização..."); } @PreDestroy public void shutdown(){ System.out.println("Código de shutdown..."); } }

Código 6.4 AnotacoesJava.Java – Classe que usa anotações padrão

Como você pode reparar a classe acima está utilizado duas anotações padrão do Java @PostConstruct, and @PreDestroy que serão executadas pelo spring depois de contruir o objeto e antes de destruir o mesmo.

Diego Pacheco – http://diego-pacheco.blogspot.com

7


Spring Framework – Framework para desenvolvimento de aplicações java

Para ativar este recurso no spring é necessário registrar um bean post processor padrão, confira esta configuração no código abaixo. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context2.5.xsd"> <context:annotation-config/> <context:component-scan base-package="com.blogspot.diegopacheco"/> </beans>

Código 6.5 spring-annotation-beans.xml – XML de configuração Existem 3 pontos importantes neste xml, o primeiro é a utilização do schema xsd chamado de context, é através dele que realizamos configurações no contexto do spring. O segundo ponto é a utilização da entrada annotation-config, isto registra os bean post processors do spring para tratamento de anotações. Por fim o terceito ponto é a utilização de component-scan que indica um pacote base, logo o spring vai varrer todos os subpacotes a procura de outros beans que estejam anotados. Vamos ver o código para testar a utilização de anotações com o Spring Framework 2.5, confira o código abaixo: package com.blogspot.diegopacheco.springframework25.annotations.spring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestaAnotacoesJava { public static void main(String[] args) { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring-annotation*.xml"); ctx.getBean("anotacoesJava"); ctx.registerShutdownHook(); } }

Código 6.6 TestaAnotacoesJava – Classe para testes Neste código foi instânciado o contexto do spring e obtido o bean anotado e depois o contexto foi derrubado com o registerShutdownHook().

Diego Pacheco – http://diego-pacheco.blogspot.com

8


Spring Framework – Framework para desenvolvimento de aplicações java

O Spring vai procurar beans com as seguintes anotações • @Component • @Service • @Repository • @Controller Caso ele encontre algum bean com alguma destas anotações, ele vai registrar o bean no contexto, o nome do bean vai ser definido da seguinte forma: Supondo que a classe se chama PessoaFisicaService o bean ter o mesmo nome só que com a primeira letra não captalizada, ou seja: pessoaFisicaService. A anotação @Component é a mais genérica do Spring, ela serve para indicar que é um bean gerenciado pelo Spring, você utiliza isso em qualquer bean de propósito geral. As outras anotações são mais específicas, elas indicam um serviço @Service, um objeto de controle (arquitetura MVC) @Controller e um objeto de acesso a dados, vulgo DAO com @Repository. Quando você utiliza @Service, @Component ou @Controller ainda não tem uma diferença prática, mas o spring pretende utilizar isso como informações para aspéctos em futuras implementações. Quanto a anotação @Repository, você já ganha o recurso de tradução de exceptions automaticamente, logo, não vai ter que lidar com exceptions específicas como as de lock otimista do JPA.

Anotações para injeção O Spring também prove anotações para injeção de beans. Para isso estão disponíveis as anotações: • @Resource • @Autowired A anotação @Resource faz a injeção baseado nos nomes dos beans e a anotação @Autowired faz baseada em tipos. Se você não trabalha com interfaces ou tem só uma implementação, pode usar @Autowired sem problemas, mas a sua aplicação pode crescer e com isso podem vir vários erros de injeção. Para resolver este problema precisamos qualificar a injeção utilizando a anotação @Qualifier indicando o identificador do bean que você quer. Diego Pacheco – http://diego-pacheco.blogspot.com

9


Spring Framework – Framework para desenvolvimento de aplicações java

Confira o código abaixo para ver a utilização destas anotações em prática. package com.blogspot.diegopacheco.springframework25.annotations.spring; import org.springframework.stereotype.Component; @Component public class Livro { private String isbn; private String titulo; public Livro() { isbn = "10ergregKL2"; titulo = "O código de Da vince"; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } @Override public String toString() { return "[livro={isbn: " + isbn + ",titulo: " + titulo + "}]"; } }

Código 6.7 Livro.java – Pojo Livro Este é um pojo simples, que foi anotado com a anotação @Component do spring framework 2.5, agora vamos ao bean autor, neste bean vamos injetar o código do livro que está acima. package com.blogspot.diegopacheco.springframework25.annotations.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component() public class Autor { private Integer id; private String nome; @Autowired private Livro livro; public Autor() {

Diego Pacheco – http://diego-pacheco.blogspot.com

10


Spring Framework – Framework para desenvolvimento de aplicações java

id=0; nome="Sem nome"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public Livro getLivro() { return livro; } public void setLivro(Livro livro) { this.livro = livro; } @Override public String toString() { return "id: " + id + ",Nome: " + nome + ", Livro: " + livro; } }

Código 6.8 Autor.java – Pojo Livro Como você pode perceber, foi utilziado a anotação @Autowired, para realizar a injeção, neste caso também poderíamos utilizar a anotação @Resource. Vamos ao código que sobe o contexto do Spring e por fim ao teste desta aplicação. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context2.5.xsd"> <context:annotation-config/> <context:component-scan base-package="com.blogspot.diegopacheco"/> </beans>

Código 6.9 spring-annotation-beans.xml xml de configuração

Diego Pacheco – http://diego-pacheco.blogspot.com

11


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.annotations.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestaInjecaoAnotacoes { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring-annotation*.xml"); Autor a =(Autor)ac.getBean("autor"); System.out.println(a); } }

Código 6.10 TestaInjecaoAnotacoes.java – Clase de testes Você já deve ter reparado que esta abordagem tem todas as vantagens que descrevi no início deste capítulo, mas ainda tem mais uma desvantagem, nós não conseguimos definir vários beans com a mesma classe e com dados diferentes, neste sentido a abordagem de xml é mais vantajosa. Nós poderiamos deixar alguma injeção obrigatória e caso você não faça isso o spring irá levantar uma exception. Para isso vamos utilizar a anotação @Required, confira o código abaixo modificado do exemplo anterior. package com.blogspot.diegopacheco.springframework25.annotations.spring; import org.springframework.beans.factory.annotation.Required; import org.springframework.stereotype.Component; @Component public class Livro { private String isbn; private String titulo; public Livro() { isbn = "10ergregKL2"; titulo = "O código de Da vince"; } public String getIsbn() { return isbn; } @Required public void setIsbn(String isbn) { this.isbn = isbn; } public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo;

Diego Pacheco – http://diego-pacheco.blogspot.com

12


Spring Framework – Framework para desenvolvimento de aplicações java

} @Override public String toString() { return "[livro={isbn: " + isbn + ",titulo: " + titulo + "}]"; } }

Código 6.11 Livro.java – Anotado Perceba que a classe livro agora tem a anotação @Required no setter da propriedade ISBN, logo, se você não injetar um valor, o spring vai levantar uma exception e o contexto não irá subir. O spring permite mesclarar informações de anotações com XML, confira a configuração abaixo para injeção deste atributo obrigatório. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context2.5.xsd"> <context:annotation-config/> <context:component-scan base-package="com.blogspot.diegopacheco"/> <bean id="livro" class="com.blogspot.diegopacheco.springframework25.annotations.spring.Liv ro" > <property name="isbn" value="1000ISBN12" /> </bean>

</beans>

Código 6.12 spring-annotation-beans.xml xml de configuração

Diego Pacheco – http://diego-pacheco.blogspot.com

13


Spring Framework – Framework para desenvolvimento de aplicações java

Testes Unitários com TestNG

Nos capitulos anteriores você aprendeu a integrar o Spring Framework com o Junit, bem como utilizar as suas facilidades para testes unitários. Neste capítulo você vai ver como utilizar o TestNG através de anotações tanto do TestNG como do próprio Spring Framework. Desenvolver aplicações utilizando os bons modelos de design como programação para interfaces, baixo acoplamento e alta coesão, extensibilidade, di, ioc, através do Spring framework nos trazem um benefício muito importante, um código que é testável. O Spring prove injeção para testes de forma diferenciada da injeção para a sua aplicação utiliza este recurso. Vamos ver como utilizar alguns recursos de testes unitários do Spring com anotações, confira o código abaixo: package com.blogspot.diegopacheco.springframework25.testng; public interface Calculadora { public void dividir(Double va, Double vb, ResultadoCallback callback); }

Código 6.13 Calculadora.java – Interface de Contrato da Calculadora package com.blogspot.diegopacheco.springframework25.testng; public interface ResultadoCallback { public void processar(Double resultado); }

Código 6.14 ResultadoCallback.java – Interface de Callback

Diego Pacheco – http://diego-pacheco.blogspot.com

14


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.testng; import org.springframework.stereotype.Service; @Service public class CalculadoraAsync implements Calculadora { @Override public void dividir(final Double va, final Double vb, final ResultadoCallback callback) { new Runnable(){ public void run() { callback.processar(va/vb); } }.run(); } }

Código 6.15 ResultadoCallback.java – Interface de Callback A classe acima implementa a interface de calculadora de modo assíncrono, ela processa a divisão em outra thread. Quando o calculo é finalizado quem infocou o serviço é notificado via um callback. Vamos ver como testar este código integrando o Spring ao TestNG, para isso confira a classe abaixo de testes. package com.blogspot.diegopacheco.springframework25.testng; import org.springframework.stereotype.Service; @Service public class CalculadoraAsync implements Calculadora { @Override public void dividir(final Double va, final Double vb, final ResultadoCallback callback) { new Runnable(){ public void run() { callback.processar(va/vb); } }.run(); } }

Código 6.16 ResultadoCallback.java – Interface de Callback

Diego Pacheco – http://diego-pacheco.blogspot.com

15


Spring Framework – Framework para desenvolvimento de aplicações java

Agora que já temos o que testar vamos criar um teste unitário com o TestNG, confira o código de testes abaixo: package com.blogspot.diegopacheco.springframework25.testng; import junit.framework.Assert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.Test; @Test(groups={"curso-spring"}) @ContextConfiguration(locations={"/spring-test-beans.xml"}) public class CalculadoraTest extends AbstractTestNGSpringContextTests { private Calculadora calc; @Test public void testInjecaoSpring(){ Assert.assertNotNull("A calculadora não foi injetada.",calc); } @Autowired @Test(enabled=false) public void setCalc(Calculadora calc) { this.calc = calc; } }

Código 6.17 ResultadoCallback.java – Interface de Callback Neste código precisamos focar nos seguintes pontos: • Extensão da classe AbstractTestNGSpringContextTests: Esta é a classe abstrata do Spring que prove integração e facilidades para trabalhar com o testNG. • @Test: Indica que a classe é testável via TestNG e que a classe pertence ao grupo de testes chamado curso-spring. • @Test no método testInjecaoSpring indica que o método deve ser testado. • @Autowired e @Test(enable=false): Indica que o Spring deve injetar a instância do bean calculadora, como estamos indo por tipo ele vai injetar a calculadora assíncrona chamada CalculadoraAsync. • Assert.assertNotNull neste ponto estamos utilizando asserções para testar se o código está fazendo o que deveria, caso isso não seja válido, uma exception será levantada com a mensagem passada no primeiro argumento do método. Diego Pacheco – http://diego-pacheco.blogspot.com

16


Spring Framework – Framework para desenvolvimento de aplicações java

• @ContextConfiguration serve para indicar ao spring onde estão os xmls de configuração para o contexto de testes que ele irá montar. Agora vamos ver outros recursos do Spring com o TestNG, podemos utilizar diversas anotações que nos provem diversas facilidades como: • @Timed: Especifica um tempo em milisegundos para o método executar, caso demore mais do que o tempo especificado uma exception é levantada e o teste irá falhar. • @Rollback: Especifica se o método irá dar um rollback na transação ou se será permitido que a transação efetue um commit no banco de dados. • @ExpectedException: Especifica que uma exception do tipo especificado deve ser levantada, este recurso é ideal para testar cenários de erros. • @IfProfileValue: Este recurso permite a execução do método de testes apartir de um profile condicional. Este profile é definido por uma variavél de ambiente e um valor, caso a váriavel do sistema tenha o valor que você informou o método será executado.

Diego Pacheco – http://diego-pacheco.blogspot.com

17


Spring Framework – Framework para desenvolvimento de aplicações java

Integração com JSF

Java Server Faces vem se tornando muito popular no desenvolvimento de aplicações Web com Java pela quantidade componentes prontos de riqueza visual dos seus componentes. O Spring Framework 2.5 possui integração com o Java Server Faces 2.5, vamos ver como configurar esta integração em uma aplicação Web utilizando o padrão MVC.

Figura 6.1 – Padrão MVC O JSF é uma das implementações de um framework MVC, o propósito de um framework MVC é separar a camada de apresentação(view) da camada de negócio(model), é comun utilizar na parte do model EJB ou Spring Framework, o JSF se encarrega das camadas de view e controller. Este padrão é largamente utilizado em desenvolvimento de aplicação Web com Java, JSF é uma das implementações, mas existem outras como o Strus, Webwork, Stripes, etc. Para integrar o Contexto do Spring ao JSF é necessário registrar o listener do Spring no web.xml para que o contexto do Spring suba automaticamente quando a aplicação inicia e bem como registrar o org.springframework.web.jsf.el.SpringBeanFacesELResolver como ElResolver do JSF. Depois disso você pode utilizar o Spring com o JSF normalmente. Então vamos ver essas configurações na prática e bem como uma aplicação com todas as camadas típicas da arquitetura MVC usando Spring Framework, JSF, Jboss RichFaces e Annotations.

Diego Pacheco – http://diego-pacheco.blogspot.com

18


Spring Framework – Framework para desenvolvimento de aplicações java

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- Configurações da Aplicação --> <display-name>Adendo-Curso-Spring-JSF</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <session-config> <session-timeout>30</session-timeout> </session-config> <!-- Configurações do Spring Framework --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-beans-core.xml</param-value> </context-param> <listener> <listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass> </listener> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener</lis tener-class> </listener>

<!-- Configurações para utilização de JSF --> <context-param> <param-name>javax.faces.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config-beans.xml,/WEB-INF/facesconfig-nav.xml</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servletclass> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.faces</url-pattern> </servlet-mapping> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.jsp</param-value>

Diego Pacheco – http://diego-pacheco.blogspot.com

19


Spring Framework – Framework para desenvolvimento de aplicações java

</context-param> <listener> <listenerclass>com.sun.faces.config.ConfigureListener</listener-class> </listener> <context-param> <param-name>com.sun.faces.verifyObjects</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>com.sun.faces.validateXml</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param>

<!-- Configurações do JBoss Richfaces --> <filter> <display-name>RichFaces Filter</display-name> <filter-name>richfaces</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>richfaces</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <context-param> <param-name>org.richfaces.SKIN</param-name> <param-value>laguna</param-value> </context-param> </web-app>

Código 6.18 web.xml – Configurações da Aplicação Como você pode perceber, as configurações de Spring, JSF e Jboss RichFaces estão separadas por comentários, vamos ver o significado de cada configuração uma a uma, começando com as configurações do Spring Framework. O parametro para Servlets chamado contextConfigLocation serve para indicar aonde estão as configurações em xml do spring para serem utilizadas na startup do contexto. Na sequencia o listener do spring chamado org.springframework.web.context.ContextLoaderListener é responsável por subir o contexto do spring nesta aplicação web.

Diego Pacheco – http://diego-pacheco.blogspot.com

20


Spring Framework – Framework para desenvolvimento de aplicações java

Por fim é utilizado o org.springframework.web.context.request.RequestContextListener para trabalhar a tecnologia de MVC do spring com JSF, no nosso caso vamos utiliza-lo apenas para ver o que está trafegando nos cabeçalhos do http. Depois vem as configurações do JSF e do Jboss RichFaces que são padrão o único ponto mais importante a prestar atenção aqui é o parâmetro de servlet chamado javax.faces.CONFIG_FILES que serve para informar onde estão os arquivos de configuração do JSF. No final do arquivo estamos registrando o filter do Jboss Richfaces, bem como a utilização de um Skin plugável chamado laguna. Vamos ver as configurações do JSF agora, ou seja, os faces-config. <?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" version="1.2"> <navigation-rule> <navigation-case> <from-outcome>sucesso</from-outcome> <to-view-id>/Pages/lista-cao-pego.jsp</to-view-id> <redirect /> </navigation-case> </navigation-rule> </faces-config>

Código 6.19 faces-config-nav.xml– Arquivo com Regras de Navegação Neste arquivo estão as configurações de navegação dos beans. Vamos ver o arquivo de configuração dos managed beans e do spring com o ElResolver. <?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" version="1.2"> <application> <elresolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</elresolver> </application>

<managed-bean> <managed-bean-name>carrocinhaBean</managed-bean-name>

Diego Pacheco – http://diego-pacheco.blogspot.com

21


Spring Framework – Framework para desenvolvimento de aplicações java

<managed-beanclass>com.blogspot.diegopacheco.springframework25.jsf.mb.CarrocinhaBean</ managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>carrocinhaService</property-name> <propertyclass>com.blogspot.diegopacheco.springframework25.jsf.service.CarrocinhaS ervice</property-class> <value>#{caveiraoService}</value> </managed-property> </managed-bean> </faces-config>

Código 6.20 faces-config-beans.xml– Arquivo com os MB do JSF O ponto mais importante deste arquivo é a configuração do SpringBeanFacesElResolver, depois está sendo declarado o carrocinhaBean que é o controller desta aplicação. Vamos ver as classes da aplicação neste momento então. package com.blogspot.diegopacheco.springframework25.jsf.pojo; import java.io.Serializable; public class Cachorro implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String nome; private String raca; public Cachorro() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getRaca() { return raca; } public void setRaca(String raca) { this.raca = raca; } @Override

Diego Pacheco – http://diego-pacheco.blogspot.com

22


Spring Framework – Framework para desenvolvimento de aplicações java

public String toString() { return "id: " + id + ",Nome: " + nome + ", Raça: " + raca; } }

Código 6.21 Cachorro.java– Pojo que representa um Cachorro Este é um simples pojo com métodos getters e setters com o construtor vazio e que implementa Serializable. Vamos ao componente responsável por persistir o objeto. package com.blogspot.diegopacheco.springframework25.jsf.dao; import java.io.Serializable; import org.springframework.stereotype.Repository; import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro; @Repository(value="carrocinhaDao") public class CarrocinhaDao { public Serializable capturar(Cachorro c){ System.out.println("Cachorro: " + c + " persistido com sucesso "); return c; } }

Código 6.22 CarrocinhaDao.java– Repository de Carrocinha Este repositório é resposável por acessar os dados referente ao serviço de carrocinha, também é conhecido como o pattern DAO. Este código não acessa o banco de dados, mas você poderia utilizar JPA ou Hibernate sem problema nenhum. package com.blogspot.diegopacheco.springframework25.jsf.service; import java.io.Serializable; import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro; public interface CarrocinhaService { public Serializable catar(Cachorro c); } }

Código 6.23 CarrocinhaService.java– Serviço de Carrocinha Esta é a interface de contrato do serviço de carrocinha, os cachorros devem ter cuidado agora, senão, vão se dar mal. Vamos ver uma implementação deste serviço:

Diego Pacheco – http://diego-pacheco.blogspot.com

23


Spring Framework – Framework para desenvolvimento de aplicações java

package com.blogspot.diegopacheco.springframework25.jsf.service; import java.io.Serializable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.blogspot.diegopacheco.springframework25.jsf.dao.CarrocinhaDao; import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro; @Service(value="caveiraoService") public class CaveiraoCarrocinhaServiceImpl implements CarrocinhaService { @Autowired private CarrocinhaDao dao; public Serializable catar(Cachorro c) { Serializable ser = dao.capturar(c); System.out.println("Cão: "+ ser + " não tem vez!"); return ser; } public void setDao(CarrocinhaDao dao) { this.dao = dao; } }

Código 6.24 CaveiraoCarrocinhaServiceImpl– Serviço de Carrocinha Impl Este é o serviço implementado para carrocinha. Como você pode perceber, ele está utilizando um dao que é injetado via anotação @Autowired. Este serviço retorna a instância do Cachorro que foi capturado. package com.blogspot.diegopacheco.springframework25.jsf.mb; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import com.blogspot.diegopacheco.springframework25.jsf.pojo.Cachorro; import com.blogspot.diegopacheco.springframework25.jsf.service.CarrocinhaService ; @Controller(value="carrocinhaBean") public class CarrocinhaBean { private private private private

Integer id; String nome; String raca; String resultado;

@Resource private CarrocinhaService carrocinhaService;

Diego Pacheco – http://diego-pacheco.blogspot.com

24


Spring Framework – Framework para desenvolvimento de aplicações java

public CarrocinhaBean() {} public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getRaca() { return raca; } public void setRaca(String raca) { this.raca = raca; } public String getResultado() { return resultado; } public void setResultado(String resultado) { this.resultado = resultado; } public CarrocinhaService getCarrocinhaService() { return carrocinhaService; } public void setCarrocinhaService(CarrocinhaService carrocinhaService) { this.carrocinhaService = carrocinhaService; }

public String catar(){ Cachorro c = new Cachorro(); c.setId(1); c.setNome(nome); c.setRaca(raca); Cachorro caoCatadado = (Cachorro)carrocinhaService.catar(c); resultado = "Cão: " + caoCatadado.getNome() + " - Catado! "; return "sucesso"; } }

Código 6.25 CarrocinhaBean– Controller da Aplicação Esta classe é um controller, você pode reparar que ela tem as mesmas propriedades que o pojo Cachorro tem, isto serve para separarmos objetos que trafegam na tela com os objetos que trafegam nos serviços e nas regras de negócio.

Diego Pacheco – http://diego-pacheco.blogspot.com

25


Spring Framework – Framework para desenvolvimento de aplicações java

Uma instância de CarrocinhaService é injetada via a anotação @Resource e o método catar tem a resposabilidade de criar o pojo Cachorro e invocar o serviço de Carrocinha e repassar o resultado, caso dê tudo certo, o resultado é “sucesso” que irá cair nas regras de navegação do JSF e levar a execução a outra página.Vamos ver o código das páginas desta aplicação; <%@ page contentType="text/html; charset=Cp1252"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%> <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Cp1252" /> <title></title> </head> <body> <f:view> <h:form> <rich:panel> <h:panelGrid> <h:outputLabel value="Capturar um Cão sem Sorte" /> <h:panelGroup> <h:outputLabel id="nome" value="Nome do Cão:" /> <h:inputText id="nomeTxt" value="#{carrocinhaBean.nome}" /> </h:panelGroup> <h:panelGroup> <h:outputLabel id="raca" value="Raça do Cão :" /> <h:inputText id="racaTxt" value="#{carrocinhaBean.raca}" /> </h:panelGroup> <h:panelGroup> <a4j:commandButton value="Catar o Cão agora!" action="#{carrocinhaBean.catar}" /> </h:panelGroup> </h:panelGrid> </rich:panel> </h:form> </f:view> </body> </html>

Código 6.26 main.jsp– Página de captura de cães

Diego Pacheco – http://diego-pacheco.blogspot.com

26


Spring Framework – Framework para desenvolvimento de aplicações java

<%@ page contentType="text/html; charset=Cp1252"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%> <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Cp1252" /> <title></title> </head> <body> <f:view> <h:form> <rich:panel> <h:panelGrid> <h:outputLabel value="Cão que se deu mal" /> <h:panelGroup> <h:outputLabel id="result" value="Cão Capturado:" /> <h:outputLabel id="resuktValue" value="#{carrocinhaBean.resultado}" /> </h:panelGroup> </h:panelGrid> </rich:panel> </h:form> </f:view> </body> </html>

Código 6.27 lista-cao-pego.jsp.jsp– Página que mostra o cão pego

Diego Pacheco – http://diego-pacheco.blogspot.com

27


Spring Framework – Framework para desenvolvimento de aplicações java

Ao rodar esta aplicação você irá precisar das seguintes dependências em termos de jars:

Figura 6.2 Dependências de Jars A versão do Spring Framework utilizada foi a versão 2.5.6.SCE e a aplicação roda no Jetty 6.1.3, você pode obter a aplicação completa nos fontes que acompanham apostila.

Diego Pacheco – http://diego-pacheco.blogspot.com

28


Spring Framework – Framework para desenvolvimento de aplicações java

Expondo os seus beans via JMX JMX é uma solução Java para monitoramento e parametrização do comportamento da aplicações Java em tempo de runtime. Esta solução é muito utilizada para o gerenciamento de aplicações Java. Para utilizar este recurso você não precisar implementar e nem estender nenhum recurso do Spring Framework. Vamos a um exemplo prático.

package com.blogspot.diegopacheco.springframework25.jmx; public interface DateService { public String getDate(); }

Figura 6.28 DateService.java contrato do serviço de dadas

Como você pode perceber esta é um interface como outa qualquer, sem nada de mais, apenas existe um método chamado getDate que deve retornar uma String. Vamos ver a sua implementação.

package com.blogspot.diegopacheco.springframework25.jmx; import java.util.Date; public class DateServiceImpl implements DateService{ public String getDate() { return new Date().toString(); } }

Figura 6.29 DateServiceImpl.java – Serviço de Datas

A implementação é bem simples, apenas retorna o método toString() de um objeto Date recente, que irá ter a data e hora atual do sistema. Vamos registrar este bean como um bean do Spring, utilizando xml como de costume.

Diego Pacheco – http://diego-pacheco.blogspot.com

29


Spring Framework – Framework para desenvolvimento de aplicações java

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/springcontext-2.5.xsd">

<bean id="dateService" class="com.blogspot.diegopacheco.springframework25.jmx.DateServiceImpl" /> </beans>

Figura 6.30 DateServiceImpl.java – Serviço de Datas

Declaração do bean no contexto do Spring como de costume é feito e sem nada de novo, agora é possível apenas expor este bean via JMX, sem esforço de programação, basta utilizar a configuração a baixo. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context2.5.xsd"> <context:annotation-config /> <context:component-scan base-package="com.blogspot" /> <bean id="dateService" class="com.blogspot.diegopacheco.springframework25.jmx.DateServiceI mpl" /> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> <property name="beans"> <map> <entry key="bean:name=DateService" valueref="dateService" /> </map> </property> </bean> </beans>

Figura 6.30 DateServiceImpl.java – Serviço de Datas Diego Pacheco – http://diego-pacheco.blogspot.com

30


Spring Framework – Framework para desenvolvimento de aplicações java

O Código acima utiliza o recurso do spring chamado de org.springframework.jmx.export.MbeanExporter que é resposável por expor os beans via JMX, ele recebe um map com os beans que vão ser expostos, logo é possível expor mais de um bean. Existem outras estratégias para exposição de beans com JMX, esta é a mais simples, caso queira saber mais, consulte a documentação oficial do spring framework. Você pode acessar este MBean via um utilitário que vem junto com o JDK do java o Jconsole, você achar o utilitário na pasta bin do seu JDK, para utilizar o JMX é comun ter que habilitar este recurso no seu container, cada container tem uma configuração diferente, recomendo verificar a documentação do container que você esteja utilizando para maiores detalhes.

Diego Pacheco – http://diego-pacheco.blogspot.com

31


Spring Framework – Framework para desenvolvimento de aplicações java

Exercícios 1) Crie um beans Pessoa, AnimalDeEstimacao e Casa e injete um no outro usando as anotaçõess do Spring. Você deve criar o método verifica animais, que deve retornar um Map contendo o nome do animal e o tipo dele, exe.: mamífero, réptil, etc... 2) Adicione a anotação de ciclo de vida @PostConstruct e @PreDestroy no bean de Pessoa e faça log do início e fim da aplicação. 3) Exponha o bean pessoa com o método listarAnimais() que deve retornar uma Sring com todos os animais da pessoa separados por “ ; ” 4) Crie um teste unitário com TestNG para validar se o objeto através do método verifica animais está correto. 5) Crie uma aplicação web com JSF que você possa cadastrar um animal preferido a pessoa e depois tenha uma página que mostre o animal cadastrado, não é necessário acessar banco de dados.

Diego Pacheco – http://diego-pacheco.blogspot.com

32


Spring Framework – Framework para desenvolvimento de aplicações java

Espaço para anotações

Diego Pacheco – http://diego-pacheco.blogspot.com

33


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.