Olá Pessoal!
Primeiro lugar, quero agradecer a todos pelo feedback do post anterior, isto é motivante e me dá ânimo em concluir este, e outros que virão.
Hoje o foco deste artigo é que você termine ele sabendo:
Configurar os Beans do Spring através de annotations;
Integrar o esquema de Beans do Spring com os services do Flex através de uma Factory;
Configurar o Spring para usar o Hibernate para abstrair nosso banco de dados;
Para isso vamos a uma breve introdução a estes poderosos frameworks
Breve Introdução ao Spring
Como não sou fã de ficar re-escrevendo a roda, vou tentar dar a você leigo em Spring, um caminho para estudar.
Primeiro de tudo, leia este artigo feito pelo Phillip Calçado (Shoes)
apostila-spring.pdf
Valeu Ebertom pela hospedagem! =)Uma Introdução ao que o SpringFramework pode oferecer:
http://blog.fragmental.com.br/2005/08/31/spring-em-acao/
http://www.ime.usp.br/~reverbel/SMA/Slides/seminarios/spring.pdf
http://imasters.uol.com.br/artigo/4497/java/spring_framework_introducao/Outros Tutoriais
http://www.javafree.org/content/view.jf?idContent=46http://www.devmedia.com.br/articles/viewcomp.asp?comp=6627
http://www.devmedia.com.br/articles/viewcomp.asp?comp=6628
http://www.devmedia.com.br/articles/viewcomp.asp?comp=6653Spring Annotations
http://blog.interface21.com/main/2006/11/28/a-java-configuration-option-for-spring/
http://weblogs.java.net/blog/seemarich/archive/2007/11/annotation_base_1.htmlExemplos de códigos
http://paulojeronimo.com/arquivos/tutoriais/tutorial-spring-framework.zip
http://www.java2s.com/Code/Java/Spring/CatalogSpring.htmDocumentação
The Spring Framework – Reference Documentation
Bom acredito que se você que está afim de conhecer o SpringFramewok, com esses Link’s já é possível entender quase tudo o que ele pode oferecer a sua arquitetura. Lembrando que não é recomendável seguir com este artigo, sem antes entender como funciona IoC, AOP, DAO, com o SpringFramework.
*Nota A abordagem aqui é sobre o SpringFramework, (Framework de Negócio) e não sobre o SpringMVC, uma vez que o Flex pode se trocar objetos através do protocolo AMF3, é totalmente dispensável o uso de Frameworks MVC’s.
Breve Introdução ao Hibernate
Como eu já disse, uma vez que já existe um bom conteúdo sobre Hibernate na Internet, não há a necessidade de re-escrever, por isso vou lhe dar a você leigo em Hibernate uma sequência de Link que irá te ajudar a entender este poderoso Framework.
Uma Introdução ao que o Hibernate pode oferecer:
http://www.students.ic.unicamp.br/~ra007271/docs/white-papers/hibernate-uma_introducao_dirigida.pdf
http://www.guj.com.br/java.tutorial.artigo.125.1.guj
http://www.jeebrasil.com.br/mostrar/4
http://www.devmedia.com.br/articles/viewcomp.asp?comp=4149Outros Tutoriais
http://simundi.blogspot.com/2007/09/criar-uma-aplicao-com-hibernate.html
http://www.hibernate.org/hib_docs/v3/reference/en/html/queryhql.html
http://www.hibernate.org/hib_docs/tools/reference/en/html/plugins.html
http://www.guj.com.br/posts/list/7249.javaPacotão de PDF’s
http://br.groups.yahoo.com/group/java-br/files/Hibernate/Exemplos de código
http://www.java2s.com/Code/Java/Hibernate/CatalogHibernate.htmDocumentação
http://www.hibernate.org/hib_docs/v3/reference/en/html/
Ok, partindo do princípio que você já entendeu como funciona o Hibernate, e o Spring, vamos ao código! +)
Requerimentos:
SpringFramework 2.5 ou superior;
*Vamos baixar o Spring com as dependências, isto é neste arquivo conterá todas as libs que nós podemos por ventura usar com o Spring, como por exemplo as libs do hibernate.MySql 5.x Instalado;
*Eu estarei usando o pacote apache friends – xamppConhecimentos básicos sobre MySql;
Plugin Eclipse SpringIDE;
*OpcionalPlugin Eclipse Hibernate Tools 3.2.x;
*Opcional
Instale os plugin’s estes opcionais na verdade este artigo não fará uso deles, mas pensando no futuro seria interessante fazer uso deles.
Após isso, abra seu projeto no Eclipse que nós tinhamos criado anteriormente, O JavaFlex.
Vamos adicionar as seguintes libs ao projeto na pasta JavaFlex\WebContent\WEB-INF\lib:
*A maioria das libs podem ser encontrada no arquivo compactado que você baixou do Spring. Lembrando também que o modelo de estilo de projeto criado no Eclipse, Dynamic Web Project, já adiciona automaticamente ao Classpath do projeto ao você colar as libs nesta pasta.
Como nós já tinhamos modelado um caso de uso chamado Cargo, vamos agora criar um banco de dados para o nosso pequeno sistema.
Abra seu MySql, e execute este script sql que criará a base de dados chamada JavaFlex, e também a tabela JAVAFLEX_CARGO;
-
–
-
– Banco de Dados: `javaflex`
-
–
-
CREATE DATABASE `javaflex` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
-
USE `javaflex`;
-
-
–
-
– Estrutura da tabela `javaflex_cargo`
-
–
-
-
CREATE TABLE `javaflex_cargo` (
-
`ID_CARGO` int(10) unsigned NOT NULL auto_increment,
-
`DS_CARGO` varchar(50) collate utf8_unicode_ci NOT NULL,
-
PRIMARY KEY (`ID_CARGO`)
-
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
Entendendo os Pacotes, e configurando a persistência
Com o banco de dados criado, vamos mapear a tabela no banco, com o nosso Entity Cargo, para isso, crie um package chamado:
com.digows.artigos.JavaFlex.model.repository.hibernate.hbm
Neste package irá conter todos os nossos mapeamentos em xml, alguns preferem fazer uso de annotations, só que pessoalmente não gosto de acoplar códigos de annotations em meus beans de negócio, prefiro delegar a função Mapeamento a arquivos xml’s.
Neste mesmo package crie um arquivo chamado Cargo.hbm.xml, e adicione o seguinte conteúdo:
Cargo.hbm.xml
-
<?xml version=“1.0″ encoding=“UTF-8″?>
-
<!DOCTYPE hibernate-mapping PUBLIC
-
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
-
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-
<hibernate-mapping>
-
<class name=“com.digows.artigos.JavaFlex.model.entity.Cargo”
-
table=“javaflex_cargo”>
-
-
<id name=“idCargo” column=“ID_CARGO” type=“long”>
-
<generator class=“native” />
-
</id>
-
-
<property name=“dsCargo” column=“DS_CARGO” type=“string”
-
not-null=“true” length=“50″ />
-
</class>
-
</hibernate-mapping>
Perceba que estamos mapeando nosso entity Cargo que foi criado no post anterior com a tabela JAVAFLEX_CARGO criada recém.
com.digows.artigos.JavaFlex.model.repository.hibernate
Este package irá conter classes que implementam o Pattern DAO usando o Hibernate. Métodos de CRUD e querys em geral usando o Hibernate deverão estar neste pacote estes separados por casos de uso.
Neste mesmo package, vamos criar um DAO usando o hibernate para o nosso entity cargo, para isso, crie uma classe java chamada CargoHibernateDao, e adicione o seguinte conteúdo:
CargoHibernateDao.java
-
package com.digows.artigos.JavaFlex.model.repository.hibernate;
-
-
import java.util.List;
-
-
import org.hibernate.SessionFactory;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.beans.factory.annotation.Qualifier;
-
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
-
import org.springframework.stereotype.Repository;
-
-
import com.digows.artigos.JavaFlex.model.entity.Cargo;
-
import com.digows.artigos.JavaFlex.model.repository.CargoRepository;
-
-
public class CargoHibernateDao extends HibernateDaoSupport
-
implements CargoRepository {
-
-
@Autowired
-
public CargoHibernateDao(@Qualifier(“sessionFactory”)SessionFactory factory) {
-
super.setSessionFactory(factory);
-
}
-
-
public Cargo save(Cargo p_cargo) {
-
getHibernateTemplate().saveOrUpdate(p_cargo);
-
return p_cargo;// ID POPULADA
-
}
-
-
public void remove(Cargo p_cargo) {
-
getHibernateTemplate().delete(p_cargo);
-
}
-
-
long id = p_cargo.getIdCargo();
-
p_cargo = (Cargo) getHibernateTemplate().get(Cargo.class, p_cargo.getIdCargo());
-
-
if (p_cargo == null)
-
throw new Exception(“O Cargo com a ID: “+id+” do(a) “+Cargo.class.getSimpleName()+” não foi encontrada.”);
-
return p_cargo;
-
}
-
-
@SuppressWarnings(“unchecked”)
-
public List<cargo> getList() {
-
return (List<cargo>) getHibernateTemplate().loadAll(Cargo.class);
-
}
-
}
Perceba que esta implementa apenas métodos de acesso ao banco de dados usando o hibernate. Nesta classe faço uso de annotations para que o container Spring faça o wire dos beans.
@Repository
A anotação @Repository é mais um estereótipo que foi introduzido no Spring 2.0. Esta anotação é usada para indicar que uma classe funciona como um repositório (Veremos mais adiante o que é este pattern), esta anotação faz com que o Spring envie Exceptions da persistência a camada de serviço, vindas de DataAccessException, isto é deixa tranparênte a camada de serviço o tipo de repository que foi implementado.
@Autowired
A anotação @Autowired é usada para a injeção de depêndencia da sessionFactory do hibernate.
@SuppressWarnings
Faço uso da anotação @SuppressWarnings, apenas para o compilador não gerar um Warning no cast da List, uma vez que o Hibernate foi projetado sem o uso de Generics, ao usar Generics o compilador devolve um Warning.
Perceba que esta classe implementa uma interface, está interface implementa o pattern Repository, este padrão já causou muita polêmica em forums Java como o GUJ por exemplo, recomendo a leitura deste post para entender o padrão:
http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/
com.digows.artigos.JavaFlex.model.repository
Este package irá conter interfaces do tipo repository que dará comportamentos a DAO’s sejam elas implementadas por DAO’s Hibernate, DAO’s JDBC, DAO’s iBatis e etc…
Neste mesmo pacote, crie uma interface chamada CargoRepository com o seguinte conteúdo:
CargoRepository.java
-
package com.digows.artigos.JavaFlex.model.repository;
-
-
import java.util.List;
-
import com.digows.artigos.JavaFlex.model.entity.Cargo;
-
-
public interface CargoRepository {
-
-
void remove(Cargo p_cargo);
-
Cargo save(Cargo p_cargo);
-
List<cargo> getList();
-
}
Ok! nossa persistência já foi programada, vamos agora alterar a classe CargoService que foi criado no post anterior, para que se comporte como uma classe de serviço gerenciada pelo container Spring.
Para isso, altere o nome da classe CargoService que está no package com.digows.artigos.JavaFlex.model.service para CargoServiceImpl e adicione este conteúdo:
CargoServiceImpl.java
-
package com.digows.artigos.JavaFlex.model.service;
-
-
import java.util.List;
-
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Service;
-
import org.springframework.transaction.annotation.Propagation;
-
import org.springframework.transaction.annotation.Transactional;
-
-
import com.digows.artigos.JavaFlex.model.entity.Cargo;
-
import com.digows.artigos.JavaFlex.model.repository.CargoRepository;
-
-
@Service(value=“cargoService”)
-
public class CargoServiceImpl implements CargoService {
-
-
private CargoRepository cargoRepository;
-
-
@Autowired
-
public void setCargoRepository(CargoRepository cargoRepository) {
-
this.cargoRepository = cargoRepository;
-
}
-
-
try {
-
this.cargoRepository.save(p_cargo);
-
return p_cargo;
-
}
-
}
-
-
try {
-
this.cargoRepository.remove(p_cargo);
-
}
-
}
-
-
try {
-
return this.cargoRepository.findById(p_cargo);
-
}
-
}
-
-
try {
-
return this.cargoRepository.getList();
-
}
-
}
-
}
Perceba que é uma classe de serviço simples, esta apenas tem a funcão de coodernar os Entities de domínio e fazer a persistência atráves de um repository.
@Service
A anotação @Service é uma forma especializada da anotação @Component. É conveniente anotar as classes da camada de serviço com @Service para facilitar o processamento por ferramentas ou antecipar qualquer futuro serviço de capacidades específicas que podem ser adicionados a esta anotação.
@Transactional
Como o próprio nome diz, é um estereótipo que delega ao container que esta classe de serviço deve ser transicional.
@Autowired
A anotação @Autowired é usada para a injeção de depêndencia que será feita pelo container de uma implementação da interface CargoService.
Nessa camada de serviço faço uso também do Pattern DIP (Dependency Inversion Principle), por isso esta classe é uma implementação (CasoDeUsoServiceImpl) de uma interface de serviço, no caso a CargoService.
Para isso no pacote com.digows.artigos.JavaFlex.model.service, crie uma interface com o nome de CargoService, com este conteúdo:
CargoService.java
-
package com.digows.artigos.JavaFlex.model.service;
-
-
import java.util.List;
-
-
import com.digows.artigos.JavaFlex.model.entity.Cargo;
-
-
public interface CargoService {
-
-
}
Ok, com estes passos realizados, já concluímos a implementação do nosso model. A estrutura final deverá ser esta:
Configurando o SpringFramework com o Hibernate e o Blaze.
No post anterior, configuramos o Tomcat para utilizar apenas o BlazeDS, agora precisamos adicionar mais as configurações do SpringFramework.
Para isso abra o arquivo JavaFlex\WebContent\WEB-INF\web.xml e altere deixando com este conteúdo:
web.xml
-
<?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″>
-
-
<display-name>JavaFlex</display-name>
-
-
<!–
-
///////////////////////////////
-
Configuracao Spring 2.5
-
///////////////////////////////
-
–>
-
<context-param>
-
<param-name>contextConfigLocation</param-name>
-
<param-value>
-
/WEB-INF/applicationContext.xml
-
</param-value>
-
</context-param>
-
-
<listener>
-
<listener-class>
-
org.springframework.web.context.ContextLoaderListener
-
</listener-class>
-
</listener>
-
<listener>
-
<listener-class>
-
org.springframework.web.context.request.RequestContextListener
-
</listener-class>
-
</listener>
-
-
<!–
-
///////////////////////////////
-
Configuracao do BlazeDS
-
///////////////////////////////
-
–>
-
<context-param>
-
<param-name>flex.class.path</param-name>
-
<param-value>/WEB-INF/flex/hotfixes</param-value>
-
</context-param>
-
-
<!– MessageBroker Servlet –>
-
<servlet>
-
<servlet-name>MessageBrokerServlet</servlet-name>
-
<display-name>MessageBrokerServlet</display-name>
-
<servlet-class>
-
flex.messaging.MessageBrokerServlet
-
</servlet-class>
-
<init-param>
-
<param-name>services.configuration.file</param-name>
-
<param-value>/WEB-INF/flex/services-config.xml</param-value>
-
</init-param>
-
<init-param>
-
<param-name>flex.write.path</param-name>
-
<param-value>/WEB-INF/flex</param-value>
-
</init-param>
-
<load-on-startup>1</load-on-startup>
-
</servlet>
-
<servlet-mapping>
-
<servlet-name>MessageBrokerServlet</servlet-name>
-
<url-pattern>/messagebroker/*</url-pattern>
-
</servlet-mapping>
-
-
-
<welcome-file-list>
-
<welcome-file>index.html</welcome-file>
-
<welcome-file>index.htm</welcome-file>
-
<welcome-file>index.jsp</welcome-file>
-
</welcome-file-list>
-
-
</web-app>
Perceba na configuração do Spring, ele faz referência a um arquivo chamado applicationContext.xml, este arquivo é o que contém as configurações do Spring em si, então no mesmo diretório que se econtra o web.xml, crie um arquivo com o nome de applicationContext.xml e coloque este conteúdo:
applicationContext.xml
-
<?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:p=“http://www.springframework.org/schema/p”
-
xmlns:context=“http://www.springframework.org/schema/context”
-
xmlns:jee=“http://www.springframework.org/schema/jee”
-
xmlns:tx=“http://www.springframework.org/schema/tx”
-
xsi:schemaLocation=“
-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
-
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd”>
-
<!–
-
//////////////////////////////////////
-
Integração do Spring com o Hibernate
-
//////////////////////////////////////
-
–>
-
-
<!–
-
Carregamento do Arquivo de Configuracoes do JDBC
-
–>
-
<context:property-placeholder location=“classpath:jdbc.properties” />
-
-
<!–
-
Configuracao do DataSource
-
–>
-
<bean id=“dataSource”
-
class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>
-
<property name=“driverClassName”>
-
<value>${jdbc.driverClassName}</value>
-
</property>
-
<property name=“url”>
-
<value>${jdbc.url}</value>
-
</property>
-
<property name=“username”>
-
<value>${jdbc.username}</value>
-
</property>
-
<property name=“password”>
-
<value>${jdbc.password}</value>
-
</property>
-
</bean>
-
-
<!–
-
Hibernate SessionFactory
-
–>
-
<bean id=“sessionFactory”
-
class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
-
-
<property name=“dataSource”>
-
<ref local=“dataSource” />
-
</property>
-
-
<!– Carrega todos os HBM’s –>
-
<property name=“mappingDirectoryLocations”>
-
<list>
-
<value>
-
classpath:com/digows/artigos/JavaFlex/model/repository/hibernate/hbm/
-
</value>
-
</list>
-
</property>
-
-
<!– Configuracoes do Hibernate –>
-
<property name=“hibernateProperties”>
-
<props>
-
<prop key=“hibernate.dialect”>
-
org.hibernate.dialect.MySQLInnoDBDialect
-
</prop>
-
<prop key=“hibernate.show_sql”>true</prop>
-
<!–
-
Atualizar o Banco de dados de acordo com os arquivos de mapeamentos.
-
<prop key="hibernate.hbm2ddl.auto">update</prop>
-
–>
-
</props>
-
</property>
-
-
<property name=“eventListeners”>
-
<map>
-
<entry key=“merge”>
-
<bean
-
class=“org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener” />
-
</entry>
-
</map>
-
</property>
-
</bean>
-
-
<!–
-
Transaction Manager
-
–>
-
<bean id=“transactionManager”
-
class=“org.springframework.orm.hibernate3.HibernateTransactionManager”>
-
<property name=“sessionFactory”>
-
<ref local=“sessionFactory” />
-
</property>
-
</bean>
-
-
<!– Habilita os Services para serem transicionais via a Annotation @Transactional –>
-
<tx:annotation-driven transaction-manager=“transactionManager” />
-
-
<!– ============================== AOP DEFINITIONS ================================ –>
-
-
-
<!– ========================= BUSINESS OBJECT DEFINITIONS ========================= –>
-
<!–
-
Activates various annotations to be detected in bean classes:
-
Spring’s @Required and @Autowired, as well as JSR 250′s @Resource.
-
–>
-
<context:annotation-config />
-
-
<!– Carrega os Beans de Servico –>
-
<context:component-scan
-
base-package=“com.digows.artigos.JavaFlex.model.service” />
-
-
<!– Carrega os Beans DAO Hibernate –>
-
<context:component-scan
-
base-package=“com.digows.artigos.JavaFlex.model.repository.hibernate” />
-
</beans>
Perceba que as configurações do banco de dados usado, delego a um arquivo .properties, também vou precisar configurar o log4j para a impressão de log’s. Por estética o bacana seria gerar um novo source-path que contenha tais arquivos properties.
Crie um pasta na raiz do projeto com o nome de resources,
De um botão direito sobre o projeto e clique em properties;
Em Java Build Path, clique no botão AddFolder;
Selecione a pasta resources, clique em ok, e marque a opção Allow output folders for source folders, e ok.
Dentro do package resources, crie um arquivo chamado jdbc.properties, e adicione o seguinte conteúdo:
jdbc.properties
-
# Properties file com as configuracoes do JDBC.
-
# Aplicado pelo PropertyPlaceholderConfigurer do Spring
-
-
jdbc.driverClassName=com.mysql.jdbc.Driver
-
jdbc.url=jdbc:mysql://localhost:3306/javaflex
-
jdbc.username=root
-
jdbc.password=
-
-
#Properties que determina o dialeto do Banco de Dados.
-
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
e outro arquivo chamado log4j.properties com este conteúdo:
log4j.properties
-
### direct log messages to stdout ###
-
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-
log4j.appender.stdout.Target=System.out
-
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L – %m%n
-
-
# set root logger level to debug and its only appender to mtf
-
log4j.rootLogger=INFO,development
-
-
# only for development purposes
-
log4j.appender.development=org.apache.log4j.ConsoleAppender
-
log4j.appender.development.layout=org.apache.log4j.PatternLayout
-
log4j.appender.development.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p [%t] (%F:%L) – %m%n
-
-
log4j.logger.noModule=FATAL
-
log4j.logger.org.springframework=WARN
-
-
# Log JDBC bind parameter runtime arguments
-
log4j.logger.org.hibernate.type=DEBUG
Uma outra modificação é necessária, está a mais importante, pois delega ao Blaze, que existe uma factory de beans criada pelo Spring.
Essa factory deve ser implementada, porém já existe pronto na internet para uso, esta pode ser encontrada aqui:
Spring and Flex Integration Factory Class
Baixe ela, e coloque por exemplo neste pacote:
com.digows.artigos.JavaFlex.controller
*O nome controller ficou sugestivo aqui, uma vez que está factory não tem comportamentos de um controller, porém como o Flex não faz uso do controller para controlar as actions que também não existe, achei bacana preservar o package colocando a factory de beans do Spring que será usada pelo Blaze neste pacote. Se alguém tiver uma idéia melhor de onde colocar a classe, estou aceitando opniões.
Vamos então configurar o Blaze. Abra o arquivo JavaFlex\WebContent\WEB-INF\flex\services-config.xml e altere deixando com este conteúdo:
services-config.xml
-
<?xml version=“1.0″ encoding=“UTF-8″?>
-
<services-config>
-
<services>
-
<service-include file-path=“remoting-config.xml” />
-
</services>
-
-
<!– Spring factory registration –>
-
<factories>
-
<factory id=“spring”
-
class=“com.digows.artigos.JavaFlex.controller.SpringFactory”/>
-
</factories>
-
-
<channels>
-
<channel-definition id=“channel-amf”
-
class=“mx.messaging.channels.AMFChannel”>
-
<endpoint
-
url=“http://{server.name}:{server.port}/{context.root}/messagebroker/amf”
-
class=“flex.messaging.endpoints.AMFEndpoint” />
-
<properties>
-
<polling-enabled>false</polling-enabled>
-
</properties>
-
</channel-definition>
-
</channels>
-
-
<logging>
-
<target class=“flex.messaging.log.ConsoleTarget”
-
level=“Error”>
-
<properties>
-
<prefix>[BlazeDS]</prefix>
-
<includeDate>true</includeDate>
-
<includeTime>false</includeTime>
-
<includeLevel>true</includeLevel>
-
<includeCategory>true</includeCategory>
-
</properties>
-
<filters>
-
<pattern>Endpoint.*</pattern>
-
<pattern>Service.*</pattern>
-
<pattern>Message.*</pattern>
-
<pattern>DataService.*</pattern>
-
<pattern>Configuration</pattern>
-
</filters>
-
</target>
-
</logging>
-
-
<system>
-
<redeploy>
-
<enabled>true</enabled>
-
<watch-interval>20</watch-interval>
-
<watch-file>
-
{context.root}/WEB-INF/flex/services-config.xml
-
</watch-file>
-
<watch-file>
-
{context.root}/WEB-INF/flex/remoting-config.xml
-
</watch-file>
-
<touch-file>{context.root}/WEB-INF/web.xml</touch-file>
-
</redeploy>
-
</system>
-
</services-config>
Perceba que mapeio o local da Factory. Agora é preciso atualizar nosso servico cargoService dentro do arquivo JavaFlex\WebContent\WEB-INF\flex\remoting-config.xml. Então abra e edite deixando com este conteúdo:
remoting-config.xml
-
<?xml version=“1.0″ encoding=“UTF-8″?>
-
<service id=“remoting-service”
-
class=“flex.messaging.services.RemotingService”>
-
-
<adapters>
-
<adapter-definition id=“java-object”
-
class=“flex.messaging.services.remoting.adapters.JavaAdapter”
-
default=“true” />
-
</adapters>
-
-
<default-channels>
-
<channel ref=“channel-amf” />
-
</default-channels>
-
-
<destination id=“cargoService”>
-
<properties>
-
<factory>spring</factory>
-
<source>cargoService</source>
-
</properties>
-
</destination>
-
</service>
Aqui só é importante observar que a tag <source /> mapeia o nome do bean do tipo serviço que foi delegado na annotation, no nosso caso na classe CargoServiceImpl perceba a annotation @Service(value=”cargoService”) e também a tag <factory /> que faz referência a configuração no arquivo services-config.xml
Se tudo foi efetuado corretamente, ao você dar um botão direito no projeto e ir em Run As -> Run On Server, ao clicar em salvar no fomulário de cadastro criado no post anterior, o seu objeto cargo vindo do Flex já será persistido! observe o console para isso.
Eu alterei o arquivo com\digows\artigos\JavaFlex\view\screen\CargoForm.mxml para que possa usar todos os métodos do CRUD Cargo. Segue como ficou:
CargoForm.mxml
-
<?xml version=“1.0″ encoding=“utf-8″?>
-
<mx:TitleWindow xmlns:mx=“http://www.adobe.com/2006/mxml”
-
layout=“vertical” width=“488″ height=“384″ creationComplete=“getList()”>
-
-
<mx:Form width=“100%” height=“100%” defaultButton=“{btSalvar}”>
-
<mx:FormHeading label=“Gerenciamento de Cargos” width=“100%”/>
-
<mx:FormItem label=“ID:” width=“127″>
-
<mx:TextInput width=“100%” id=“txtIdCargo”
-
text=“{Cargo(dgCargo.selectedItem).idCargo}” editable=“false” enabled=“false”/>
-
</mx:FormItem>
-
<mx:FormItem label=“Cargo:” width=“345″>
-
<mx:TextInput width=“100%” id=“txtDsCargo”
-
text=“{Cargo(dgCargo.selectedItem).dsCargo}”/>
-
</mx:FormItem>
-
<mx
ataGrid id=“dgCargo” width=“100%” height=“100%” dataProvider=“{listCargos}”> -
<mx:columns>
-
<mx
ataGridColumn headerText=“ID” dataField=“idCargo” width=“30″/> -
<mx
ataGridColumn headerText=“Cargo” dataField=“dsCargo”/> -
</mx:columns>
-
</mx
ataGrid> -
</mx:Form>
-
-
<mx:ControlBar horizontalAlign=“center”>
-
<mx:Button label=“Novo” click=“setDefault()”/>
-
<mx:Button label=“Salvar” id=“btSalvar” click=“save()”
-
textAlign=“center”/>
-
<mx:Button label=“Excluir” click=“remove()”/>
-
</mx:ControlBar>
-
-
<mx:RemoteObject id=“cargoService” showBusyCursor=“true”
-
fault=“onFault(event)” destination=“cargoService”>
-
<mx:method name=“save” result=“onResultSave(event)” fault=“onFault(event)”/>
-
<mx:method name=“remove” result=“onResultRemove(event)” fault=“onFault(event)”/>
-
<mx:method name=“getList” result=“onResultGetList(event)” fault=“onFault(event)”/>
-
</mx:RemoteObject>
-
-
<mx:Script>
-
<![CDATA[
-
import mx.collections.ArrayCollection;
-
import com.digows.artigos.JavaFlex.view.entity.Cargo;
-
import mx.rpc.events.ResultEvent;
-
import mx.rpc.events.FaultEvent;
-
import mx.controls.Alert;
-
-
[Bindable]
-
private var listCargos:ArrayCollection;
-
-
private var cargo:Cargo;
-
-
public function save():void
-
{
-
this.cargo = new Cargo();
-
this.cargo.idCargo = new Number(txtIdCargo.text);
-
this.cargo.dsCargo = txtDsCargo.text;
-
-
//Chama o metodo Save do servico "cargoService"
-
cargoService.save(cargo);
-
}
-
-
//Função que será executada após a conclusão do método save
-
public function onResultSave(event:ResultEvent):void
-
{
-
status = "Salvo com Sucesso! Ultima ID: "+Cargo(event.result).idCargo;
-
getList();
-
}
-
-
public function remove():void
-
{
-
if (dgCargo.selectedItem != null) {
-
cargo = dgCargo.selectedItem as Cargo;
-
cargoService.remove(cargo);
-
} else {
-
Alert.show("Selecione um Item na DataGrid");
-
}
-
}
-
-
//Função que será executada após a conclusão do método remove
-
public function onResultRemove(event:ResultEvent):void
-
{
-
status = "Excluido com Sucesso!";
-
getList();
-
}
-
-
public function getList():void
-
{
-
cargoService.getList();
-
}
-
-
//Função que será executada após a conclusão do método getList
-
public function onResultGetList(event:ResultEvent):void
-
{
-
listCargos = event.result as ArrayCollection;
-
}
-
-
public function setDefault():void
-
{
-
txtIdCargo.text = "";
-
txtDsCargo.text = "";
-
}
-
-
//Ocorreu uma falha ao chamar algum servico servico.
-
public function onFault(event:FaultEvent):void
-
{
-
Alert.show(event.fault.message);
-
}
-
]]>
-
</mx:Script>
-
</mx:TitleWindow>
Bom pessoal, acredito que com estes 2 artigos consegui atingir o objetivo de dar a comunidade Java uma proposta de interface produtiva e poderosa, e também a comunidade Flex uma proposta de uma arquitetura com Flex e Java, utilizando o Blaze Data Services.
Faça mais testes, veja que o desenvolvimento é muito rápido! muito melhor do que se matar com tags html e funções em JavaScript.
Fora que você pode desenvolver com o Flex aplicando os conceitos de Orientação a Objetos, a começar pela tranferência de dados, no Flex chega Objetos! e não textos (XML, WebServices, Request/Response e afins).
Neste artigo não fiz uso de patterns para o desenvolvimento das telas em Flex, porém nos próximos artigos irei abordar detalhadamente como você pode arquiteturar seu código Flex visando ganhar manutenabilidade, escalabilidade, e reusabilidade.
Tópico no Forum que contém detalhes sobre o download. Flex 2.0 e Flex 3.0
[Link]
Obrigado a todos e um Beijão especial para minha querida Liz!
=*****
Abraços
\o/







