construindo um crud com flex e java
TRANSCRIPT
Construindo um CRUD com Flex e Java
– Parte I
Depois de um pedido (exigência, rs) especial de um dos meus alunos do Curso Flex que
está sendo realizado no Sicoob Confederação, resolvi criar esse post. Ele tem o objetivo
de desenvolver uma simples aplicação usando Flex e Java. Nele será abordado o
desenvolvimento de um CRUD (Create, Retrieve, Update e Delete), para não ficar
muito longo decidi dividi-lo em duas partes, na primeira irei mostrar como desenvolver
o back-end e na segunda o desenvolvimento do front-end e a integração com Java.
Antes de começar, assegure-se de possuir as ferramentas abaixo:
- BlazeDS – Baixar versão personalizada
- Flex Builder 3 instalado sobre o Eclipse Europa – Baixar FB3 e Baixar EE
- MySQL 5 ou superior – Baixar
- JSDK 5.0 ou superior – Baixar
- Tomcat 6.0 – Baixar
Caso não tenha alguma das ferramentas, faça o download usando o link ao lado da
ferramenta. Agora, que você está com tudo pronto vamos começar.
CRIANDO O PROJETO Para criar o seu projeto siga os passos das telas abaixo.
Selecione o menu File > New > Other e depois selecione Flex Project.
Dê o nome do seu projeto de CrudFlex e em Server tecnology selecione a opção J2EE,
pois utilizaremos Java como tecnologia no back-end.
Em Target runtime você deve selecione o botão New e configurar o servidor que iremos
trabalhar, nesse caso o Tomcat. Mais, abaixo em Flex WAR file, clique em Browser para
selecionar o WAR do BlazeDS que você fez o download. Depois basta clicar em Finish
para concluir a criação do projeto. Devendo ficar assim:
AJUSTANDO O PROJETO Devido a um bug na ferramenta é necessário que façamos um pequeno ajusto no projeto
assim que ele criado, esse ajuste permitirá que executamos a nossa aplicação no browser
sem problema. Para isso, clique com o botão direito sobre o projeto e selecione
Properties e na tela que se abre escolha a opção Flex Server, a tela exibida deverá ser
igual a essa.
Na opção Contex root, deveria ser exibido /CrudFlex, mas em vez disso aparece
WebContent, faça o ajuste como mostra a tela.
CRIANDO O BANCO DE DADOS Nosso projeto terá apenas uma tabela que se chamará contato e ficará em um banco de
dados chamado minha_agenda, veja a estrutura da tabela abaixo.
Agora vamos começar a criação de sua estrutura. Para facilitar o trabalho resolvi criar
um script para a criação do banco e da tabela, copie o código e salve-o na unidade C:\
do Windows e dê o nome de script.sql. Usaremos o CLI (Command Line Interface) do
MySQL para criá-lo. Acesse o shell do Windows, digite mysql -u root -p e tecle enter,
logo em seguida ele irá solicitar que você entre com a senha do servidor. Depois digite
na linha de comando co CLI “source c:/script.sql” e tecle enter, se tudo correr bem você
terá seu banco e sua tabelas criada.
Source code
1. CREATE DATABASE minha_agenda; 2. 3. USE minha_agenda; 4. 5. CREATE TABLE contato ( 6. id INT AUTO_INCREMENT, 7. nome VARCHAR(20) NOT NULL, 8. telefone VARCHAR(20) NOT NULL, 9. celular VARCHAR(20), 10. email VARCHAR(150) NOT NULL,
11. PRIMARY KEY(id)
12.
13. );
Com o banco criado estamos pronto para desenvolver as classes Java.
ENTENDENDO A ARQUITETURA
Nossa aplicação será organizada em duas grandes partes, o front-end e o back-end. O
back-end por sua vez é dividido em duas camadas, são elas Serviço e DAO. Veja a
imagem abaixo.
A camada de Serviço trata-se da única camada que será exposta ao Flex, ou seja, ela
será o ponto de comunicação entre o Flex e o Java, já, a DAO ela é responsável pela
persistência e recuperação das informações do banco de dados.
CRIANDO AS CAMADAS JAVA Para começa a codificar é necessários que definamos uma padrão para a organização
das nossas classes, eu adotei o seguinte, teremos um pacote default chamado de
br.com.waelson e dentro dele teremos dao, servico e dominio, que respectivamente
teremos a classe de persistência, a classe que irá expor o serviço ao Flex e a classe que
representa a nossa tabela do banco de dados, devendo ficar assim:
Agora vamos começa a codificar, começaremos pela classe de domínio, segue abaixo o
código.
Contato.java
1. package br.com.waelson.dominio; 2. 3. public class Contato { 4. 5. private Long id; 6. private String nome; 7. private String telefone; 8. private String celular; 9. private String email; 10. public Long getId() {
11. return id;
12. }
13. public void setId(Long id) {
14. if(id > 0){
15. this.id = id;
16. }
17. }
18. public String getNome() {
19. return nome;
20. }
21. public void setNome(String nome) {
22. this.nome = nome;
23. }
24. public String getTelefone() {
25. return telefone;
26. }
27. public void setTelefone(String telefone) {
28. this.telefone = telefone;
29. }
30. public String getCelular() {
31. return celular;
32. }
33. public void setCelular(String celular) {
34. this.celular = celular;
35. }
36. public String getEmail() {
37. return email;
38. }
39. public void setEmail(String email) {
40. this.email = email;
41. }
42.
43. }
Agora vem a classe de persistência.
ContatoDao.java
1. package br.com.waelson.dao; 2. 3. import java.sql.Connection; 4. import java.sql.DriverManager; 5. import java.sql.PreparedStatement; 6. import java.sql.ResultSet; 7. import java.sql.SQLException; 8. import java.util.ArrayList; 9. import java.util.List; 10.
11. import br.com.waelson.dominio.Contato;
12.
13. /**
14. * Classe responsável pela persistência da
entidade Contato
15. * @author Waelson Negreiros
16. *
17. */
18. public class ContatoDao {
19.
20. /**
21. * Inclui um novo registro no banco de dados
22. * @param contato Contato
23. */
24. public void incluir(Contato contato){
25. Connection conn = null;
26. PreparedStatement ps = null;
27. try{
28. conn = getConnection();
29. ps = conn.prepareStatement("INSERT
INTO contato (nome, telefone, celular, email) VALUES
(?,?,?,?)");
30. ps.setString(1, contato.getNome());
31. ps.setString(2,
contato.getTelefone());
32. ps.setString(3,
contato.getCelular());
33. ps.setString(4, contato.getEmail());
34. ps.execute();
35. }catch(SQLException ex){
36. throw new RuntimeException(ex);
37. }finally{
38. try{
39. if(ps != null) ps.close();
40. if(conn != null) conn.close();
41. }catch(SQLException ex){}
42. }
43. }
44.
45. /**
46. * Altera um registro no banco de dados
47. * @param contato Contato
48. */
49. public void alterar(Contato contato){
50. Connection conn = null;
51. PreparedStatement ps = null;
52. try{
53. conn = getConnection();
54. ps = conn.prepareStatement("UPDATE
contato SET nome = ?, telefone = ?, celular = ?, email
= ? WHERE id = ?");
55. ps.setString(1, contato.getNome());
56. ps.setString(2,
contato.getTelefone());
57. ps.setString(3,
contato.getCelular());
58. ps.setString(4, contato.getEmail());
59. ps.setLong(5, contato.getId());
60. ps.execute();
61. }catch(SQLException ex){
62. throw new RuntimeException(ex);
63. }finally{
64. try{
65. if(ps != null) ps.close();
66. if(conn != null) conn.close();
67. }catch(SQLException ex){}
68. }
69. }
70.
71. /**
72. * Exclui um contato. Mas, antes verifica se
ele ainda existe
73. * @param id Long
74. */
75. public void excluir(Long id){
76. Connection conn = null;
77. PreparedStatement ps = null;
78. try{
79. conn = getConnection();
80. ps = conn.prepareStatement("DELETE
FROM contato WHERE id = ?");
81. ps.setLong(1, id);
82. ps.execute();
83. }catch(SQLException ex){
84. throw new RuntimeException(ex);
85. }finally{
86. try{
87. if(ps != null) ps.close();
88. if(conn != null) conn.close();
89. }catch(SQLException ex){}
90. }
91. }
92.
93. /**
94. * Recuperar um contato por ID
95. * @param id Long
96. * @return Contato
97. */
98. public Contato buscarPorId(Long id){
99. Contato retorno = null;
100. Connection conn = null;
101. PreparedStatement ps = null;
102. ResultSet rs = null;
103. try{
104. conn = getConnection();
105. ps = conn.prepareStatement("SELECT *
FROM contato WHERE id = ?");
106. ps.setLong(1, id);
107. rs = ps.executeQuery();
108. if(rs.next()){
109. retorno =
converterResultSetParaContato(rs);
110. }
111. }catch(SQLException ex){
112. throw new RuntimeException(ex);
113. }finally{
114. try{
115. if(rs != null) rs.close();
116. if(ps != null) ps.close();
117. if(conn != null) conn.close();
118. }catch(SQLException ex){}
119. }
120. return retorno;
121. }
122.
123. /**
124. * Recupera todos os contatos
125. * @return {@literal List<Contato>}
126. */
127. public List<Contato> buscarTodos(){
128. List<Contato> retorno = new
ArrayList<Contato>();
129. Connection conn = null;
130. PreparedStatement ps = null;
131. ResultSet rs = null;
132. try{
133. conn = getConnection();
134. ps = conn.prepareStatement("SELECT *
FROM contato ORDER BY nome");
135. rs = ps.executeQuery();
136. Contato contato;
137. while(rs.next()){
138. contato =
converterResultSetParaContato(rs);
139. retorno.add(contato);
140. }
141. }catch(SQLException ex){
142. throw new RuntimeException(ex);
143. }finally{
144. try{
145. if(rs != null) rs.close();
146. if(ps != null) ps.close();
147. if(conn != null) conn.close();
148. }catch(SQLException ex){}
149. }
150. return retorno;
151. }
152.
153. /**
154. * Converte um objeto ResultSet em um objeto
Contato
155. * @param rs ResultSet
156. * @return Contato
157. * @throws SQLException
158. */
159. private Contato
converterResultSetParaContato(ResultSet rs) throws
SQLException{
160. Contato contato = new Contato();
161. contato.setId(rs.getLong("id"));
162. contato.setNome(rs.getString("nome"));
163.
contato.setTelefone(rs.getString("telefone"));
164.
contato.setCelular(rs.getString("celular"));
165. contato.setEmail(rs.getString("email"));
166. return contato;
167. }
168.
169. /**
170. * Recupera um conexão física com o banco de
dados
171. * @return Connection
172. */
173. private Connection getConnection(){
174. Connection conn = null;
175. try{
176.
Class.forName("com.mysql.jdbc.Driver");
177. conn =
DriverManager.getConnection("jdbc:mysql://localhost:33
06/contato", "root", "root");
178. }catch(Exception ex){
179. throw new RuntimeException(ex);
180. }
181. return conn;
182. }
183.
184. }
E para finalizar a classe de serviço.
ContatoServico.java
1. package br.com.waelson.servico; 2. 3. import java.util.List; 4. 5. import br.com.waelson.dao.ContatoDao; 6. import br.com.waelson.dominio.Contato; 7. 8. /** 9. * Classe que expõem seus serviços ao Flex 10. * @author Waelson Negreiros
11. *
12. */
13. public class ContatoServico {
14.
15. private ContatoDao dao = new ContatoDao();
16.
17. /**
18. * Inclui ou alterar um contato
19. * @param contato Contato
20. */
21. public void salvar(Contato contato){
22. if(contato.getId() != null){
23. dao.alterar(contato);
24. }else{
25. dao.incluir(contato);
26. }
27. }
28.
29. /**
30. * Exclui um contato. Mas, antes verifica se
ele ainda existe
31. * @param id Long
32. */
33. public void excluir(Long id){
34. Contato contato = dao.buscarPorId(id);
35. if(contato != null){
36. dao.excluir(id);
37. }
38. }
39.
40. /**
41. * Recuperar um contato por ID
42. * @param id Long
43. * @return Contato
44. */
45. public Contato buscarPorId(Long id){
46. return dao.buscarPorId(id);
47. }
48.
49. /**
50. * Recupera todos os contatos
51. * @return {@literal List<Contato>}
52. */
53. public List<Contato> buscarTodos(){
54. return dao.buscarTodos();
55. }
56.
57. }
No final a organização do seu projeto deve está assim:
CONFIGURANDO O REMOTING-CONFIG.XML
Para fechar esse post iremos configurar o arquivo remoting-config.xml, essa arquivo é
responsável pela exposição de um conjunto de classes ao Flex. Esse arquivo está
localizado /CrudFlex > WebContext > WEB-INF > flex. Sua configuração é bastante
simples, é necessário incluir apenas uma tag destination. Todo destination precisa ter
um identificado único que pode ser definido através do atributo id, o desenvolvedor é
livre para definí-lo e por fim temos as tags filhas properties e source e é dentro do corpo
da tag source que iremos definir o fully qualified da classe que desejamos expor. Seu
remoting-config.xml deve ficar assim:
remoting-config.xml
1. <?xml version="1.0" encoding="UTF-8"?> 2. <service id="remoting-service" 3. class="flex.messaging.services.RemotingService"> 4. 5. <adapters> 6. <adapter-definition id="java-object" 7.
class="flex.messaging.services.remoting.adapters.JavaA
dapter"
8. default="true"/> 9. </adapters> 10.
11. <default-channels>
12. <channel ref="my-amf"/>
13. </default-channels>
14.
15. <destination id="contatoServico">
16. <properties>
17.
<source>br.com.waelson.servico.ContatoServico</source>
18. </properties>
19. </destination>
20.
21. </service>
CONCLUSÃO
Nesse post vimos todo o processo de criação do back-end da aplicação de maneira
simples, clara e direta. Utilizamos o BlazeDS como framework de integração com o
Java e o quanto é fácil sua configuração. Breve estarei disponibilizando a segunda parte,
não deixe de visitar o site.