desenvolvimento java para web osvaldo pinali doederlein visionnaire
TRANSCRIPT
Desenvolvimento Java para Desenvolvimento Java para WebWeb
Osvaldo Pinali DoederleinOsvaldo Pinali Doederlein
VisionnaireVisionnaire
Introdução à Introdução à PlataformaPlataforma
J2EE 1.4J2EE 1.4
AgendaAgenda
ContainersContainers Padrões JCPPadrões JCP Servidores de AplicaçãoServidores de Aplicação
J2EE e ContainersJ2EE e Containers
http://java.sun.com/j2ee/http://java.sun.com/j2ee/ Container: Conceito fundamental do J2EEContainer: Conceito fundamental do J2EE Aplicação executa num “casulo” que Aplicação executa num “casulo” que
assume ou facilita diversas assume ou facilita diversas responsabilidadesresponsabilidades Administração / Ciclo de vidaAdministração / Ciclo de vida Conectividade (SGBD, Messaging, HTTP, SOAP Conectividade (SGBD, Messaging, HTTP, SOAP
etc.)etc.) Funcionalidades: Persistência, Segurança...Funcionalidades: Persistência, Segurança...
APIsAPIs
O Container também implementa APIs O Container também implementa APIs J2EEJ2EE APIs J2SE: stand-alone (bibliotecas simples)APIs J2SE: stand-alone (bibliotecas simples) APIs J2EE: maior dependência de serviçosAPIs J2EE: maior dependência de serviços
XML-RPC: exige server HTTPXML-RPC: exige server HTTP JMS: exige middleware de mensagensJMS: exige middleware de mensagens Connector: exige bridges com outros sistemasConnector: exige bridges com outros sistemas EJB: exige servidor RMI/IIOPEJB: exige servidor RMI/IIOP
APIs do J2EE 1.4: APIs do J2EE 1.4: DiversosDiversos JavaMailJavaMail
Envio e recepção de e-mail por POP, IMAP, SMTPEnvio e recepção de e-mail por POP, IMAP, SMTP
JavaBeans Activation FrameworkJavaBeans Activation Framework Ativação de funcionalidades via tipos MIMEAtivação de funcionalidades via tipos MIME
JNDI JNDI (Java Naming and Directory)(Java Naming and Directory) LDAP, NDS, DNS, NIS, CosNaming; serviços J2EELDAP, NDS, DNS, NIS, CosNaming; serviços J2EE
JAASJAAS (Autenthication & Authorization (Autenthication & Authorization Service)Service) Autorização e Autenticação; PAMAutorização e Autenticação; PAM
APIs do J2EE 1.4: APIs do J2EE 1.4: MiddlewareMiddleware JMSJMS (Java Message Service) (Java Message Service)
Comunicação assíncrona robustaComunicação assíncrona robusta
JTAJTA (Java Transaction API) (Java Transaction API) Transações de alto nívelTransações de alto nível
JCAJCA (J2EE Connector Architecture) (J2EE Connector Architecture) Integração com sistemas não-J2EEIntegração com sistemas não-J2EE
JDBCJDBC (Java Database Connectivity) (Java Database Connectivity) J2SE + DataSources, transações XAJ2SE + DataSources, transações XA
APIs do J2EE 1.4: WebAPIs do J2EE 1.4: Web
ServletsServlets Programação Web dinâmicaProgramação Web dinâmica
JSPJSP (Java Sever Pages) (Java Sever Pages) Idem, mais visualIdem, mais visual
JSTLJSTL (Java Standard Template Library) (Java Standard Template Library) Idem, mais estruturadoIdem, mais estruturado
Alternativas/Complementos: Alternativas/Complementos: StrutsStruts, , Spring...Spring...
Futuro (J2SE 5.0): JSF (JavaServerFaces)Futuro (J2SE 5.0): JSF (JavaServerFaces)
APIs do J2EE 1.4:APIs do J2EE 1.4:XML e Web ServicesXML e Web Services JAXPJAXP (Java API for XML Processing) (Java API for XML Processing)
DOM, SAX, XSLTDOM, SAX, XSLT
SAAJSAAJ (SOAP with Attachments API for (SOAP with Attachments API for Java)Java) Web Services: SOAP (modelo documento)Web Services: SOAP (modelo documento)
JAX-RPCJAX-RPC (Java API for XML-based RPC) (Java API for XML-based RPC) Web Services: SOAP (modelo RPC), WSDLWeb Services: SOAP (modelo RPC), WSDL
JAXRJAXR (Java API for XML Registries) (Java API for XML Registries) Web Services: UDDI / ebXMLWeb Services: UDDI / ebXML
APIs do J2EE 1.4: EJBAPIs do J2EE 1.4: EJB
EJBEJB (Enterprise Java Beans) (Enterprise Java Beans) Componentes Distribuídos; Session; RMI/IIOPComponentes Distribuídos; Session; RMI/IIOP
EJB EJB BMPBMP//CMPCMP//CMRCMR Entity; Persistência Automática (mapeamento Entity; Persistência Automática (mapeamento
O/R)O/R)
EJB EJB MDBMDB (Message-Driven Beans) (Message-Driven Beans) Facilidade de alto nível para JMS e Web ServicesFacilidade de alto nível para JMS e Web Services
Transações, SegurançaTransações, Segurança Facilidades declarativasFacilidades declarativas
Padrões do JCPPadrões do JCP
J2EE 1.4 (JSR-151 + 15 JSRs, jcp.org)J2EE 1.4 (JSR-151 + 15 JSRs, jcp.org) Padroniza quase tudoPadroniza quase tudo
APIsAPIs Schemas, DeploymentSchemas, Deployment Comportamentos (ciclos de vida, etc.)Comportamentos (ciclos de vida, etc.)
Não cobre:Não cobre: Ferramentas, MetodologiasFerramentas, Metodologias QoSQoS Integração (ex.: suporte a SGBDs e middlewares)Integração (ex.: suporte a SGBDs e middlewares)
http://java.sun.com/reference/blueprints/http://java.sun.com/reference/blueprints/
Tomcat 5.5Tomcat 5.5
Apache + Sun; RI de JSRs de Servlet, JSP, Apache + Sun; RI de JSRs de Servlet, JSP, etc.etc.
Container Web do JBoss, Sun AppServer, Container Web do JBoss, Sun AppServer, ……
Conectores para Apache e IISConectores para Apache e IIS http://jakarta.apache.org/tomcat/http://jakarta.apache.org/tomcat/
JBoss 4.0JBoss 4.0
JBoss GroupJBoss Group Open Source & ComercialOpen Source & Comercial Arquitetura: Microkernel (JMX), AOPArquitetura: Microkernel (JMX), AOP http://www.jboss.com/products/jbossas/http://www.jboss.com/products/jbossas/
Design Patterns para Design Patterns para J2EEJ2EE
AgendaAgenda
Design PatternsDesign Patterns SingletonSingleton FaçadeFaçade FactoryFactory DAODAO MVCMVC
Design PatternsDesign Patterns
Design PatternsDesign Patterns (GoF, 1995) (GoF, 1995) Pattern = design reutilizável; Pattern = design reutilizável;
problema+soluçãoproblema+solução Modelos; ex.: Intenção, Motivação, Modelos; ex.: Intenção, Motivação,
Aplicabilidade, Estrutura, Implementação, Aplicabilidade, Estrutura, Implementação, Implicações, Categoria...Implicações, Categoria...
Instanciável, mas não reusável, como códigoInstanciável, mas não reusável, como código
Linguagem de Patterns: Coleção de patterns Linguagem de Patterns: Coleção de patterns relacionados, com modelo comumrelacionados, com modelo comum
http://java.sun.com/blueprints/patterns/http://java.sun.com/blueprints/patterns/
Singleton: MotivaçãoSingleton: Motivação
Garantir que uma classe tenha instância Garantir que uma classe tenha instância únicaúnica Sem abrir mão do suporte à heranSem abrir mão do suporte à herança (como ça (como
staticstatic))
Implementação robusta de entidades que Implementação robusta de entidades que precisam ser únicas; ex: configuraçãoprecisam ser únicas; ex: configuração
Alternativa OO às variáveis globaisAlternativa OO às variáveis globais Facilita a inicialização “lazy”Facilita a inicialização “lazy”
Singleton: EstruturaSingleton: Estrutura
Singleton
-singletonInstance...
«constructor»-Singleton( )«misc»+getInstance( )...
class Configuracao {class Configuracao { private static private static Configuracao Configuracao singletonsingleton;; private final Properties props;private final Properties props; private Configuracao private Configuracao (Properties props) { this.props = props; }(Properties props) { this.props = props; } public static Configuracao getInstance () public static Configuracao getInstance () {{ if (singleton == null) {if (singleton == null) { properties props = // ... Lê properties de um arquivoproperties props = // ... Lê properties de um arquivo singleton = new Configuracao(props);singleton = new Configuracao(props); }} return singleton;return singleton; }} public getProperties () { return props; }public getProperties () { return props; }}}
Properties props = Configuracao.getInstance().getProperties();Properties props = Configuracao.getInstance().getProperties();
Façade: MotivaçãoFaçade: Motivação
Interface única e simples para um sistemaInterface única e simples para um sistema Simplifica API, reduz curva de aprendizadoSimplifica API, reduz curva de aprendizado
Reduz dependências e acoplamentoReduz dependências e acoplamento Se o modelo interno do sistema evoluir, basta Se o modelo interno do sistema evoluir, basta
mudar a implementação da Façade; clientes mudar a implementação da Façade; clientes são preservadossão preservados
Conduz a modelos em camadas (layers)Conduz a modelos em camadas (layers) Ex: Cliente (JSP) Ex: Cliente (JSP) Façade (Session Bean) Façade (Session Bean)
NegócioNegócio
Façade: EstruturaFaçade: Estrutura
Cliente
Façade
Usa1
*
Façade (Session / J2EE)Façade (Session / J2EE)
public class SistemaPagamentos {public class SistemaPagamentos { public void alteraSalario (String matricula, double salario) public void alteraSalario (String matricula, double salario) {{ Funcionario func = CadastroFuncs.getInstance().find(matricula);Funcionario func = CadastroFuncs.getInstance().find(matricula); if (func != null && func.isAtivo())if (func != null && func.isAtivo()) func.setSalario(salario);func.setSalario(salario); }} // ... Outros métodos da Façade// ... Outros métodos da Façade
}}
// Cliente não precisa conhecer Funcionario, CadastroFuncs, etc.// Cliente não precisa conhecer Funcionario, CadastroFuncs, etc.
SistemaPagamentos sp = SistemaPagamentos sp = // ...// ...
sp.alteraSalario("93764622", 4350.00);sp.alteraSalario("93764622", 4350.00);
Factory: MotivaçãoFactory: Motivação
Cria objetos sem saber suas classes concretasCria objetos sem saber suas classes concretas Encapsula decisões sobre a criação de objetoEncapsula decisões sobre a criação de objeto Melhoram OO (construtores não são polimórficos!)Melhoram OO (construtores não são polimórficos!)
Variante: Factory MethodVariante: Factory Method Útil com herança, delega criação à subclasseÚtil com herança, delega criação à subclasse Evita Evita instanceofinstanceof para criar objetos relacionados para criar objetos relacionados
Variante: Abstract FactoryVariante: Abstract Factory Suporta um conjunto de entidades relacionadasSuporta um conjunto de entidades relacionadas Suporta implementações "plugáveis", ex.: JDBC, XMLSuporta implementações "plugáveis", ex.: JDBC, XML
Factory Method: Factory Method: EstruturaEstrutura
public interface Cliente {public interface Cliente { public Conta abreConta ();public Conta abreConta ();
}}public class ClienteSimples public class ClienteSimples implements Clienteimplements Cliente { { public Conta abreConta () public Conta abreConta () {{ return new ContaComum(this);return new ContaComum(this);}}public class ClientePremier public class ClientePremier implements Clienteimplements Cliente { { public Conta abreConta () public Conta abreConta () {{ return new ContaEspecial(this);return new ContaEspecial(this);}}
Cliente cli = Cliente cli = // ... obtém da database ou outra fonte// ... obtém da database ou outra fonte
Conta ct = cli.abreConta(); Conta ct = cli.abreConta(); // cria conta do tipo correto// cria conta do tipo correto
Abstract Factory: Abstract Factory: EstruturaEstrutura
// Utiliza fábrica abstrata de engine XML (Xerces, Crimson, etc.)// Utiliza fábrica abstrata de engine XML (Xerces, Crimson, etc.)SAXParserFactory spf =SAXParserFactory spf = SAXParserFactorySAXParserFactory.newInstance().newInstance();;spf.setValidating(true);spf.setValidating(true);spf.setNamespaceAware(true);spf.setNamespaceAware(true);// Utiliza fábrica abstrata de parser (com ou sem validação, etc.)// Utiliza fábrica abstrata de parser (com ou sem validação, etc.)SAXParser parser = spfSAXParser parser = spf.newSAXParser().newSAXParser();;XMLReader reader = parser.getXMLReader();XMLReader reader = parser.getXMLReader();reader.setContentHandler(this);reader.setContentHandler(this);reader.parse(config);reader.parse(config);
DAO: MotivaçãoDAO: Motivação
Desacoplar o acesso a dados dos clientesDesacoplar o acesso a dados dos clientes Ocultar a complexidade do acesso a Ocultar a complexidade do acesso a
dadosdados Permitir alternância fácil e dinâmica da Permitir alternância fácil e dinâmica da
implementação de persistênciaimplementação de persistência
Não é necessário com ferramentas ORM Não é necessário com ferramentas ORM (como Hibernate), mas facilita migração (como Hibernate), mas facilita migração JDBCJDBCORMORM
DAO: EstruturaDAO: Estrutura
public class public class VendaVenda { { /* nenhum acesso a dados */ /* nenhum acesso a dados */ }}public interface VendaDaopublic interface VendaDao { { public Venda find (String id) throws SQLException;public Venda find (String id) throws SQLException;
}}public class VendaDaoJDBC implements VendaDaopublic class VendaDaoJDBC implements VendaDao { { private DataSource ds;private DataSource ds;
public Venda find (String id) throws SQLException public Venda find (String id) throws SQLException {{ try {try { Connection c = ds.getConnection();Connection c = ds.getConnection(); Statement stmt = c.createStatement();Statement stmt = c.createStatement(); ResultSet rs = stmt.executeQuery("SELECT…");ResultSet rs = stmt.executeQuery("SELECT…"); if (rs.next()) return new Venda(id, rs.getString("produto"), …);if (rs.next()) return new Venda(id, rs.getString("produto"), …); } finally { if (c != null) try { c.close(); } catch (SQLException e){} }} finally { if (c != null) try { c.close(); } catch (SQLException e){} } return null; return null; // // OObjeto não encontradobjeto não encontrado
}}
MVC-2: MotivaçãoMVC-2: Motivação
Desacoplar responsabilidades de uma GUI:Desacoplar responsabilidades de uma GUI: Model:Model: Camada de Implementação das Regras Camada de Implementação das Regras
de Negóciode Negócio View:View: Layout dos dados (ex.: telas HTML) Layout dos dados (ex.: telas HTML) Controller:Controller: Comportamento da GUI (ex.: Comportamento da GUI (ex.:
consultas, atualizações, tratamento de erros, consultas, atualizações, tratamento de erros, defaults)defaults)
Permite variar/evoluir cada um separadamentePermite variar/evoluir cada um separadamente
View editável por não-programadoresView editável por não-programadores Back-end pode variar sem afetar GUIBack-end pode variar sem afetar GUI
MVC-2: EstruturaMVC-2: Estrutura
Controller
ModelView
Requisição Envio de Dados
Resposta do Envio de dados
Seleção do Visualizador
Resposta
<html:form action="/LoginSubmit.do"><html:form action="/LoginSubmit.do"> <table><table> <tr><td>Login:</td><tr><td>Login:</td> <td><html:text property="login" size="20"/></td><td><html:text property="login" size="20"/></td> </tr></tr> <tr><td>Senha:</td><tr><td>Senha:</td> <td><html:password property="<td><html:password property="passwordpassword" size="20"/></td>" size="20"/></td> </tr></tr> <tr><td><html:submit>OK</html:submit></td></tr><tr><td><html:submit>OK</html:submit></td></tr> </table></table></html:form></html:form><html:messages id="error" property="invalid"><html:messages id="error" property="invalid"><script><script>aalert('<bean:write name="error" />');</script>lert('<bean:write name="error" />');</script></html:messages></html:messages><html:javascript formName="LoginForm"/><html:javascript formName="LoginForm"/>
ViewView
public class LoginAction extends DispatchActionpublic class LoginAction extends DispatchAction { { public ActionForward login (ActionMapping map,public ActionForward login (ActionMapping map,
ActionForm form, HttpServletRequest req, ActionForm form, HttpServletRequest req, HttpServletResponse resp) throws ExceptionHttpServletResponse resp) throws Exception { {
audit(request, PortalAudit.ACCESS);audit(request, PortalAudit.ACCESS); if (isFirstLogin(request))if (isFirstLogin(request)) return return mapping.findForward("firstLogin")mapping.findForward("firstLogin");; elseelse return mapping.findForward("loginOk")return mapping.findForward("loginOk");; }} private boolean isFirstLogin (HttpServletRequest req) {...}private boolean isFirstLogin (HttpServletRequest req) {...} // ... Outras ações ...// ... Outras ações ...
}}
ControllerController
LoggingLogging
AgendaAgenda
Log4JLog4J java.util.loggingjava.util.logging
Log4JLog4J
Biblioteca do projeto Apache JakartaBiblioteca do projeto Apache Jakarta Substitui Substitui System.out.println()System.out.println()......
Níveis de log; ativação dinâmica sem mudar códigoNíveis de log; ativação dinâmica sem mudar código Opções de output (console, arquivo, rede, DB etc.)Opções de output (console, arquivo, rede, DB etc.) Formatação, ExtensibilidadeFormatação, Extensibilidade
Logs detalhados, de qualidade; fácil e eficienteLogs detalhados, de qualidade; fácil e eficiente Para diagnóstico de problemas (debug ou produção)Para diagnóstico de problemas (debug ou produção) Para auditoria, etc.Para auditoria, etc.
http://logging.apache.org/log4j/http://logging.apache.org/log4j/
Log4J: ExemploLog4J: Exemplo
Logger logger = Logger.getLogger("SIST");Logger logger = Logger.getLogger("SIST");
logger.debug("x=“ + x);logger.debug("x=“ + x);logger.log(Level.DEBUG, "x=“ + x);logger.log(Level.DEBUG, "x=“ + x);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled()) // Se não estiver habilitado...// Se não estiver habilitado...
logger.debug(a+b+c+d+e+f); logger.debug(a+b+c+d+e+f); // ...evita custo de gerar dados// ...evita custo de gerar dados
Log4J: log4j.propertiesLog4J: log4j.properties
log4j.logger.SIST = INFO, APP_SISTlog4j.logger.SIST = INFO, APP_SIST
log4j.appender.APP_SIST = org.apache.log4j.RollingFileAppenderlog4j.appender.APP_SIST = org.apache.log4j.RollingFileAppenderlog4j.appender.APP_SIST.File = ../logs/SIST.loglog4j.appender.APP_SIST.File = ../logs/SIST.loglog4j.appender.APP_SIST.MaxFileSize = 10MBlog4j.appender.APP_SIST.MaxFileSize = 10MBlog4j.appender.APP_SIST.MaxBackupIndex = 10log4j.appender.APP_SIST.MaxBackupIndex = 10log4j.appender.APP_SIST.layout = org.apache.log4j.PatternLayoutlog4j.appender.APP_SIST.layout = org.apache.log4j.PatternLayoutlog4j.appender.APP_SIST.layout.ConversionPattern =log4j.appender.APP_SIST.layout.ConversionPattern = [%p] %d{HH:mm:ss} - %m%n[%p] %d{HH:mm:ss} - %m%n
Log4J: log4j.xmlLog4J: log4j.xml
<?xml version="1.0" encoding="UTF-8" ?><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'><log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> <logger name=“SIST"> <level value="INFO"/> </logger><logger name=“SIST"> <level value="INFO"/> </logger> <appender name="APP_SIST" class="org.apache.log4j.RollingFileAppender"><appender name="APP_SIST" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="../logs/SIST.log"/><param name="File" value="../logs/SIST.log"/> <param name="MaxFileSize" value="10MB"/><param name="MaxFileSize" value="10MB"/> <param name="MaxBackupIndex" value="10"/><param name="MaxBackupIndex" value="10"/> <layout class="org.apache.log4j.PatternLayout"><layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%p] %d{HH:mm:ss} - %m%n"/><param name="ConversionPattern" value="[%p] %d{HH:mm:ss} - %m%n"/> </layout></layout> </appender></appender></log4j:configuration></log4j:configuration>
java.util.loggingjava.util.logging
API padrão do J2SE 1.4+ (JSR-47)API padrão do J2SE 1.4+ (JSR-47) Semelhante à Log4J, mas não Semelhante à Log4J, mas não
igual/compatíveligual/compatível Menos poderosa; Mais leve, simples, eficienteMenos poderosa; Mais leve, simples, eficiente
Log4J ou Log4J ou java.util.loggingjava.util.logging?? Log4J não é o padrão, mas ainda é mais popularLog4J não é o padrão, mas ainda é mais popular java.util.loggingjava.util.logging melhor para componentes reusáveis melhor para componentes reusáveis
(não impõe dependência da Log4J para projetos)(não impõe dependência da Log4J para projetos) A Jakarta Commons Logging só piora as coisas A Jakarta Commons Logging só piora as coisas
http://java.sun.com/j2se/1.5.0/docs/guide/logging/http://java.sun.com/j2se/1.5.0/docs/guide/logging/
java.util.loggingjava.util.logging: Exemplo: Exemplo
Logger logger = Logger.getLogger("SIST");Logger logger = Logger.getLogger("SIST");
logger.fine("x=“ + x);logger.fine("x=“ + x);logger.log(Level.FINE, "x=“ + x);logger.log(Level.FINE, "x=“ + x);
if (logger.isLoggable(Level.FINE)) if (logger.isLoggable(Level.FINE)) // Se não estiver habilitado...// Se não estiver habilitado...
logger.fine(a+b+c+d+e+f); logger.fine(a+b+c+d+e+f); // ...evita custo de gerar dados// ...evita custo de gerar dados
java.util.loggingjava.util.logging: : logging.propertieslogging.properties
handlers= java.util.logging.FileHandlerhandlers= java.util.logging.FileHandlerSIST.level = INFOSIST.level = INFO
java.util.logging.FileHandler.pattern = ../logs/SIST%u.logjava.util.logging.FileHandler.pattern = ../logs/SIST%u.logjava.util.logging.FileHandler.limit = 10000000java.util.logging.FileHandler.limit = 10000000java.util.logging.FileHandler.formatter = java.util.logging.FileHandler.formatter =
java.util.logging.SimpleFormatterjava.util.logging.SimpleFormatter
JDBCJDBC
AgendaAgenda
JDBC APIJDBC API
J2EE/DataSourcesJ2EE/DataSources
A API JDBCA API JDBC
Baseada na ODBC (Microsoft; Open Group Baseada na ODBC (Microsoft; Open Group CLI)CLI) Microsoft: novas APIs (OleDB, ADO, RDO, RDS...)Microsoft: novas APIs (OleDB, ADO, RDO, RDS...) JDBC: evolução compatível + frameworks O/RJDBC: evolução compatível + frameworks O/R
CaracterísticasCaracterísticas Baixo nível: conexões, statements, cursores, SQLBaixo nível: conexões, statements, cursores, SQL Leve e eficienteLeve e eficiente Infra-estrutura para todas as outras soluçõesInfra-estrutura para todas as outras soluções
http://java.sun.com/products/jdbc/http://java.sun.com/products/jdbc/
JDBC: JDBC: ConnectionConnection
Representa sessão com o SGBD, e Representa sessão com o SGBD, e transaçãotransação Alto custo de criação. Usar pools!Alto custo de criação. Usar pools! Default: auto-commit, não usar!!Default: auto-commit, não usar!!
Connection conn = null;Connection conn = null;try {try { conn = DriverManager.getConnection(url, user, password);conn = DriverManager.getConnection(url, user, password); // Utiliza a conexão...// Utiliza a conexão...
} catch (SQLException e) {} catch (SQLException e) { if (conn != null) try { conn.close(); } catch (SQLException e) {}if (conn != null) try { conn.close(); } catch (SQLException e) {}}}
JDBC: JDBC: Statement Statement ee ResultSet ResultSet
StatementStatement: Query, Update, ou DDL: Query, Update, ou DDL Prefira Prefira PreparedStatementPreparedStatement sempre!sempre!
ResultSetResultSet: Cursor (resultado de : Cursor (resultado de StatementStatement))
Statement stmt = conn.createStatement();Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT id,nome FROM FUNC");ResultSet rs = stmt.executeQuery("SELECT id,nome FROM FUNC");while (rs.next()) {while (rs.next()) { System.out.println(rs.getInt(1));System.out.println(rs.getInt(1)); System.out.println(rs.getString("nome"));System.out.println(rs.getString("nome"));}}stmt.close();stmt.close();
JDBC: JDBC: PreparedStatementPreparedStatement
EstendeEstende Statement Statement, mais poderoso e eficiente, mais poderoso e eficiente Binding (?), reduz recompilação e formatação de Binding (?), reduz recompilação e formatação de
SQLSQL Cache no cliente (driver JDBC)Cache no cliente (driver JDBC) Também é mais seguro (evita "injeção de SQL")Também é mais seguro (evita "injeção de SQL")
PreparedStatement stmt = conn.prepareStatement(PreparedStatement stmt = conn.prepareStatement( "SELECT id,nome FROM FUNC WHERE salario >= ?");"SELECT id,nome FROM FUNC WHERE salario >= ?");stmt.setDouble(1, 3000);stmt.setDouble(1, 3000);ResultSet rs = stmt.executeQuery();ResultSet rs = stmt.executeQuery();......stmt.close();stmt.close();
JDBC: JDBC: CallableStatementCallableStatement
Invocação de stored procedures / Invocação de stored procedures / functionsfunctions ““Anti-OO”, mas reduz tráfego com SGBDAnti-OO”, mas reduz tráfego com SGBD
CallableStatement stmt = conn.prepareCall(CallableStatement stmt = conn.prepareCall( “ “{call CALCULA_SALARIO (?,?)}");{call CALCULA_SALARIO (?,?)}");stmt.setInt(1, idFuncionario);stmt.setInt(1, idFuncionario);stmt.registerOutParameter(2, Types.DOUBLE);stmt.registerOutParameter(2, Types.DOUBLE);stmt.executeUpdate();stmt.executeUpdate();double salario = stmt.getDouble(2);double salario = stmt.getDouble(2);stmt.close();stmt.close();
Gerenciamento de Gerenciamento de RecursosRecursos Invocação dos métodos Invocação dos métodos close()close()
Connection.close()Connection.close(): fecha todos : fecha todos StatementStatements e blobss e blobs Statement.close()Statement.close(): fecha : fecha ResultSetResultSet corrente corrente Statemet.execute*()Statemet.execute*(): também fecha : também fecha ResultSetResultSet anterior anterior ResultSet.close()ResultSet.close(): : nãonão fecha seus blobs! fecha seus blobs!
Regra: fechar só o objeto “raiz local” do Regra: fechar só o objeto “raiz local” do métodométodo Ex.: Se um método recebe a Ex.: Se um método recebe a ConnectionConnection como como
parâmetro, basta fechar os parâmetro, basta fechar os StatementStatement criados criados Evite dividir responsabilidades (um método cria, Evite dividir responsabilidades (um método cria,
outro faz o outro faz o close()close()) ) bugs, bugs, bugs!! bugs, bugs, bugs!!
Opções: Opções: ConnectionConnection
TRANSACTION_READ_UNCOMMITTEDTRANSACTION_READ_UNCOMMITTEDPermite dirtyPermite dirty//non-repeatable/phantom readsnon-repeatable/phantom reads
TRANSACTION_READ_COMMITTEDTRANSACTION_READ_COMMITTEDPermite non-repeatable/phantom readsPermite non-repeatable/phantom reads
TRANSACTION_REPEATABLE_READTRANSACTION_REPEATABLE_READPermite phantom readsPermite phantom reads
TRANSACTION_SERIALIZABLETRANSACTION_SERIALIZABLEIsolamento ACID totalIsolamento ACID total
DES
EM
PEN
HO
D
ES
EM
PEN
HO
C
ON
FIA
BIL
IDA
DE
CO
NFIA
BIL
IDA
DE
Opções: Opções: ResultSetResultSet
FETCH_FORWARD/REVERSE/UNKNOWNFETCH_FORWARD/REVERSE/UNKNOWNDireção da leitura (hints para o driver)Direção da leitura (hints para o driver)
CONCUR_READ_ONLY/UPDATABLECONCUR_READ_ONLY/UPDATABLESomente leitura, ou cursor atualizávelSomente leitura, ou cursor atualizável
TYPE_FORWARD_ONLY/TYPE_FORWARD_ONLY/ SCROLL_SENSITIVE/SCROLL_SENSITIVESCROLL_SENSITIVE/SCROLL_SENSITIVE
Leitura randômica ou aleatóriaLeitura randômica ou aleatória
DES
EM
PEN
HO
DES
EM
PEN
HO
PR
OD
UTIV
IDA
DE
PR
OD
UTIV
IDA
DE
DataSourceDataSource
Abstração sobre obtenção de conexõesAbstração sobre obtenção de conexões J2EE, mas também pode ser usada sem J2EE, mas também pode ser usada sem
containercontainer Suporte a JNDI, pools, transações distribuídasSuporte a JNDI, pools, transações distribuídas Configuração no containerConfiguração no container
Context ctx = new InitialContext();Context ctx = new InitialContext();DataSource ds = (DataSource)ctx.lookup("jdbc/Sistema");DataSource ds = (DataSource)ctx.lookup("jdbc/Sistema");......Connection conn = ds.getConnection();Connection conn = ds.getConnection();
Testes UnitáriosTestes Unitários
AgendaAgenda
Testes UnitáriosTestes Unitários JUnitJUnit
Testes UnitáriosTestes Unitários
TDD (Test-Driven Development), XPTDD (Test-Driven Development), XP 1 funcionalidade = 1 teste1 funcionalidade = 1 teste
Funcionalidade: método, classe, caso de uso, cenárioFuncionalidade: método, classe, caso de uso, cenário
Escrever teste antes do código a testarEscrever teste antes do código a testar Objetivos: melhorar qualidade e produtividadeObjetivos: melhorar qualidade e produtividade
Planejar componentes, do ponto de vista do clientePlanejar componentes, do ponto de vista do cliente Proteção contra bugs de regressãoProteção contra bugs de regressão Otimizações, refactoring... "Otimizações, refactoring... "fearless programmingfearless programming""
http://www.extremeprogramming.org/rules/unittests.htmlhttp://www.extremeprogramming.org/rules/unittests.html
JUnitJUnit
Framework para testes unitários em JavaFramework para testes unitários em Java Kent Beck (XP) + Erich Gamma (Patterns, Kent Beck (XP) + Erich Gamma (Patterns,
Eclipse)Eclipse) SimplesSimples ExtensívelExtensível
Exemplos públicos para examinar...Exemplos públicos para examinar... J2SE/TCK (45.000 testes)J2SE/TCK (45.000 testes) Eclipse (feito com o JUnit)Eclipse (feito com o JUnit)
http://www.junit.org/http://www.junit.org/
public class TestaRaizes public class TestaRaizes extends TestCaseextends TestCase { { public void testpublic void testOk () {Ok () { double[] x = Raizes.calcula(3, 4, 1);double[] x = Raizes.calcula(3, 4, 1); // 3x // 3x22+4x+1=0+4x+1=0 assertTrueassertTrue(x[0] == -3 && x[1] == -9);(x[0] == -3 && x[1] == -9); System.out.println(x[0] + "," + x[1]);System.out.println(x[0] + "," + x[1]); }} public void testpublic void testDeltaNegativo () {DeltaNegativo () { try {try { double[] x = Raizes.calcula(3, 0, 1); double[] x = Raizes.calcula(3, 0, 1); // 3x// 3x22=-1=-1 fail()fail();; }} catch (IllegalArgumentException e) {catch (IllegalArgumentException e) {}} }}}}
public class Raizes {public class Raizes { public static double[] calcula (double a, double b, double c) {public static double[] calcula (double a, double b, double c) { double delta = Math.sqrt(b*b-4*a*c);double delta = Math.sqrt(b*b-4*a*c); if (Double.isNaN(delta)) throw newif (Double.isNaN(delta)) throw new IllegalArgumentException("Delta negativo");IllegalArgumentException("Delta negativo"); double x1 = (-b+delta)/2*a;double x1 = (-b+delta)/2*a; double x2 = (-b-delta)/2*a;double x2 = (-b-delta)/2*a; return new double[]{x1,x2};return new double[]{x1,x2}; }}}}
ServletsServlets
AgendaAgenda
ServletServlet InicializaçãoInicialização FiltrosFiltros RedirecionamentoRedirecionamento SessõesSessões CookiesCookies
ServletServlet
Servlet = Classe Java que responde a Servlet = Classe Java que responde a HTTPHTTP
Exige um conector HTTP (webserver)Exige um conector HTTP (webserver) Servlet recebe um requestServlet recebe um request Conector cuida de headers, TCP/IP, etc.Conector cuida de headers, TCP/IP, etc.
Base para todo stack Java WebBase para todo stack Java Web JSP, JSTL, JSF, Struts, Velocity, Spring, etc.JSP, JSTL, JSF, Struts, Velocity, Spring, etc.
http://java.sun.com/products/servlet/http://java.sun.com/products/servlet/
public class AloMundo extends HttpServlet {public class AloMundo extends HttpServlet { public void doGet (HttpServletRequest req,public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {HttpServletResponse resp) throws IOException, ServletException { resp.setContentType("text/html");resp.setContentType("text/html"); PrintWriter out = response.getWriter();PrintWriter out = response.getWriter(); out.println("<html>");out.println("<html>"); out.println("<head>");out.println("<head>"); out.println("<title>Alô Mundo</title>");out.println("<title>Alô Mundo</title>"); out.println("</head>");out.println("</head>"); out.println("<body>");out.println("<body>"); out.println("<h1>Alô, Mundo!</h1>");out.println("<h1>Alô, Mundo!</h1>"); out.println("</body>");out.println("</body>"); out.println("</html>");out.println("</html>"); }}}}
Web.xml:Web.xml:
<servlet><servlet><servlet-name>AloMundo</servlet-name><servlet-name>AloMundo</servlet-name><servlet-class>AloMundo</servlet-class><servlet-class>AloMundo</servlet-class>
</servlet></servlet><servlet-mapping><servlet-mapping>
<servlet-name>AloMundo</servlet-name><servlet-name>AloMundo</servlet-name><url-pattern>/alo</url-pattern><url-pattern>/alo</url-pattern>
</servlet-mapping></servlet-mapping></web-app></web-app>
Inicialização e Inicialização e ShutdownShutdown Servlet.init(), Servlet.destroy()Servlet.init(), Servlet.destroy()
init()init() na primeira invocação, ou na primeira invocação, ou load-on-startup=trueload-on-startup=true ServletContextListenerServletContextListener
Mecanismo apropriado para ciclo de vida da Mecanismo apropriado para ciclo de vida da aplicação como um todoaplicação como um todo
public class MeuListener implements ServletContextListener{public class MeuListener implements ServletContextListener{public void contextInitialized (ServletContextEvent sce) {public void contextInitialized (ServletContextEvent sce) {
System.out.println("inicializando...");System.out.println("inicializando...");}}public void contextDestroyed (ServletContextEvent sce) {public void contextDestroyed (ServletContextEvent sce) {
System.out.println("terminando...");System.out.println("terminando...");}}
}}
Web.xml:Web.xml:
<listener><listener> <listener-class>TesteListener</listener-class><listener-class>TesteListener</listener-class></listener></listener>
FiltrosFiltros
Interceptação de requestsInterceptação de requests Verificação de desempenhoVerificação de desempenho Logging automatizadoLogging automatizado Controle de segurança, transações, etc.Controle de segurança, transações, etc. Transformações, ex.: via XSLTTransformações, ex.: via XSLT Implementação de frameworks dinâmicos, ex.: Implementação de frameworks dinâmicos, ex.:
StrutsStruts Implementação do próprio containerImplementação do próprio container
public class PSSFilter public class PSSFilter implements Filterimplements Filter { { // Omitidos: init(), destroy()// Omitidos: init(), destroy() public void doFilter (ServletRequest req, ServletResponse resp,public void doFilter (ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOExceptionFilterChain chain) throws ServletException, IOException { { try { chain.doFilter(req, resp); }try { chain.doFilter(req, resp); } finally { Catalog.closeConnection(); }finally { Catalog.closeConnection(); } }}}}
Web.xml:Web.xml: <filter><filter> <filter-name>PSSFilter</filter-name><filter-name>PSSFilter</filter-name> <filter-class>com.visionnaire.PSS.servlet.PSSFilter</filter-class><filter-class>com.visionnaire.PSS.servlet.PSSFilter</filter-class> </filter></filter> <filter-mapping><filter-mapping> <filter-name>PSSFilter</filter-name><url-pattern>*.jsp</url-pattern><filter-name>PSSFilter</filter-name><url-pattern>*.jsp</url-pattern> </filter-mapping></filter-mapping>
Forward e IncludeForward e Include
Forward: Desvio para outra URLForward: Desvio para outra URL
request.getrequest.getRequestDispatcherRequestDispatcher("/Header.jsp")("/Header.jsp") ..forwardforward(request, response);(request, response);
Include: Cópia do output de uma URLInclude: Cópia do output de uma URL
request.getrequest.getRequestDispatcherRequestDispatcher("/OK.jsp")("/OK.jsp") ..includeinclude(request, response);(request, response);
Contexto, Sessões e Contexto, Sessões e CookiesCookies ServletContextServletContext: Representa a web-app: Representa a web-app
MIME, dispatchers, resources, servlets, atributos, logMIME, dispatchers, resources, servlets, atributos, log
HttpSessionHttpSession: Permite armazenar informações : Permite armazenar informações sobre um cliente, através de várias páginassobre um cliente, através de várias páginas ID, atributos, criação, último acesso, timeoutID, atributos, criação, último acesso, timeout Cookies ou URL rewritingCookies ou URL rewriting
CookieCookie: Pacote de dados armazenável no browser: Pacote de dados armazenável no browser Utiliza headers do HTTPUtiliza headers do HTTP Pode ser restrito pelo cliente (número, tamanho)Pode ser restrito pelo cliente (número, tamanho)
JSPJSP
AgendaAgenda
JSPJSP TaglibsTaglibs Expression LanguageExpression Language JSTLJSTL
JSPJSP
Servlet: Java com HTML, JSP: HTML com JavaServlet: Java com HTML, JSP: HTML com Java Semelhante a ASP, PHP, etc.Semelhante a ASP, PHP, etc. JSP gera uma ServletJSP gera uma Servlet
Compilado pelo container, em demanda ou Compilado pelo container, em demanda ou deploydeploy
Acesso a toda a API de ServletsAcesso a toda a API de Servlets
Diretrizes de páginaDiretrizes de página ScriptletsScriptlets AçõesAções
JSP: SintaxeJSP: Sintaxe
ComentárioComentário ExpressãoExpressão ScriptletScriptlet DeclaraçãoDeclaração Diretiva Diretiva includeinclude Diretiva Diretiva pagepage
<%-- <%-- comentáriocomentário --> --><%= <%= expressãoexpressão %> %><% <% statementstatement %> %><%! <%! declaraçãodeclaração %> %><%@include file="<%@include file="url-absolutaurl-absoluta">"><%@page <%@page atribatrib="="valorvalor" %>" %>language="java", import="pkg"language="java", import="pkg"errorPage="errorPage="urlurl", extends="", extends="classeclasse""info="info="msgmsg", contentType="", contentType="MIMEMIME""buffer="buffer="kb|nonekb|none", isErrorPage,", isErrorPage,session, autoflush, isThreadSafesession, autoflush, isThreadSafe
JSP: AçõesJSP: Ações
Ação Ação includeinclude Ação Ação useBeanuseBean
Ação Ação getPropertygetProperty
Ação Ação forwardforward Ação Ação pluginplugin
<jsp:include page="<jsp:include page="urlurl">"><jsp:useBean <jsp:useBean atribatrib="="valorvalor"/>"/>id="id="nomenome" scope="page|request|" scope="page|request|session|application" type="session|application" type="classclass""class="class="classclass" beanName="" beanName="classclass""<jsp:getProperty<jsp:getPropertyname="name="namename" value="" value="valorvalor"/>"/><jsp:forward page="<jsp:forward page="urlurl"/>"/><jsp:plugin <jsp:plugin atribatrib="="valorvalor"/>"/>
JSP: Variáveis JSP: Variáveis predefinidaspredefinidas As mesmas que estariam disponíveis na As mesmas que estariam disponíveis na
ServletServlet HttpServletRequest requestHttpServletRequest request HttpServletResponse responseHttpServletResponse response HttpSession sessionHttpSession session PrintWriter outPrintWriter out
<h2><h2>Seu host é: Seu host é: <%= <%= request.getRemoteHost()request.getRemoteHost() %>%></h2></h2>
<%@page language="java"%><%@page language="java"%>
<%@page import="java.util.Date"/><%@page import="java.util.Date"/>
<jsp:include page="Titulo.html"/><jsp:include page="Titulo.html"/>
<jsp:include page="Navegacao.jsp"/><jsp:include page="Navegacao.jsp"/>
<html><head/><html><head/> <body><body> <p><p> Alo, mundo! Agora são Alo, mundo! Agora são <%= <%= new Date()new Date() %> %>
</p></p> </body></body></html></html>
TaglibsTaglibs
Declaração e Uso (JSP)Declaração e Uso (JSP)<%@taglib prefix="opd" uri="/tags/osvaldo" %><%@taglib prefix="opd" uri="/tags/osvaldo" %><tt:alo name="Osvaldo"> ... </tt:alo><tt:alo name="Osvaldo"> ... </tt:alo>
Configuração (web.xml)Configuração (web.xml)<jsp-config><jsp-config> <taglib><taglib> <taglib-uri>/tags/osvaldo</taglib-uri><taglib-uri>/tags/osvaldo</taglib-uri> <taglib-location>/WEB-INF/tags/osvaldo.tld</taglib-location><taglib-location>/WEB-INF/tags/osvaldo.tld</taglib-location> </taglib></taglib></jsp-config></jsp-config>
<?xml version="1.0" encoding="ISO-8859-1"?><?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE taglib PUBLIC<!DOCTYPE taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN""-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN""http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib><taglib> <tlibversion>1.0.0</tlibversion><tlibversion>1.0.0</tlibversion> <jspversion>1.1</jspversion><jspversion>1.1</jspversion> <shortname>Taglib Demo</shortname><shortname>Taglib Demo</shortname> <tag><tag> <name>alo</name><name>alo</name> <tagclass><tagclass>tags.tags.AloTag</tagclass>AloTag</tagclass> <bodycontent>empty</bodycontent><bodycontent>empty</bodycontent> <attribute><attribute> <name>nome</name><name>nome</name> <required>true</required><required>true</required> <rtexprvalue>true</rtexprvalue><rtexprvalue>true</rtexprvalue> <<typetype>>java.lang.Stringjava.lang.String</</typetype>> </attribute></attribute> </tag></tag></taglib></taglib>
public class AloTag public class AloTag extends BodyTagSupportextends BodyTagSupport { { private String nome;private String nome; public void setNome (String nome) {public void setNome (String nome) { this.nome = nome;this.nome = nome; }} public int doEndTag () throws JspException {public int doEndTag () throws JspException {
try {try { pageContext.getOut().write("Alo, " + nome);pageContext.getOut().write("Alo, " + nome); }} catch (IOException e) {}catch (IOException e) {} return SKIP_BODY;return SKIP_BODY; }}
}}
EL (Expression EL (Expression Language)Language) Parâmetros de tags; reduz uso de Parâmetros de tags; reduz uso de
scriptletsscriptlets Sintaxe:Sintaxe:
${${varvar}} (= var)(= var) ${${var.x.yvar.x.y}} (= var.getX().getY())(= var.getX().getY())
Operadores extra; números e stringsOperadores extra; números e strings div, mod, and, or, not, eq, ne, lt, gt, le, ge, emptydiv, mod, and, or, not, eq, ne, lt, gt, le, ge, emptyEx.: Ex.: ${(10 mod 4 == 5) and empty x}${(10 mod 4 == 5) and empty x} ${(10 % 4 == 5) && x == null}${(10 % 4 == 5) && x == null}
EL (Expression EL (Expression Language)Language) Variáveis predefinidasVariáveis predefinidas
pageContext (servletContext, session, request, response)pageContext (servletContext, session, request, response) param, paramValuesparam, paramValues header, headerValuesheader, headerValues cookie, initParamcookie, initParam pageScope, requestScope, sessionScope, applicationScopepageScope, requestScope, sessionScope, applicationScope
Sintaxe Sintaxe [ ][ ] para acesso a variáveis para acesso a variáveis MapMap ( (get()get()))${header${header[["host""host"]]}}${pageScope.departamentos${pageScope.departamentos[[nomeDeptonomeDepto]]}}
JSTL (JSP Standard JSTL (JSP Standard TagLib)TagLib) JSR-52: Biblioteca padrão de tags para JSPJSR-52: Biblioteca padrão de tags para JSP Core:Core: Iteração, Condições, Output… Iteração, Condições, Output… FMT:FMT: Formatação, Internacionalização Formatação, Internacionalização SQL:SQL: Acesso a dados via JDBC Acesso a dados via JDBC XML:XML: Parsing, Xpath, XSLT Parsing, Xpath, XSLT Functions:Functions: Manipulação de strings Manipulação de strings
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %><%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html> <head><title>Demo de JSTL</title></head><html> <head><title>Demo de JSTL</title></head><body><body><sql:transaction<sql:transaction dataSource=“jdbc/MinhaDatabase"> dataSource=“jdbc/MinhaDatabase"> <sql:query<sql:query var=“produtos"> var=“produtos"> SELECT * FROM PRODUTOSELECT * FROM PRODUTO </sql:query></sql:query></sql:transaction></sql:transaction><h2>Componentes de Hardware</h2><h2>Componentes de Hardware</h2><table border="1"><table border="1"> <c:forEach<c:forEach var="row" items="${produtos.rowsByIndex}"> var="row" items="${produtos.rowsByIndex}"> <tr> <tr> <c:forEach<c:forEach var="col" items="${row}"> var="col" items="${row}"> <td><td><c:out<c:out value="${col}"/></td> value="${col}"/></td> </c:forEach></c:forEach> </tr></tr> </c:forEach></c:forEach></table></table></body></html></body></html>
JSTL: CoreJSTL: Core
<<c:outc:out value=" value="textotexto“/>“/> <<c:setc:set var=" var="nomenome" value="" value="valorvalor" scope="page|request|session|" scope="page|request|session|
application"/>application"/> <<c:removec:remove var=" var="nomenome" scope="page|request|session|application"/>" scope="page|request|session|application"/> <<c:catchc:catch var=" var="nomenome"> ... </c:catch>"> ... </c:catch> <<c:ifc:if test=" test="condiçãocondição" " var,scopevar,scope> ... </c:if>> ... </c:if> <<c:choosec:choose>> <<c:whenc:when test=" test="condiçãocondição">...</c:when>">...</c:when> <<c:otherwisec:otherwise>...</c:otherwise>>...</c:otherwise> </c:choose></c:choose>
JSTL: CoreJSTL: Core
<<c:forEachc:forEach var=" var="nomenome" items="" items="coleçãocoleção" " varStatus="varStatus="statusstatus" begin="" begin="nn" end="" end="nn" step="" step="nn">">
<<c:forTokensc:forTokens var=" var="nomenome" items="" items="stringstring" delims="" delims="sepsep" " varStatus="varStatus="statusstatus" begin="" begin="nn" end="" end="nn" step="" step="nn">">
<<c:importc:import url=" url="urlurl" charEncoding="" charEncoding="encodingencoding" " context="context="contextocontexto" varReader="" varReader="nomenome" " var,scopevar,scope>>
<<c:paramc:param name=" name="nomenome" value="" value="valorvalor"/>"/> <<c:urlc:url value=" value="urlurl" context="" context="contextocontexto" " var,scopevar,scope/>/> <<c:redirectc:redirect url=" url="urlurl" context="" context="contextocontexto" >" > <<c:paramc:param name=" name="nomenome" value="" value="valorvalor"/>"/>
JSTL: FormataçãoJSTL: Formatação
<<fmt:setTimeZonefmt:setTimeZone value=" value="timeZonetimeZone"/>"/> <<fmt:timeZonefmt:timeZone var,scope var,scope> > corpocorpo </fmt:timeZone> </fmt:timeZone> <<fmt:formatNumberfmt:formatNumber value=" value="valorvalor" " currencyCode="currencyCode="codecode" "
currencySymbol="currencySymbol="symbolsymbol" type="number|currency|percent" " type="number|currency|percent" var,scopevar,scope groupingUsed="groupingUsed="boolbool" pattern="" pattern="patternpattern" maxIntegerDigits="" maxIntegerDigits="nn" " minIntegerDigits="minIntegerDigits="nn" maxFractionDigits="" maxFractionDigits="nn" minFractionDigits="" minFractionDigits="nn"">>
<<fmt:parseNumberfmt:parseNumber value=" value="valorvalor" " parseLocale="parseLocale="localelocale"" type="number|currency|percent" integerOnly="type="number|currency|percent" integerOnly="boolbool" " var,scopevar,scope/>/>
JSTL: FormataçãoJSTL: Formatação
<fmt:formatDate value="data" type="{time|date|both}" dateStyle="{default|short|medium|long|full}" timeStyle="{default|short|medium|long|full}" pattern="pattern" timeZone="zona" var,scope/>
<fmt:parseDate value="data" type="{time|date|both}" dateStyle="{default|short|medium|long|full}" timeStyle="{default|short|medium|long|full}" var,scope pattern="pattern" timeZone="zona" parseLocale="locale"/>
JSTL: SQLJSTL: SQL
<sql:query sql="query" var="var" dataSource="nome" maxRows="max" startRow="start" var,scope>
<sql:param value="valor"/> </sql:query> <sql:update sql="update" dataSource="nome" var,scope>
params </sql:update> <sql:dateParam value="valor" type="timestamp|time|
date"/>
JSTL: SQLJSTL: SQL
<sql:transaction dataSource="nome" isolation="read_committed|read_uncommitted|repeatable_read|serializable"> ... </sql:tx>
<sql:setDataSource dataSource="nome" url="url" driver="classe" user="nome" password="pwd" var,scope/>
Mais taglibs...Mais taglibs...
JSTLJSTL XML (<x:...>)XML (<x:...>) Internacionalização (<fmt:...>)Internacionalização (<fmt:...>) Funções EL definidas pelo usuárioFunções EL definidas pelo usuário
JSR-128: JESI, JSP TagLib for Edge Side JSR-128: JESI, JSP TagLib for Edge Side IncludesIncludes
JSR-267: JSP TagLib for Web ServicesJSR-267: JSP TagLib for Web Services
DeploymentDeployment
AgendaAgenda
Pacotes jar, war, earPacotes jar, war, ear Deploy em servidores J2EEDeploy em servidores J2EE
Pacotes jar, war, earPacotes jar, war, ear
JAR: J2SEJAR: J2SE / / Classes, Resources Classes, Resources /META-INF/ /META-INF/ Manifest.MF Manifest.MF
WAR: J2EEWAR: J2EE / / Páginas (e subdiretórios) Páginas (e subdiretórios) /WEB-INF /WEB-INF Configurações, TLDs Configurações, TLDs /WEB-INF/classes /WEB-INF/classes Classes Classes /WEB-INF/lib /WEB-INF/lib JARs JARs /WEB-INF/tags /WEB-INF/tags tagfiles tagfiles
EAR: J2EE (EJB)EAR: J2EE (EJB)
Deploy em servidores Deploy em servidores J2EEJ2EE "Hot deploy", copiar WAR/EAR para diretório"Hot deploy", copiar WAR/EAR para diretório
Tomcat: /webappsTomcat: /webapps JBoss: server/JBoss: server/configconfig/deploy/deploy
DataSources: deploy de .XMLDataSources: deploy de .XML Outros (JBoss):Outros (JBoss):
RAR (Resource Adapter)RAR (Resource Adapter) SAR (Service)SAR (Service)
Deploy "explodido" (opcional / debug)Deploy "explodido" (opcional / debug) Ferramentas GUI de Deploy: overridesFerramentas GUI de Deploy: overrides
StrutsStruts
AgendaAgenda
Model (forms)Model (forms) ViewView Controller (actions)Controller (actions) ConfiguraçãoConfiguração TaglibsTaglibs TilesTiles ValidaçãoValidação
Controller
ModelView
Requisição Envio de Dados
Resposta do Envio de dados
Seleção do Visualizador
Resposta
ViewView
Página JSP "amarrada" à StrutsPágina JSP "amarrada" à Struts <html:form action> <html:form action> Action (Controller) Action (Controller) Campos Campos Form (View) Form (View)
ControllerController
Herda Herda ActionAction Predefinidas: Tiles, Download, Forward, Predefinidas: Tiles, Download, Forward,
Include...Include...
Implementar Implementar execute()execute() Uma ou mais actions: Uma ou mais actions: request.getParameter("action")request.getParameter("action") Dispara alguma ação de negócioDispara alguma ação de negócio Determina próxima página (forward)Determina próxima página (forward)
DispatchActionDispatchAction: implementar métodos : implementar métodos similares ao execute(), mas com nome similares ao execute(), mas com nome igual à da açãoigual à da ação
ConfiguraçãoConfiguração
WEB-INF/struts-config.xmlWEB-INF/struts-config.xml Mapeamento MVC, page flowMapeamento MVC, page flow
WEB-INF/web.xmlWEB-INF/web.xml Configuração padrão da Struts, ex.: Configuração padrão da Struts, ex.:
ActionServletActionServlet
WEB-INF/: Outros arquivos da StrutsWEB-INF/: Outros arquivos da Struts WEB-INF/lib: Binários da StrutsWEB-INF/lib: Binários da Struts WEB-INF/.struts-config.mex: Layout visual WEB-INF/.struts-config.mex: Layout visual
para o struts-config.xml (MyEclipse)para o struts-config.xml (MyEclipse)
public class ContatoForm extends ActionFormpublic class ContatoForm extends ActionForm { { private String nome=""private String nome="",, sobrenome="" sobrenome="", , email=""email="",, fone="" fone="", , warning="";warning=""; public String getNome () {public String getNome () { return nome; }return nome; } public void setNome (String nome) { this.nome = nome; }public void setNome (String nome) { this.nome = nome; } // Omitido: outros getters/setters// Omitido: outros getters/setters
public String valida () {public String valida () { if (nome == null || nome.length() == 0) return "nome";if (nome == null || nome.length() == 0) return "nome"; if (sobrenome == null || sobrenome.length() == 0) return if (sobrenome == null || sobrenome.length() == 0) return
"sobrenome";"sobrenome"; if (email == null || email.length() == 0 ||if (email == null || email.length() == 0 || email.indexOf('@') == -1) return "email";email.indexOf('@') == -1) return "email"; if (fone == null || fone.length() == 0) return "fone";if (fone == null || fone.length() == 0) return "fone"; return null;return null; }}}}
public class MessageBean {public class MessageBean { private String message = "";private String message = ""; public String getMessage () {public String getMessage () { return message;return message; }} public void setMessage (String message) {public void setMessage (String message) { this.message = message;this.message = message; }}}}
public class AssinaAction extends Action {public class AssinaAction extends Action { public ActionForward execute (ActionMapping map,public ActionForward execute (ActionMapping map,
ActionForm aForm, HttpServletRequest req,ActionForm aForm, HttpServletRequest req,
HttpServletResponse resp) throws ExceptionHttpServletResponse resp) throws Exception { { ContatoForm form = (ContatoForm)aForm;ContatoForm form = (ContatoForm)aForm; String campoRuim = form.valida();String campoRuim = form.valida(); if (campoRuim != null) {if (campoRuim != null) { warn(req, campoRuim);warn(req, campoRuim); return map.findForward("valor-errado");return map.findForward("valor-errado"); }} else return map.findForward("sucesso");else return map.findForward("sucesso"); }} protected void warnprotected void warn (HttpServletRequest req, String msg) {(HttpServletRequest req, String msg) { MessageBean msgBean = new MessageBean();MessageBean msgBean = new MessageBean(); msgBean.setMessage(msg);msgBean.setMessage(msg); req.setAttribute("messageBean", msgBean);req.setAttribute("messageBean", msgBean); }}}}
assina.jsp:assina.jsp:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><html><head><title>Assinatura</title></head><html><head><title>Assinatura</title></head><body><h1 align="center">Assinatura</h1><body><h1 align="center">Assinatura</h1>Digite seus dados de contato para receber nossa Newsletter!<p/>Digite seus dados de contato para receber nossa Newsletter!<p/><center><center><<html:formhtml:form action="/assina"> action="/assina"> <table><table> <tr><td>Nome:</td><td><<tr><td>Nome:</td><td><html:texthtml:text property="nome"/></td></tr> property="nome"/></td></tr> <tr><td>Sobrenome:</td><td><<tr><td>Sobrenome:</td><td><html:texthtml:text property="sobrenome"/></td></tr> property="sobrenome"/></td></tr> <tr><td>Email:</td><td><<tr><td>Email:</td><td><html:texthtml:text property="email"/></td></tr> property="email"/></td></tr> <tr><td>Fone:</td><td><<tr><td>Fone:</td><td><html:texthtml:text property="fone"/></td></tr> property="fone"/></td></tr> </table></table> <<html:submithtml:submit value="Assine!"/> value="Assine!"/></html:form></html:form></center></center></body></html></body></html>
confirma.jsp: (Usando taglib Struts Beans – confirma.jsp: (Usando taglib Struts Beans – NÃO PROGRAMAR ASSIM!!!NÃO PROGRAMAR ASSIM!!!))
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><html><head><title>Confirmação</title></head><html><head><title>Confirmação</title></head><body><center><h1>Confirmação</h1><body><center><h1>Confirmação</h1>Muito obrigado, prepare seu Inbox para nosso spam!Muito obrigado, prepare seu Inbox para nosso spam!<table><table> <tr><td>Nome:</td><tr><td>Nome:</td> <td><<td><bean:writebean:write name="contatoForm" property="nome"/></td></tr> name="contatoForm" property="nome"/></td></tr> <tr><td>Sobrenome:</td><tr><td>Sobrenome:</td> <td><<td><bean:writebean:write name="contatoForm" property="sobrenome"/></td></tr> name="contatoForm" property="sobrenome"/></td></tr> <tr><td>Email:</td><tr><td>Email:</td> <td><<td><bean:writebean:write name="contatoForm" property="email"/></td></tr> name="contatoForm" property="email"/></td></tr> <tr><td>Fone:</td><tr><td>Fone:</td> <td><<td><bean:writebean:write name="contatoForm" property="fone"/></td></tr> name="contatoForm" property="fone"/></td></tr></table></table></center></center></body></html></body></html>
confirma.jsp: (Usando taglib JSTL Core – confirma.jsp: (Usando taglib JSTL Core – FAZER DESSA MANEIRA!!!FAZER DESSA MANEIRA!!!))
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><head><title>Confirmação</title></head><html><head><title>Confirmação</title></head><body><center><h1>Confirmação</h1><body><center><h1>Confirmação</h1>Muito obrigado, prepare seu Inbox para nosso spam!Muito obrigado, prepare seu Inbox para nosso spam!<table><table> <tr><td>Nome:</td><tr><td>Nome:</td> <td><<td><c:outc:out valuevalue="="${${contatoFormcontatoForm..nomenome}}"/></td></tr>"/></td></tr> <tr><td>Sobrenome:</td><tr><td>Sobrenome:</td> <td><<td><c:outc:out valuevalue="="${${contatoFormcontatoForm..sobrenomesobrenome}}"/></td></tr>"/></td></tr> <tr><td>Email:</td><tr><td>Email:</td> <td><<td><c:outc:out valuevalue="="${${contatoFormcontatoForm..emailemail}}"/></td></tr>"/></td></tr> <tr><td>Fone:</td><tr><td>Fone:</td> <td><<td><c:outc:out valuevalue="="${${contatoFormcontatoForm..fonefone}}"/></td></tr>"/></td></tr></table></table></center></center></body></html></body></html>
valor-errado.jsp:valor-errado.jsp:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><html><head><title>Valor faltando ou incorreto<head><title>Valor faltando ou incorreto!!</title></head></title></head><body><center><body><center><h2>Valor faltando ou incorreto: <c:out value="${messageBean.message}"/>!</h2><h2>Valor faltando ou incorreto: <c:out value="${messageBean.message}"/>!</h2>Por favor, <a href="assina.jsp">Tente novamente</a>.Por favor, <a href="assina.jsp">Tente novamente</a>.</center></center></body></html></body></html>
assina2.jsp:assina2.jsp:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><html><head><title>Assinatura</title></head><html><head><title>Assinatura</title></head><body><h1 ALIGN="CENTER">Assinatura</h1><body><h1 ALIGN="CENTER">Assinatura</h1>Digite seus dados de contato para receber nossa Newsletter!<p/><center>Digite seus dados de contato para receber nossa Newsletter!<p/><center><html:form action="/assina2"><html:form action="/assina2"> <c:if test="${not empty contatoForm.warning}"><c:if test="${not empty contatoForm.warning}"> Campo faltando ou inválido:Campo faltando ou inválido: <bean:write name="contatoForm" property="warning" filter="false"/><bean:write name="contatoForm" property="warning" filter="false"/> </c:if></c:if> <table><table> <tr><td>Nome:</td><td><html:text property="nome"/></td></tr><tr><td>Nome:</td><td><html:text property="nome"/></td></tr> <tr><td>Sobrenome:</td><td><html:text property="sobrenome"/></td></tr><tr><td>Sobrenome:</td><td><html:text property="sobrenome"/></td></tr> <tr><td>Email:</td><td><html:text property="email"/></td></tr><tr><td>Email:</td><td><html:text property="email"/></td></tr> <tr><td>Fone:</td><td><html:text property="fone"/></td></tr><tr><td>Fone:</td><td><html:text property="fone"/></td></tr> </table></table> <html:submit value="Assine!"/><html:submit value="Assine!"/></html:form></center></body></html></html:form></center></body></html>
struts-config.xml:struts-config.xml:
<struts-config> <struts-config> <form-beans> <form-beans> <form-bean name="contatoForm" type="ContatoForm"/><form-bean name="contatoForm" type="ContatoForm"/> </form-beans></form-beans> <global-forwards><global-forwards> <forward name="sucesso" path="/confirma.jsp"/><forward name="sucesso" path="/confirma.jsp"/> </global-forwards></global-forwards> <action-mappings><action-mappings> <action path="/assina" type="AssinaAction" name="contatoForm" scope="request"><action path="/assina" type="AssinaAction" name="contatoForm" scope="request"> <forward name="valor-errado" path="/valor-errado.jsp"/><forward name="valor-errado" path="/valor-errado.jsp"/> </action></action> <action path="/assina2" type="AssinaAction2" name="contatoForm" <action path="/assina2" type="AssinaAction2" name="contatoForm"
scope="request">scope="request"> <forward name="valor-errado" path="/assina2.jsp"/><forward name="valor-errado" path="/assina2.jsp"/> </action></action> </action-mappings></action-mappings></struts-config></struts-config>
Struts TaglibsStruts Taglibs
Struts inclui várias taglibs:Struts inclui várias taglibs: Bean, Logic Bean, Logic (maior parte obsoleta; usar JSTL)(maior parte obsoleta; usar JSTL) HTML: Gera elementos, útil para formsHTML: Gera elementos, útil para formshttp://struts.apache.org/userGuide/struts-
html.html Nested: Relacionamentos entre tags (pai/filho)Nested: Relacionamentos entre tags (pai/filho) Utilities: DiversosUtilities: Diversos TilesTiles
TilesTiles
Taglib da StrutsTaglib da Struts Permite compor páginas complexas, Permite compor páginas complexas,
juntando fragmentos (tiles) reutilizáveisjuntando fragmentos (tiles) reutilizáveis Como Como <jsp:include><jsp:include>, mas mais flexível e , mas mais flexível e
estruturadoestruturado
Facilidade de templateFacilidade de template Separa estrutura, layout e componentesSepara estrutura, layout e componentes Permite recombinar estes elementos facilmentePermite recombinar estes elementos facilmente
http://struts.apache.org/userGuide/dev_tiles.html
Tiles: PreparandoTiles: Preparando
Configuração do struts-config.xml:(copiar do struts-blank.war)
<controller processorClass= "org.apache.struts.tiles.TilesRequestProcessor"/><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>
Tiles: PlanejandoTiles: Planejando
Comece planejando seu layout "master"...Comece planejando seu layout "master"...
Cabeçalho
Corpo
Menu
Rodapé
Tiles: PlanejandoTiles: Planejando
Defina estrutura de página/layout/fragmentosDefina estrutura de página/layout/fragmentos
Cabeçalho CorpoMenu Rodapé
layout
página1 página2 página3
Tiles: Implementando Tiles: Implementando PáginaPágina(instancia/parametriza o (instancia/parametriza o layout)layout)pagina1.jsp:pagina1.jsp:
<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %><%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <<tiles:inserttiles:insert page="/layout.jsp" flush="true"> page="/layout.jsp" flush="true"> <<tiles:puttiles:put name="titulo" value=" name="titulo" value="Página 1Página 1"/>"/> <<tiles:puttiles:put name="cabecalho" value="/ name="cabecalho" value="/cabecalho.htmlcabecalho.html"/>"/> <<tiles:puttiles:put name="menu" value="/ name="menu" value="/menu.jspmenu.jsp"/>"/> <<tiles:puttiles:put name="rodape" value="/ name="rodape" value="/rodape.jsprodape.jsp"/>"/> <<tiles:puttiles:put name="corpo" value=" name="corpo" value="/corpo1.jsp/corpo1.jsp"/>"/></tiles:insert></tiles:insert>
Tiles: Implementando Tiles: Implementando LayoutLayoutlayout.jsp:layout.jsp:
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %><%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <html><head><html><head> <title><title><tiles:getAsString<tiles:getAsString name="titulo"/></title></head> name="titulo"/></title></head> <body><table width="100%"><body><table width="100%"> <tr><td colspan="2"><<tr><td colspan="2"><tiles:inserttiles:insert attribute="cabecalho"/></td></tr> attribute="cabecalho"/></td></tr> <tr><td width="120"><<tr><td width="120"><tiles:inserttiles:insert attribute="menu"/></td> attribute="menu"/></td> <td><<td><tiles:inserttiles:insert attribute="corpo"/></td></tr> attribute="corpo"/></td></tr> <tr><td colspan="2"><<tr><td colspan="2"><tiles:inserttiles:insert attribute="rodape"/></td></tr> attribute="rodape"/></td></tr></ table></body></html></ table></body></html>
Tiles: Implementando Tiles: Implementando os Tilesos Tiles JSPs, HTMLs ou imagens, normaisJSPs, HTMLs ou imagens, normais Exemplo: cabecalho.htmlExemplo: cabecalho.html
<a href="http://www.companhia.com"><a href="http://www.companhia.com"> <img src="/BannerEsq.gif" align="left" border="0"><img src="/BannerEsq.gif" align="left" border="0"></a></a><img src="/BannerDir.gif" align="right" border="0"><img src="/BannerDir.gif" align="right" border="0">
Tiles: Usando Tiles: Usando DefinitionsDefinitions Especificação declarativa das Especificação declarativa das
páginaspáginas Suporta herança de páginasSuporta herança de páginas JSPs de página reduzidas 1 insertJSPs de página reduzidas 1 insert:<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %><tiles:insert definition="pagina2.page" flush="true"/> Ainda mais facilidade para sites dinâmicos
JSP pode decidir entre várias definitions
Tiles-defs.xml:Tiles-defs.xml:<?xml version="1.0" encoding="ISO-8859-1" ?><?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN""-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">"http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd"><tiles-definitions><tiles-definitions>
<definition name=".layoutBase" path="/layout.jsp"><definition name=".layoutBase" path="/layout.jsp"> <put name="titulo" value=""/><put name="titulo" value=""/> <put name="cabecalho" value="cabecalho.html"/><put name="cabecalho" value="cabecalho.html"/> <put name="menu" value="menu.jsp"/><put name="menu" value="menu.jsp"/> <put name="rodape" value="rodape.jsp"/><put name="rodape" value="rodape.jsp"/> <put name="corpo" value=""/><put name="corpo" value=""/></definition></definition>
<definition name="pagina1.page" extends=".layoutBase" ><definition name="pagina1.page" extends=".layoutBase" > <put name="titulo" value="Página 2"/><put name="titulo" value="Página 2"/> <put name="corpo" value="corpo2.jsp"/><put name="corpo" value="corpo2.jsp"/>
</definition></definition></tiles-definitions></tiles-definitions>
pagina3.jsp
layout.jsp
(titulo="Página 3")
cabecalho.html
corpo3.jsp
menu.js
p
rodape.jsp
pagina2.jsp
layout.jsp
(titulo="Página 2")
cabecalho.html
corpo2.jsp
menu.js
p
rodape.jsp
pagina1.jsp
layout.jsp
(titulo="Página 1")
cabecalho.html
corpo1.jsp
menu.js
p
rodape.jsp
ValidaçãoValidação
Opções de validaçãoOpções de validação Sem Validator: ad-hocSem Validator: ad-hoc Validação Manual (ou semi-automática)Validação Manual (ou semi-automática) Validação AutomáticaValidação Automática
Código de validação, onde?Código de validação, onde? Form (e/ou JavaScript): Só regras encapsuláveis Form (e/ou JavaScript): Só regras encapsuláveis
no bean; ex.: formato de string; valores mín/máxno bean; ex.: formato de string; valores mín/máx Action: Acesso à lógica de negócio, database, etc.Action: Acesso à lógica de negócio, database, etc.
http://struts.apache.org/userGuide/dev_validator.html
Validação ManualValidação Manual
Implementar Implementar ActionForm.validate()ActionForm.validate()public ActionErrors validatepublic ActionErrors validate (( ActionMapping map, HttpServletRequest req) {ActionMapping map, HttpServletRequest req) { ActionErrors ae = super.validate(map, req);ActionErrors ae = super.validate(map, req); if (ae == null) ae = new ActionErrors();if (ae == null) ae = new ActionErrors(); if (if (......)) ae.add("ae.add("nomenome", new Action", new ActionMessageMessage("("contatoForm.nomecontatoForm.nome"));")); if (if (......)) ae.add("ae.add("emailemail", new Action", new ActionMessageMessage("("contatoForm.emailcontatoForm.email"));")); ... ... return ae;return ae;}}
Detecte todos os erros, não só o primeiro!Detecte todos os erros, não só o primeiro!
struts-config.xml:struts-config.xml:
<action path="/assina" type="AssinaAction" <action path="/assina" type="AssinaAction" name="contatoForm" scope="request" name="contatoForm" scope="request" input="/assina.jsp" validate="true"input="/assina.jsp" validate="true">></action></action><message-resources<message-resources parameter="MessageResources" null="false"/>parameter="MessageResources" null="false"/>
WEB-INF/classes/MessageResources.properties:WEB-INF/classes/MessageResources.properties:
contatoForm.nome=Nome não pode ser vaziocontatoForm.nome=Nome não pode ser vaziocontatoForm.email=Email deve ter formato "conta@host"contatoForm.email=Email deve ter formato "conta@host"
assina.jsp:assina.jsp:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><html><head><title>Assinatura</title></head><html><head><title>Assinatura</title></head><body><h1 align="center">Assinatura</h1><body><h1 align="center">Assinatura</h1>Digite seus dados de contato para receber nossa Newsletter!<p/>Digite seus dados de contato para receber nossa Newsletter!<p/><center><center><html:form action="/assina"><html:form action="/assina"> <table><table> <html:errors/><html:errors/> <tr><td>Nome:</td><td><html:text property="nome"/></td></tr><tr><td>Nome:</td><td><html:text property="nome"/></td></tr> <tr><td>Sobrenome:</td><td><html:text property="sobrenome"/></td></tr><tr><td>Sobrenome:</td><td><html:text property="sobrenome"/></td></tr> <tr><td>Email:</td><td><html:text property="email"/></td></tr><tr><td>Email:</td><td><html:text property="email"/></td></tr> <tr><td>Fone:</td><td><html:text property="fone"/></td></tr><tr><td>Fone:</td><td><html:text property="fone"/></td></tr> </table></table> <html:submit value="Assine!"/><html:submit value="Assine!"/></html:form></html:form></center></center></body></html></body></html>
public class AssinaAction extends Action {public class AssinaAction extends Action { public ActionForward execute (ActionMapping map,public ActionForward execute (ActionMapping map, ActionForm aForm, HttpServletRequest req,ActionForm aForm, HttpServletRequest req, HttpServletResponse resp) throws Exception {HttpServletResponse resp) throws Exception { // Se chegou até aqui, é porque o Struts já// Se chegou até aqui, é porque o Struts já
// executou a validação com sucesso!// executou a validação com sucesso!
return map.findForward("sucesso");return map.findForward("sucesso");
}}}}
Validação AutomáticaValidação Automática
Validação declarada em arquivo XMLValidação declarada em arquivo XML Validação Server-Side (Validator), Validação Server-Side (Validator),
obrigatóriaobrigatória Mais segura, não contornável pelo usuárioMais segura, não contornável pelo usuário
Validação Client-Side (JavaScript), Validação Client-Side (JavaScript), opcionalopcional Mais eficiente, evita request ao servidor e Mais eficiente, evita request ao servidor e
refreshrefresh
struts-config.xml:struts-config.xml:
<plug-in<plug-in className="org.apache.struts.validator.ValidatorPlugIn">className="org.apache.struts.validator.ValidatorPlugIn"><set-property property="pathnames"<set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/>value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/></plug-in></plug-in>
validator-rules.xmlvalidator-rules.xml,, validation.xml validation.xml: extraia do : extraia do struts-blank.warstruts-blank.war
WEB-INF/classes/MessageResources.properties:WEB-INF/classes/MessageResources.properties:
# Mensagens-padrão (copiar do comentário no validator-rules.xml):# Mensagens-padrão (copiar do comentário no validator-rules.xml):errors.required={0} é obrigatório.errors.required={0} é obrigatório.errors.minlength={0} não pode ter menos que {1} caracteres.errors.minlength={0} não pode ter menos que {1} caracteres.......
validation.xml:validation.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?><?xml version="1.0" encoding="ISO-8859-1" ?><!DOCTYPE form-validation PUBLIC<!DOCTYPE form-validation PUBLIC"-//Apache Software Foundation//DTD Commons Validator Rules Configuration "-//Apache Software Foundation//DTD Commons Validator Rules Configuration
1.1.3//EN" "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">1.1.3//EN" "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd"><form-validation><form-validation><formset><formset><form name="contatoForm"><form name="contatoForm"> <field property="nome" depends="required"><arg key="contatoForm.nome"/></field><field property="nome" depends="required"><arg key="contatoForm.nome"/></field> <field property="sobrenome" depends="required"><field property="sobrenome" depends="required"> <arg key="contatoForm.sobrenome"/> </field><arg key="contatoForm.sobrenome"/> </field> <field property="email" depends="required,mask"><field property="email" depends="required,mask"> <arg key="contatoForm.email"/><arg key="contatoForm.email"/> <var><var> <var-name>mask</var-name><var-name>mask</var-name> <var-value>^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$</var-value><var-value>^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$</var-value> </var></var> </field></field> <field property="fone" depends="required"> <arg key="contatoForm.fone"/> </field><field property="fone" depends="required"> <arg key="contatoForm.fone"/> </field></form></form></form-validation></form-validation>
assina.jsp:assina.jsp:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><html><head><title>Assinatura</title></head><html><head><title>Assinatura</title></head><body><h1 align="center">Assinatura</h1><body><h1 align="center">Assinatura</h1><p align="center"><p align="center">Digite seus dados de contato para receber nossa Newsletter!<Digite seus dados de contato para receber nossa Newsletter!<//p>p><center><center><html:form action="/assina" <html:form action="/assina" onsubmit="return validateonsubmit="return validateContatoFormContatoForm(this);(this);">"> <table><table> <tr><td>Nome:</td><td><html:text property="nome"/><tr><td>Nome:</td><td><html:text property="nome"/> <html:errors property="nome"/><html:errors property="nome"/></td></tr></td></tr> <tr><td>Sobrenome:</td><td><html:text property="sobrenome"/><tr><td>Sobrenome:</td><td><html:text property="sobrenome"/> <html:errors property="<html:errors property="sobresobrenome"/>nome"/> </td></tr></td></tr> <tr><td>Email:</td><td><html:text property="email"/><tr><td>Email:</td><td><html:text property="email"/> <html:errors property="email"/><html:errors property="email"/> </td></tr></td></tr> <tr><td>Fone:</td><td><html:text property="fone"/><tr><td>Fone:</td><td><html:text property="fone"/> <html:errors property="<html:errors property="fonefone"/>"/> </td></tr></td></tr> </table></table> <html:submit value="Assine!"/><html:submit value="Assine!"/></html:form></html:form><html:javascript <html:javascript
formName="formName="contatocontatoForm"/>Form"/></center></body></html></center></body></html>
public class ContatoForm public class ContatoForm extends ValidatorFormextends ValidatorForm { { private String nome="";private String nome=""; private String sobrenome="";private String sobrenome=""; private String email="";private String email=""; private String fone="";private String fone=""; public String getNome () { return nome; }public String getNome () { return nome; } public void setNome (String nome) { this.nome = nome; }public void setNome (String nome) { this.nome = nome; } public String getSobrenome () { return sobrenome; }public String getSobrenome () { return sobrenome; } public void setSobrenome (String sn) {this.sobrenome = sn;}public void setSobrenome (String sn) {this.sobrenome = sn;} public String getEMail () { return email; }public String getEMail () { return email; } public void setEMail (String email) { this.email = email; }public void setEMail (String email) { this.email = email; } public String getFone () { return fone; }public String getFone () { return fone; } public void setFone (String nome) { this.fone = fone; }public void setFone (String nome) { this.fone = fone; }}} // Nenhum código de validação!// Nenhum código de validação!
Validação no Validação no ServidorServidor
Validação no Validação no ClienteCliente
Validação: CapacidadesValidação: Capacidades
Validações predefinidas:Validações predefinidas:required, requiredif, validwhen, minlength, maxlengthrequired, requiredif, validwhen, minlength, maxlengthmask, creditCard, email, urlmask, creditCard, email, urlinteger, float, double, long, short, byte, dateinteger, float, double, long, short, byte, dateintRange, longRange, floatRange, doubleRangeintRange, longRange, floatRange, doubleRange
Definições globais (constantes)Definições globais (constantes) Validadores plugáveisValidadores plugáveis Validação Híbrida (Manual + Automática)Validação Híbrida (Manual + Automática)