(ainda não pus a legenda das imagens )
Requisitos :
- Netbeans 7.2
- spring-3.2.0.M2 -- link direto
- estar com o banco mysql springlessons, e a tabela contato criada. ver lição 4,5, 6 ou 7
- Struts 1.3.10 (utilizarei a dist que já vem com o NB)
- Ter lido :
Posts Anteriores :
JSNBTut - Lesson 01 - introdução ao Spring
JSNBTut - Lesson 02 - introdução ao gerenciamento de dependências no SpringJSNBTut - Lesson 03 - acessando banco de dados Mysql com beans e injeção de dependências
JSNBTut - Lesson 04 - outro jeito rápido de utilizar o Spring e Mysql sem utilizar Arquivos XML.
JSNBTut - Lesson 05 - comparação entre as implementações e introdução ao Swing. Jtable + DefaultTableModel e implementação de uma TableModel, ...
Obrigatório:
JSNBTut - Lesson 06 - implementando um CRUD ao exemplo , que é o projeto que continuaremos neste post.
- Finalizando o CRUD completo em Java utilizando Swing e Spring
- Implementamos um validador com org.springframework.validation.Validator
- Implementamos um Tema
- Vimos como importar /exportar arquivos XML usando XStream
- Aprendemos a usar Anotações
- Implementamos um SplashScreen
- Aprendemos a distribuir nossa aplicação e customizar o build do projeto no build.xml
Lembrando a estrutura da nossa tabela do mysql
![]() |
| Figura 01 - Tabela Contato |
CREATE TABLE IF NOT EXISTS `springlessons`.`contato` ( `id` INT NOT NULL AUTO_INCREMENT , `nome` VARCHAR(45) NULL , `telefone` VARCHAR(45) NULL , PRIMARY KEY (`id`) ) ENGINE = InnoDB
OBS : as vezes o nome do meu servidor Mysql pode aparece como ns1 (quando estou no escritório) ou localhost (quando estou no lap). Relax, o banco é o mesmo, ok ?
Este é o 8º da série , o objetivo deste post é implementar o programa que terminamos na lição 07 na web. Para isso utilizaremos o framework Struts, e depois integraremos com o Spring.
Algumas info antes de criar o projeto web. Quando se trata de JSP, já existem alguns padrões de implementação e organização dos arquivos :
1) Vendo a organização do projeto (arquivos e pastas)
I ) exemplo criado com o o Maven :Comando : mvn archetype:generate -DgroupId=com.myapp -DartifactId=meuscontatos-webapp -DarchetypeArtifactId=maven-archetype-webapp
![]() |
| Figura 02 - Gerando um projeto baseado no Maven |
![]() |
| Figura 03 - Arquivos gerado pelo mvn |
II) o Struts fornece um exemplo também p/ iniciar um projeto, após descompactar a lib do struts veja a pasta apps tem um arquivo struts-blank-1.3.10.war (que é um zip. descompacte esse arquivo)
![]() |
| Figura 04 - Exemplos do struts 1 |
![]() |
| Figura 05 - Arquivos do exemplo |
Então vimos que uma webApp contém a seguinte estrutura (com variações de implementação):
Projeto
--src
--conf : arquivo Manifest
--java : packages e classes Java e arquivos .properties
--web ouWebContent
---META-INF
--context.xml
---WEB-INF
--Arquivos.xml ; normalmente aqui vão o web.xml. o beans.xml, struts-config.xml e TLDs
--Arquivos JSP e html, images, js, css, etc..
então vamos criar a webapp no NB:
2) Criando o Projeto Web
![]() |
| Figura 06 - Novo Projeto |
![]() |
| Figura 07 - Nome do projeto |
![]() |
| Figura 08 - Defina Servidor Tomcat ou GlassFish |
![]() |
| Figura 09 - Adicionando o Struts 1.3.10 que vem com o NB |
![]() |
| Figura 10 - Projeto com a inclusão do Struts |
![]() |
| Figura 11 - Teste o projeto |
![]() |
| Figura 12 - Teste pelo Run Projet |
![]() |
| Figura 13 - Teste pelo Run Projet pasando a URL na mão |
![]() |
| Figura 14 - Output do NB |
Nossa aplicação contém arquivos XML que definem o comportamento dos servlets e algumas configurações.
I) Ao carregar a app,
O arquivo struts-config.xml informou uma action de nome Welcome apontado /Welcome.do
Veja o nosso arquivo struts-config.xml sem os comentários :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
</form-beans>
<global-exceptions>
</global-exceptions>
<global-forwards>
<forward name="welcome" path="/Welcome.do"/>
</global-forwards>
<action-mappings>
<action path="/Welcome" forward="/welcomeStruts.jsp"/>
</action-mappings>
<controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
<message-resources parameter="com/myapp/struts/ApplicationResource"/>
<!-- ========================= Tiles plugin ===============================-->
<!-- ..... Paths found in Tiles definitions are relative to the main context.
-->
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
</plug-in>
<!-- ========================= Validator plugin ================================= -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>
II) e de onde vem esse .do no fim da solicitação http ?
R: da configuração do arquivo web.xml, observe a inicial :
Atenção :
- Na linha <load-on-startup>2</load-on-startup> dentro da tag <servlet>
- No conjunto <jsp-config> que adicionei as TLDs junto com o projeto. Pode-se usar a url do site, mas e se a WebApp estiver num servidor que não acessa a Internet ?
- E o .do está sendo "resolvido" pela tag <servlet-mapping> com um pattern .do .
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
III) é chamado o arquivo welcomeStruts.jsp :
![]() |
| Figura 15 - arquivo welcomeStruts.jsp |
Observe as linhas : <beans:message> a chave (key) welcome.Propriedade
IV) Essa definições estão no arquivo ApplicationResource.properties dentro do package com.app.struts
![]() |
| Figura 16 - Arquivo properties |
observe as linhas finais :
welcome.title=Struts Application
welcome.heading=Struts Applications in Netbeans!
welcome.message=It's easy to create Struts applications with NetBeans.
3) Implementando nossas classes ao projeto:
Vamos manipular a tabela contato do banco, certo ? Precisamos de :
0) adicionar o driver do Mysql ao projeto
1) um modelo Contato
2) uma interface DAO
3) uma classe que implemente a interface DAO
4) uma interface de Serviço
5) uma classe que implemente a interface de Serviço
6) das classes p/ atender os actions que serão mapeados no arquivo struts-config.xml, que extendem a classe org.apache.struts.action.Action,
7) definir as actions e mappings no arquivo struts-config.xml
8) criar a view (interface para o usuário), definindo um form
9) criar uma página que mostre os erros quando acontecer
9) criar uma página que mostre os erros quando acontecer
OBS: ainda não vou utilizar o spring, depois implementaremos:
Mãos a obra..
defina 3 variávess:
int id;
String nome;
String telefone , e escolha refactor>> encapsulate Fields
CODE
CODE
CODE
CODE
CODE
dentro de um novo package ...action
- CreateContatoAction.java
- ContatoForm.java
- RedirectContatoAction.java
I) CreateContatoAction.java
CODE
II) ContatoForm.java
CODE
III) RedirectContatoAction.java
CODE
0) Adicione a Lib do Mysql:
![]() |
| Figura 17 - Adicione a lib do Mysql |
1) Criando o modelo :
![]() |
| Figura 18 - Criando o modelo Contato |
defina 3 variávess:
int id;
String nome;
String telefone , e escolha refactor>> encapsulate Fields
![]() |
| Figura 19 - Encapsulando a classe Contato |
CODE
package com.myapp.model;
public class Contato {
private int id;
private String nome;
private String telefone;
public Contato() {
this.id=0;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
}
2) Criando uma interface DAO
![]() |
| Figura 20 - Interface DAO |
CODE
package com.myapp.dao;
import com.myapp.model.Contato;
import java.util.List;
public interface ContatoDao {
public void create(Contato contato);
public List<Contato> findAll();
}
3) Criando uma classe que implemente a interface DAO
![]() |
| Figura 21- Criando a implementação da interface |
![]() |
| Figura 22 - nome da Classe de implementação |
CODE
package com.myapp.dao;
import com.myapp.model.Contato;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ContatoDaoImpl implements ContatoDao {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception ex) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
throw new ExceptionInInitializerError(ex);
}
}
private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://ns1/springlessons", "springlessons", "DHADdSXcDF29WGXy");
}
@Override
public void create(Contato contato) {
Connection Con = null;
PreparedStatement pstm = null;
try {
Con = getConnection();
String sql = "INSERT INTO `springlessons`.`contato`"
+ "(`nome`,`telefone`)"
+ " VALUES (?,?)";
pstm = Con.prepareStatement(sql);
pstm.setString(1, contato.getNome());
pstm.setString(2, contato.getTelefone());
pstm.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
pstm.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
try {
Con.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
}
}
@Override
public List<Contato> findAll() {
Connection Con = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try {
Con = getConnection();
String sql = "SELECT `contato`.`id`,`contato`.`nome`,`contato`.`telefone`"
+ " FROM `springlessons`.`contato`";
pstm = Con.prepareStatement(sql);
List<Contato> contatos = new ArrayList<Contato>();
rs = pstm.executeQuery(sql);
while (rs.next()) {
Contato contato = new Contato();
contato.setId(rs.getInt("id"));
contato.setNome(rs.getString("nome"));
contato.setTelefone(rs.getString("telefone"));
contatos.add(contato);
}
return contatos;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
pstm.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
try {
Con.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
}
}
}
4) Criando uma interface de Serviço
![]() |
| Figura 23 - criando a interface de Serviço |
CODE
package com.myapp.service;
import com.myapp.model.Contato;
import java.util.List;
public interface ContatoService {
public void create(Contato contato);
public List<Contato> findAll();
}
5) Criando uma classe que implemente a interface de Serviço
![]() |
| Figura 24 - Implemente a interface |
![]() |
| Figura 25 - nome da implementação |
CODE
package com.myapp.service;
import com.myapp.dao.ContatoDao;
import com.myapp.dao.ContatoDaoImpl;
import com.myapp.model.Contato;
import java.util.List;
public class ContatoServiceImpl implements ContatoService {
private ContatoDao dao = new ContatoDaoImpl();
@Override
public void create(Contato contato) {
dao.create(contato);
}
@Override
public List<Contato> findAll() {
return dao.findAll();
}
}
6) Criando as classes p/ atender os actions que serão mapeados no arquivo struts-config.xml, que extendem a classe org.apache.struts.action.Action,
dentro de um novo package ...action
- CreateContatoAction.java
- ContatoForm.java
- RedirectContatoAction.java
I) CreateContatoAction.java
![]() |
| Figura 26 - Criando a Action |
CODE
package com.myapp.action;
import com.myapp.model.Contato;
import com.myapp.service.ContatoService;
import com.myapp.service.ContatoServiceImpl;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class CreateContatoAction extends Action {
private ContatoService userService = new ContatoServiceImpl();
public void setContatoService(ContatoService userService) {
this.userService = userService;
}
@Override
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// return super.execute(mapping, form, request, response);
ContatoForm contatoForm = (ContatoForm) form;
Contato contato = new Contato();
BeanUtils.copyProperties(contato, contatoForm);
userService.create(contato);
return mapping.findForward("list");
}
}
II) ContatoForm.java
![]() |
| Figura 27 - mande o NB criar essa classe no package action |
CODE
package com.myapp.action;
import org.apache.struts.action.ActionForm;
public class ContatoForm extends ActionForm {
private String nome;
private String telefone;
public ContatoForm() {
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
}
III) RedirectContatoAction.java
![]() |
| Figura 28 - Adicionando a action de redirect |
CODE
package com.myapp.action;
import com.myapp.service.ContatoService;
import com.myapp.service.ContatoServiceImpl;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class RedirectContatoAction extends Action {
private ContatoService contatoService = new ContatoServiceImpl();
public void setContatoService(ContatoService contatoService) {
this.contatoService = contatoService;
}
@Override
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// return super.execute(mapping, form, request, response);
request.setAttribute("contatos", contatoService.findAll());
return mapping.findForward("sucess");
}
}
7) Definindo as actions e mappings no arquivo struts-config.xml
Xml<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<form-bean name="contatoForm"
type="com.myapp.action.ContatoForm">
</form-bean>
</form-beans>
<global-exceptions>
<exception
type="java.lang.Exception"
key="user.global.ex"
path="/error.jsp" />
</global-exceptions>
<global-forwards>
<forward name="welcome" path="/Welcome.do"/>
</global-forwards>
<action-mappings>
<action path="/Welcome" forward="/welcomeStruts.jsp"/>
<action
path="/RedirectContato"
type="com.myapp.action.RedirectContatoAction">
<forward
name="sucess"
path="/index.jsp">
</forward>
</action>
<action
path="/CreateContato"
type="com.myapp.action.CreateContatoAction"
name="contatoForm"
input="/RedirectContato.do">
<forward
name="list"
path="/RedirectContato.do">
</forward>
</action>
<!-- samples
<action
path="/"
type="com.myapp."
name=""
scope=""
validate=""
input="" />
</action-mappings>
-->
</action-mappings>
<controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
<message-resources parameter="com/myapp/struts/ApplicationResource"/>
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
</plug-in>
<!-- ========================= Validator plugin ================================= -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>
9) criar uma página que mostre os erros quando acontecer
![]() |
| Figura 30 - Preparando uma página p/ mostrar os erros |
![]() |
| Figura 31 - Página error.jsp |
o projeto deve estar assim :
![]() |
| Figura 32 - Estrutura do projeto até esse ponto |
3) Testando o Projeto Web
Run>> Project
![]() |
| Figura 33 - Testando a app |
![]() |
| Figura 34 - Testando a app, mais um cadastro |
![]() |
| Figura 35 - O programa em Swing da lição anterior acessando a mesma tabela que a pagina |
Mas está com um comportamento estranho:
1º mostra uma tela de cadastro e ao cadastrar mostra a lista dos cadastrados.Porquê ?
Se quisermos entrar direto na lista completa precisamos acessar pelo seguinte endereço na url :
http://localhost:8080/SpringLesson08-SpringStruts/RedirectContato.do
e o link p/ acessa a pagina criada pelo NB+Struts hello, por esse http://localhost:8080/SpringLesson08-SpringStruts/Welcome.do
Como acertamos isso ? Bom tem centenas de jeitos, vamos fazer o mais simples 1º
I) defina como index.html no arquivo web.xml
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
e no index.html aponte p/ o mapping desejado :
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<script type="text/javascript">
location.href='/SpringLesson08-SpringStruts/RedirectContato.do';
</script>
</body>
</html>
II) Salve os arquivos, o NB automaticamente faz o Deploy da app,clique em Run. veja se o apontamento do arquivo html funcionou.
Vou fornecer a versão 1 do projeto como está até aqui.
SpringLesson08-SpringStruts-v1
4) Implementando o Spring ao projeto com o struts.
1) adicione a lib do spring ao projeto
![]() |
| Figura 36 - Adicionando a lib do Spring |
2) altere o struts-config.xml
Xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<form-bean name="contatoForm"
type="com.myapp.action.ContatoForm">
</form-bean>
</form-beans>
<global-exceptions>
<exception
type="java.lang.Exception"
key="user.global.ex"
path="/error.jsp" />
</global-exceptions>
<global-forwards>
<forward name="welcome" path="/Welcome.do"/>
</global-forwards>
<action-mappings>
<action path="/Welcome" forward="/welcomeStruts.jsp"/>
<action
path="/RedirectContato">
<forward
name="sucess"
path="/index.jsp">
</forward>
</action>
<action
path="/CreateContato"
name="contatoForm"
input="/RedirectContato.do">
<forward
name="list"
path="/RedirectContato.do">
</forward>
</action>
<!-- renomeado apos adicionar o spring
<action
path="/CreateContato"
type="com.myapp.action.CreateContatoAction"
name="contatoForm"
input="/RedirectContato.do">
<forward
name="list"
path="/RedirectContato.do">
</forward>
</action>
<action
path="/RedirectContato"
type="com.myapp.action.RedirectContatoAction">
<forward
name="sucess"
path="/index.jsp">
</forward>
</action>
-->
<!-- samples
<action
path="/"
type="com.myapp."
name=""
scope=""
validate=""
input="" />
</action-mappings>
-->
</action-mappings>
<controller>
<set-property
property="processorClass"
value="org.springframework.web.struts.DelegatingRequestProcessor" />
</controller>
<message-resources parameter="MessageResources"/>
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn" >
</plug-in>
<!-- <controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
<message-resources parameter="com/myapp/struts/ApplicationResource"/>
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
</plug-in>
========================= Validator plugin =================================
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>-->
</struts-config>
3) crie o arquivo action-servlet.xml
Xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean name="/CreateContato"
class="com.myapp.action.CreateContatoAction">
<property name="contatoService"></property>
</bean>
<bean name="/RedirectContato"
class="com.myapp.action.RedirectContatoAction">
<property name="contatoService"></property>
</bean>
<bean id="contatoService"
class="com.myapp.service.ContatoServiceImpl">
<!--<property name="contatoDao"> isso causa um erro o correto esta abaixo-->
<property name="dao">
<!-- injeção da dependência-->
<bean
id="contatoDao"
class="com.myapp.dao.ContatoDaoImpl">
</bean>
</property>
</bean>
</beans>
4) salve os arquivos modificados.
5) teste o programa e veja o Log do NB:
Não deve conter nenhum erro, se tiver verifique as configurações nos arquivos XML
Sep 27, 2012 1:02:18 PM org.springframework.web.struts.ContextLoaderPlugIn init INFO: ContextLoaderPlugIn for Struts ActionServlet 'action, module '': initialization started Sep 27, 2012 1:02:18 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing WebApplicationContext for namespace 'action-servlet': startup date [Thu Sep 27 13:02:18 BRT 2012]; root of context hierarchy Sep 27, 2012 1:02:19 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/action-servlet.xml] Sep 27, 2012 1:02:20 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@fe2254a: defining beans [/CreateContato,/RedirectContato]; root of factory hierarchy Sep 27, 2012 1:02:21 PM org.springframework.web.struts.ContextLoaderPlugIn initWebApplicationContext INFO: Using context class 'org.springframework.web.context.support.XmlWebApplicationContext' for servlet 'action' Sep 27, 2012 1:02:21 PM org.springframework.web.struts.ContextLoaderPlugIn init INFO: ContextLoaderPlugIn for Struts ActionServlet 'action', module '': initialization completed in 2610 ms Sep 27, 2012 1:02:21 PM org.apache.catalina.util.LifecycleBase start INFO: The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/SpringLesson08-SpringStruts]] after start() had already been called. The second call will be ignored.
6) altere as actions no package actions
CODE
package com.myapp.action;
import com.myapp.model.Contato;
import com.myapp.service.ContatoService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class CreateContatoAction extends Action {
// private ContatoService userService = new ContatoServiceImpl();
// com o Spring
private ContatoService contatoService;
public void setContatoService(ContatoService userService) {
this.contatoService = userService;
}
@Override
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// return super.execute(mapping, form, request, response);
ContatoForm contatoForm = (ContatoForm) form;
Contato contato = new Contato();
BeanUtils.copyProperties(contato, contatoForm);
contatoService.create(contato);
return mapping.findForward("list");
}
}
CODE
package com.myapp.action;
import com.myapp.service.ContatoService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class RedirectContatoAction extends Action {
// private ContatoService contatoService = new ContatoServiceImpl();
// com o Spring
private ContatoService contatoService ;
public void setContatoService(ContatoService contatoService) {
this.contatoService = contatoService;
}
@Override
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// return super.execute(mapping, form, request, response);
request.setAttribute("contatos", contatoService.findAll());
return mapping.findForward("sucess");
}
}
7) altere a classe dao.ContatoServiceImpl
CODE
package com.myapp.service;
import com.myapp.dao.ContatoDao;
import com.myapp.model.Contato;
import java.util.List;
public class ContatoServiceImpl implements ContatoService {
// private ContatoDao dao = new ContatoDaoImpl();
// depois do spring
private ContatoDao dao;
@Override
public void create(Contato contato) {
getDao().create(contato);
}
@Override
public List<Contato> findAll() {
return getDao().findAll();
}
}
8) compile e teste. veja o erro :
Log
Offending resource: ServletContext resource [/WEB-INF/action-servlet.xml] Bean '/CreateContato'; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: <property> element for property 'contatoService' must specify a ref or value Offending resource: ServletContext resource [/WEB-INF/action-servlet.xml] Bean '/CreateContato' -> Property 'contatoService' at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68) at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
9) acerte o arquivo action-servlet.xml e adicione as ref
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean name="/CreateContato"
class="com.myapp.action.CreateContatoAction">
<property name="contatoService" ref="contatoService"></property>
</bean>
<bean name="/RedirectContato"
class="com.myapp.action.RedirectContatoAction">
<property name="contatoService" ref="contatoService"></property>
</bean>
<bean id="contatoService"
class="com.myapp.service.ContatoServiceImpl">
<!--<property name="contatoDao"> isso causa um erro o correto esta abaixo-->
<property name="dao">
<!-- injeção da dependência-->
<bean
id="contatoDao"
class="com.myapp.dao.ContatoDaoImpl">
</bean>
</property>
</bean>
</beans>
10) compile e teste. veja o erro : Log
org.springframework.beans.factory.BeanCreationException: Error creating bean with name '/CreateContato' defined in ServletContext resource [/WEB-INF/action-servlet.xml]: Cannot resolve reference to bean 'contatoService' while setting bean property 'contatoService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contatoService' defined in ServletContext resource [/WEB-INF/action-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'dao' of bean class [com.myapp.service.ContatoServiceImpl]: Bean property 'dao' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:329)
A classe precisa dos Gets/Sets
11) encapsule a classe ContatoServiceImpl
![]() |
| Figura 37 - Encapsule a classe ContatoServiceImpl |
CODE
package com.myapp.service;
import com.myapp.dao.ContatoDao;
import com.myapp.model.Contato;
import java.util.List;
public class ContatoServiceImpl implements ContatoService {
// private ContatoDao dao = new ContatoDaoImpl();
// depois do spring
private ContatoDao dao;
@Override
public void create(Contato contato) {
getDao().create(contato);
}
@Override
public List<Contato> findAll() {
return getDao().findAll();
}
public ContatoDao getDao() {
return dao;
}
public void setDao(ContatoDao dao) {
this.dao = dao;
}
}
compile e teste.
Log
Sep 27, 2012 1:43:55 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing WebApplicationContext for namespace 'action-servlet': startup date [Thu Sep 27 13:43:55 BRT 2012]; root of context hierarchy Sep 27, 2012 1:43:55 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/action-servlet.xml] Sep 27, 2012 1:43:55 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3e898802: defining beans [/CreateContato,/RedirectContato,contatoService]; root of factory hierarchy Sep 27, 2012 1:43:56 PM org.springframework.web.struts.ContextLoaderPlugIn initWebApplicationContext INFO: Using context class 'org.springframework.web.context.support.XmlWebApplicationContext' for servlet 'action' Sep 27, 2012 1:43:56 PM org.springframework.web.struts.ContextLoaderPlugIn init INFO: ContextLoaderPlugIn for Struts ActionServlet 'action', module '': initialization completed in 921 ms Sep 27, 2012 1:43:56 PM org.apache.catalina.core.StandardContext reload INFO: Reloading Context with name [/SpringLesson08-SpringStruts] is completed
12) Teste. experimente fazer mais um cadastro.
![]() |
| Figura 38 - Testando a app de novo |
13) se tivéssemos outros objetos e tabelas precisaríamos da conexão compartilhada entre os DAOs.
![]() |
| Figura 39 - Crie a classe de conexão ao Mysql |
CODE
package com.myapp.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ConexaoMysql {
private Connection Conexao;
public ConexaoMysql() {
connect();
}
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception ex) {
Logger.getLogger(ConexaoMysql.class.getName()).log(Level.SEVERE, null, ex);
throw new ExceptionInInitializerError(ex);
}
}
public Connection getConexao() {
return Conexao;
}
public final void connect() {
try {
this.Conexao = DriverManager.getConnection("jdbc:mysql://ns1/springlessons", "springlessons", "DHADdSXcDF29WGXy");
} catch (SQLException ex) {
Logger.getLogger(ConexaoMysql.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
14) altere o contatoDaoImpl p/ usar essa conexão :
CODE
package com.myapp.dao;
import com.myapp.model.Contato;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ContatoDaoImpl implements ContatoDao {
ConexaoMysql Conexao = new ConexaoMysql();
@Override
public void create(Contato contato) {
Connection Con = this.Conexao.getConexao();
PreparedStatement pstm = null;
try {
// Con = getClass();
String sql = "INSERT INTO `springlessons`.`contato`"
+ "(`nome`,`telefone`)"
+ " VALUES (?,?)";
pstm = Con.prepareStatement(sql);
pstm.setString(1, contato.getNome());
pstm.setString(2, contato.getTelefone());
pstm.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
pstm.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
try {
Con.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
}
}
@Override
public List<Contato> findAll() {
Connection Con = this.Conexao.getConexao();
PreparedStatement pstm = null;
ResultSet rs = null;
try {
// Con = getConnection();
String sql = "SELECT `contato`.`id`,`contato`.`nome`,`contato`.`telefone`"
+ " FROM `springlessons`.`contato`";
pstm = Con.prepareStatement(sql);
List<Contato> contatos = new ArrayList<Contato>();
rs = pstm.executeQuery(sql);
while (rs.next()) {
Contato contato = new Contato();
contato.setId(rs.getInt("id"));
contato.setNome(rs.getString("nome"));
contato.setTelefone(rs.getString("telefone"));
contatos.add(contato);
}
return contatos;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
pstm.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
try {
Con.close();
} catch (Exception e) {
Logger.getLogger(ContatoDaoImpl.class.getName()).log(Level.SEVERE, null, e);
}
}
}
}
Salve, e teste:
![]() |
| Figura 40 - Testando a app a pós as alterações |
E assim integramos o struts 1.3.10 com o Spring 3.2
Projeto NB
![]() |
| Figura 41a - Arquivos do projeto |
![]() |
| Figura 41b - Arquivos do projeto |
Como este projeto tem propósitos educacionais , os frameworks são libs do NB, e estão incluídas inteiras com todas as deps.
Fica como lição de casa, adicionar manualmente apenas as libs utilizadas.
![]() |
| Figura 42 - Libs utilizadas do projeto |
Download do projeto NB
SpringLesson08-SpringStruts-v2
Resumo, o que vimos :
- Organização de projetos WEB
- Implementar o Struts 1.3.10
- Criamos uma interface contatoDAO
- Implementamos a interface com a classe ContatoDaoImpl
- Criamos uma interface de Serviço ContatoService
- Implementamos a interface com a classe ContatoServiceImpl
- Criamos as classes p/ atender os actions que são mapeados no arquivo struts-config.xml, que extendem a classe org.apache.struts.action.Action
- Definimos as actions e mappings no arquivo struts-config.xml
- Criamos uma view através de um arquivo index.jsp
- Criamos uma vier p/ mostrar os erros
- Integramos o Spring 3 com o Struts 2
- Definimos nossos beans no arquivo action-servlet.xml
- Vimos nos logs a ordem em que as classes são instanciadas e como localizar erros
- Compartilhamos a conexão através de uma classe ConexaoMysql
- Testamos o cadastro e vimos funcionando
humm e como ficaria essa implementação com o Struts 2?
até o próximo post...











































Nenhum comentário:
Postar um comentário