desenvolvimento java para web osvaldo pinali doederlein visionnaire

144
Desenvolvimento Java para Web Desenvolvimento Java para Web Osvaldo Pinali Doederlein Osvaldo Pinali Doederlein Visionnaire Visionnaire

Upload: internet

Post on 17-Apr-2015

114 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Desenvolvimento Java para Desenvolvimento Java para WebWeb

Osvaldo Pinali DoederleinOsvaldo Pinali Doederlein

VisionnaireVisionnaire

Page 2: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Introdução à Introdução à PlataformaPlataforma

J2EE 1.4J2EE 1.4

Page 3: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

ContainersContainers Padrões JCPPadrões JCP Servidores de AplicaçãoServidores de Aplicação

Page 4: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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...

Page 5: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 6: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 7: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 8: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 9: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 10: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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)

Page 11: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 12: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 13: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 14: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 15: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 16: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Design Patterns para Design Patterns para J2EEJ2EE

Page 17: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

Design PatternsDesign Patterns SingletonSingleton FaçadeFaçade FactoryFactory DAODAO MVCMVC

Page 18: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 19: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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”

Page 20: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Singleton: EstruturaSingleton: Estrutura

Singleton

-singletonInstance...

«constructor»-Singleton( )«misc»+getInstance( )...

Page 21: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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();

Page 22: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 23: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Façade: EstruturaFaçade: Estrutura

Cliente

Façade

Usa1

*

Page 24: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Façade (Session / J2EE)Façade (Session / J2EE)

Page 25: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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);

Page 26: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 27: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Factory Method: Factory Method: EstruturaEstrutura

Page 28: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 29: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Abstract Factory: Abstract Factory: EstruturaEstrutura

Page 30: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

// 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);

Page 31: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 32: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

DAO: EstruturaDAO: Estrutura

Page 33: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

}}

Page 34: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 35: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

MVC-2: EstruturaMVC-2: Estrutura

Controller

ModelView

Requisição Envio de Dados

Resposta do Envio de dados

Seleção do Visualizador

Resposta

Page 36: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

<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

Page 37: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 38: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

LoggingLogging

Page 39: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

Log4JLog4J java.util.loggingjava.util.logging

Page 40: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 41: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 42: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 43: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 44: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 45: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 46: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 47: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

JDBCJDBC

Page 48: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

JDBC APIJDBC API

J2EE/DataSourcesJ2EE/DataSources

Page 49: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 50: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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) {}}}

Page 51: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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();

Page 52: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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();

Page 53: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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();

Page 54: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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!!

Page 55: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 56: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 57: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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();

Page 58: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Testes UnitáriosTestes Unitários

Page 59: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

Testes UnitáriosTestes Unitários JUnitJUnit

Page 60: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 61: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 62: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 63: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 64: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 65: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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) {}} }}}}

Page 66: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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}; }}}}

Page 67: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

ServletsServlets

Page 68: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

ServletServlet InicializaçãoInicialização FiltrosFiltros RedirecionamentoRedirecionamento SessõesSessões CookiesCookies

Page 69: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/

Page 70: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 71: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>"); }}}}

Page 72: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 73: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 74: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 75: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 76: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 77: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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);

Page 78: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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)

Page 79: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

JSPJSP

Page 80: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

JSPJSP TaglibsTaglibs Expression LanguageExpression Language JSTLJSTL

Page 81: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 82: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 83: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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"/>"/>

Page 84: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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 85: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

<%@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>

Page 86: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 87: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

<?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>

Page 88: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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; }}

}}

Page 89: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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}

Page 90: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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]]}}

Page 91: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 92: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

<%@ 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>

Page 93: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 94: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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"/>"/>

Page 95: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/>/>

Page 96: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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"/>

Page 97: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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"/>

Page 98: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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/>

Page 99: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 100: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

DeploymentDeployment

Page 101: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

Pacotes jar, war, earPacotes jar, war, ear Deploy em servidores J2EEDeploy em servidores J2EE

Page 102: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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)

Page 103: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 104: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 105: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

StrutsStruts

Page 106: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

AgendaAgenda

Model (forms)Model (forms) ViewView Controller (actions)Controller (actions) ConfiguraçãoConfiguração TaglibsTaglibs TilesTiles ValidaçãoValidação

Page 107: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Controller

ModelView

Requisição Envio de Dados

Resposta do Envio de dados

Seleção do Visualizador

Resposta

Page 108: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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)

Page 109: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 110: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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)

Page 111: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire
Page 112: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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; }}}}

Page 113: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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; }}}}

Page 114: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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); }}}}

Page 115: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 116: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 117: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 118: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 119: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 120: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 121: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 122: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 123: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 124: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Tiles: PlanejandoTiles: Planejando

Comece planejando seu layout "master"...Comece planejando seu layout "master"...

Cabeçalho

Corpo

Menu

Rodapé

Page 125: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 126: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 127: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 128: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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">

Page 129: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 130: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 131: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 132: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 133: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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!

Page 134: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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"

Page 135: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 136: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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");

}}}}

Page 137: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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

Page 138: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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.......

Page 139: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 140: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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>

Page 141: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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!

Page 142: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Validação no Validação no ServidorServidor

Page 143: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Validação no Validação no ClienteCliente

Page 144: Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

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)