Desenvolvimento Java para Web

Slides:



Advertisements
Apresentações semelhantes
Aplicação de exemplo Struts Aplicação de exemplo
Advertisements

JBanana.
ARQUITETURA EM CAMADAS
UNIPAC – ARAGUARI CAMPUS – IX PROF. EVERTON HIPÓLITO DE FREITAS
Framework para desenvolvimento web
JSP Segundo Semestre – 2008 Professor Glaucio Bianchini
Prof. Alessandro J. de Souza
Java Conexão com Banco de Dados
Modelo Cliente-Servidor
Desenvolvimento Web em Java com Java Server Faces (JSF)
Projeto de Sistemas de Software
Projeto de Sistemas de Software
Linguagens de Programação Orientadas a Objetos
Jakarta Struts 1.1 Ago/2006 Softplan/Poligraph Alessandro Lemser
Aplicações para Web.
WebWork e JSP Keven andrade
Introdução a JDBC Eduardo Martins Guerra Instituto Tecnológico de Aeronáutica Curso de Pós-Graduação em Engenharia de Software Programação Distribuída.
Introdução a EJB 3.0 Eduardo Martins Guerra Instituto Tecnológico de Aeronáutica Curso de Pós-Graduação em Engenharia de Software Programação Distribuída.
Geração Dinâmica de Páginas com JSP Eduardo Martins Guerra Instituto Tecnológico de Aeronáutica Curso de Pós-Graduação em Engenharia de Software Programação.
Desenvolvimento de Soluções WEB Escopos de uma Aplicação Web
EL e JSTL Prof. Danton Cavalcanti Franco Junior
JAVA - Struts
Java & Bancos de Dados Universidade Salgado de Oliveira Goiânia
Aplicativos Web Com Orientação a Objetos
Acesso a Base de Dados JDBC Trabalho Realizado por:
Desenvolvimento WEB I Camila Nunes
JAVA - Struts
Conexão com Bancos de Dados Carlos Bazilio Depto de Ciência e Tecnologia Pólo Universitário de Rio das Ostras Universidade Federal Fluminense.
Capítulo 2 Java Servlets.
Filtros. O que são Filtros Um filtro é um componente Web que reside no servidor Intercepta as requisições e respostas no seu caminho até o servlet e de.
Integração com Banco de Dados
Aplicativos Comerciais para Internet Camada View do MVC Apresentando os resultados de uma Consulta.
JSP / Servlets Avançado
JAVA - Struts. AULA 3.
Introdução ao Hibernate
Struts Java avançado – PCC Jobson Ronan
Tópicos Avançados em Sistemas Distribuídos
Aula 2 – Primeiros Passos com a arquitetura Web Servidor
Java para Web com Struts
1 Servlet Prof. Alexandre Monteiro Recife. Contatos n Prof. Guilherme Alexandre Monteiro Reinaldo n Apelido: Alexandre Cordel n /gtalk:
JDBC Java Database Connectivity. JDBC Especificação para uso de base de dados em aplicações e applets JAVA; API para uso de drivers JDBC; Compatível com.
JSP / Servlets Avançado
The Factory Esclarecendo a arquitetura utilizada no projeto Piloto Autor: Wabber Filho.
Unidade III JBoss O servidor JBoss Aula 2.
Aula 2 – Primeiros Passos com a arquitetura Web Servidor Instituto Metodista Izabela Hendrix Curso de Tecnologia em Análise e Desenvolvimento de Sistemas.
Configuração do Ambiente de programação
Arquitetura das JSP - Aula 2
Implementação MVC Pedro Antonino.
Aplicações Web com Orientação a Objetos
Conceitos da arquitetura
Java Kickstart, day 2 Semelhanças com linguagem C.
Introdução a JEE Marco A. S. Reis Arquiteto de Software Abril/2011.
Programação para Web Unidade 06 – Java Beans e BDs Prof.: Henrique Santos.
Padrões de Interação com o Usuário
Unidade 1 – Introdução a J2EE Prof.: Henrique Santos
Ultimos recursos Jobson Ronan
Java Conexão com Baco de dados Saulo Bazzi Oberderfer Fonte:
JavaServer Faces Rapid Web Application Development em Java Ricardo Cavalcanti Jobson Ronan
JSP – Mais Recursos Jobson Ronan
Unidade 5 – Integrando JSP e Servlets Prof.: Henrique Santos
Programação Distribuída em Java Aula Na aula passada vimos: TomCat –Instalação e configuração –Criação de contexto JSP... uma introdução –Expressões.
Projeto Supervisionado no Desenvolvimento de Aplicações Profissionais na Web Servidores.
Leo Silva Leonardo Murta Luiz Viana Persistência em Java.
Universidade Federal de Sergipe Departamento de Sistemas de Informação Bruno Cruz Jessica Rodrigo Aragão – ASP.NET MVC 3.
UCSal – Tecnologia em Análise e Desenvolvimento de Sistemas Programação para Aplicações WEB Profa. Semíramis Assis
UCSal – Tecnologia em Análise e Desenvolvimento de Sistemas Programação para Aplicações WEB Profa. Semíramis Assis
O que é? Um framework para facilitar a implementação de uma arquitetura MVC em aplicações web Oferece  Um servlet controlador configurável ( Front Controller.
Desenvolvimento WEB II Professora: Kelly de Paula Cunha Apresentação baseada no material didático elaborado pelo Prof. Pasteur Ottoni de Miranda Junior.
Apache Struts 1. Idéias principais Model View Controller Front Controller Action Mapping Form Beans Struts Tags Plugins Desenvolvimento web com Java #
ALUNO: RONI FABIO BANASZEWSKI Model-View-Controller.
Transcrição da apresentação:

Desenvolvimento Java para Web Osvaldo Pinali Doederlein Visionnaire

Introdução à Plataforma J2EE 1.4

Agenda Containers Padrões JCP Servidores de Aplicação

J2EE e Containers http://java.sun.com/j2ee/ Container: Conceito fundamental do J2EE Aplicação executa num “casulo” que assume ou facilita diversas responsabilidades Administração / Ciclo de vida Conectividade (SGBD, Messaging, HTTP, SOAP etc.) Funcionalidades: Persistência, Segurança...

APIs O Container também implementa APIs J2EE APIs J2SE: stand-alone (bibliotecas simples) APIs J2EE: maior dependência de serviços XML-RPC: exige server HTTP JMS: exige middleware de mensagens Connector: exige bridges com outros sistemas EJB: exige servidor RMI/IIOP

APIs do J2EE 1.4: Diversos JavaMail JavaBeans Activation Framework Envio e recepção de e-mail por POP, IMAP, SMTP JavaBeans Activation Framework Ativação de funcionalidades via tipos MIME JNDI (Java Naming and Directory) LDAP, NDS, DNS, NIS, CosNaming; serviços J2EE JAAS (Autenthication & Authorization Service) Autorização e Autenticação; PAM

APIs do J2EE 1.4: Middleware JMS (Java Message Service) Comunicação assíncrona robusta JTA (Java Transaction API) Transações de alto nível JCA (J2EE Connector Architecture) Integração com sistemas não-J2EE JDBC (Java Database Connectivity) J2SE + DataSources, transações XA

APIs do J2EE 1.4: Web Servlets JSP (Java Sever Pages) Programação Web dinâmica JSP (Java Sever Pages) Idem, mais visual JSTL (Java Standard Template Library) Idem, mais estruturado Alternativas/Complementos: Struts, Spring... Futuro (J2SE 5.0): JSF (JavaServerFaces)

APIs do J2EE 1.4: XML e Web Services JAXP (Java API for XML Processing) DOM, SAX, XSLT SAAJ (SOAP with Attachments API for Java) Web Services: SOAP (modelo documento) JAX-RPC (Java API for XML-based RPC) Web Services: SOAP (modelo RPC), WSDL JAXR (Java API for XML Registries) Web Services: UDDI / ebXML

APIs do J2EE 1.4: EJB EJB (Enterprise Java Beans) EJB BMP/CMP/CMR Componentes Distribuídos; Session; RMI/IIOP EJB BMP/CMP/CMR Entity; Persistência Automática (mapeamento O/R) EJB MDB (Message-Driven Beans) Facilidade de alto nível para JMS e Web Services Transações, Segurança Facilidades declarativas

Padrões do JCP J2EE 1.4 (JSR-151 + 15 JSRs, jcp.org) Padroniza quase tudo APIs Schemas, Deployment Comportamentos (ciclos de vida, etc.) Não cobre: Ferramentas, Metodologias QoS Integração (ex.: suporte a SGBDs e middlewares) http://java.sun.com/reference/blueprints/

Tomcat 5.5 Apache + Sun; RI de JSRs de Servlet, JSP, etc. Container Web do JBoss, Sun AppServer, … Conectores para Apache e IIS http://jakarta.apache.org/tomcat/

JBoss 4.0 JBoss Group Open Source & Comercial Arquitetura: Microkernel (JMX), AOP http://www.jboss.com/products/jbossas/

Design Patterns para J2EE

Agenda Design Patterns Singleton Façade Factory DAO MVC

Design Patterns Design Patterns (GoF, 1995) Pattern = design reutilizável; problema+solução Modelos; ex.: Intenção, Motivação, Aplicabilidade, Estrutura, Implementação, Implicações, Categoria... Instanciável, mas não reusável, como código Linguagem de Patterns: Coleção de patterns relacionados, com modelo comum http://java.sun.com/blueprints/patterns/

Singleton: Motivação Garantir que uma classe tenha instância única Sem abrir mão do suporte à herança (como static) Implementação robusta de entidades que precisam ser únicas; ex: configuração Alternativa OO às variáveis globais Facilita a inicialização “lazy”

Singleton: Estrutura

class Configuracao { private static Configuracao singleton; private final Properties props; private Configuracao (Properties props) { this.props = props; } public static Configuracao getInstance () { if (singleton == null) { properties props = // ... Lê properties de um arquivo singleton = new Configuracao(props); } return singleton; public getProperties () { return props; } Properties props = Configuracao.getInstance().getProperties();

Façade: Motivação Interface única e simples para um sistema Simplifica API, reduz curva de aprendizado Reduz dependências e acoplamento Se o modelo interno do sistema evoluir, basta mudar a implementação da Façade; clientes são preservados Conduz a modelos em camadas (layers) Ex: Cliente (JSP)  Façade (Session Bean)  Negócio

Façade: Estrutura

Façade (Session / J2EE)

public class SistemaPagamentos { public void alteraSalario (String matricula, double salario) { Funcionario func = CadastroFuncs.getInstance().find(matricula); if (func != null && func.isAtivo()) func.setSalario(salario); } // ... Outros métodos da Façade // Cliente não precisa conhecer Funcionario, CadastroFuncs, etc. SistemaPagamentos sp = // ... sp.alteraSalario("93764622", 4350.00);

Factory: Motivação Cria objetos sem saber suas classes concretas Encapsula decisões sobre a criação de objeto Melhoram OO (construtores não são polimórficos!) Variante: Factory Method Útil com herança, delega criação à subclasse Evita instanceof para criar objetos relacionados Variante: Abstract Factory Suporta um conjunto de entidades relacionadas Suporta implementações "plugáveis", ex.: JDBC, XML

Factory Method: Estrutura

public interface Cliente { public Conta abreConta (); } public class ClienteSimples implements Cliente { public Conta abreConta () { return new ContaComum(this); public class ClientePremier implements Cliente { return new ContaEspecial(this); Cliente cli = // ... obtém da database ou outra fonte Conta ct = cli.abreConta(); // cria conta do tipo correto

Abstract Factory: Estrutura

// Utiliza fábrica abstrata de engine XML (Xerces, Crimson, etc.) SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); spf.setNamespaceAware(true); // Utiliza fábrica abstrata de parser (com ou sem validação, etc.) SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setContentHandler(this); reader.parse(config);

DAO: Motivação Desacoplar o acesso a dados dos clientes Ocultar a complexidade do acesso a dados Permitir alternância fácil e dinâmica da implementação de persistência Não é necessário com ferramentas ORM (como Hibernate), mas facilita migração JDBCORM

DAO: Estrutura

public class Venda { /* nenhum acesso a dados */ } public interface VendaDao { public Venda find (String id) throws SQLException; } public class VendaDaoJDBC implements VendaDao { private DataSource ds; public Venda find (String id) throws SQLException { try { Connection c = ds.getConnection(); Statement stmt = c.createStatement(); ResultSet rs = stmt.executeQuery("SELECT…"); if (rs.next()) return new Venda(id, rs.getString("produto"), …); } finally { if (c != null) try { c.close(); } catch (SQLException e){} } return null; // Objeto não encontrado

MVC-2: Motivação Desacoplar responsabilidades de uma GUI: Model: Camada de Implementação das Regras de Negócio View: Layout dos dados (ex.: telas HTML) Controller: Comportamento da GUI (ex.: consultas, atualizações, tratamento de erros, defaults) Permite variar/evoluir cada um separadamente View editável por não-programadores Back-end pode variar sem afetar GUI

MVC-2: Estrutura Controller View Model Requisição Envio de Dados Seleção do Visualizador Resposta do Envio de dados Resposta View Model

<html:form action="/LoginSubmit.do"> <table> <tr><td>Login:</td> <td><html:text property="login" size="20"/></td> </tr> <tr><td>Senha:</td> <td><html:password property="password" size="20"/></td> <tr><td><html:submit>OK</html:submit></td></tr> </table> </html:form> <html:messages id="error" property="invalid"> <script>alert('<bean:write name="error" />');</script> </html:messages> <html:javascript formName="LoginForm"/> View

public class LoginAction extends DispatchAction { public ActionForward login (ActionMapping map, ActionForm form, HttpServletRequest req, HttpServletResponse resp) throws Exception { audit(request, PortalAudit.ACCESS); if (isFirstLogin(request)) return mapping.findForward("firstLogin"); else return mapping.findForward("loginOk"); } private boolean isFirstLogin (HttpServletRequest req) {...} // ... Outras ações ... Controller

Logging

Agenda Log4J java.util.logging

Log4J Biblioteca do projeto Apache Jakarta Substitui System.out.println()... Níveis de log; ativação dinâmica sem mudar código Opções de output (console, arquivo, rede, DB etc.) Formatação, Extensibilidade Logs detalhados, de qualidade; fácil e eficiente Para diagnóstico de problemas (debug ou produção) Para auditoria, etc. http://logging.apache.org/log4j/

Log4J: Exemplo Logger logger = Logger.getLogger("SIST"); logger.debug("x=“ + x); logger.log(Level.DEBUG, "x=“ + x); if (logger.isDebugEnabled()) // Se não estiver habilitado... logger.debug(a+b+c+d+e+f); // ...evita custo de gerar dados

Log4J: log4j.properties log4j.logger.SIST = INFO, APP_SIST log4j.appender.APP_SIST = org.apache.log4j.RollingFileAppender log4j.appender.APP_SIST.File = ../logs/SIST.log log4j.appender.APP_SIST.MaxFileSize = 10MB log4j.appender.APP_SIST.MaxBackupIndex = 10 log4j.appender.APP_SIST.layout = org.apache.log4j.PatternLayout log4j.appender.APP_SIST.layout.ConversionPattern = [%p] %d{HH:mm:ss} - %m%n

Log4J: log4j.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'> <logger name=“SIST"> <level value="INFO"/> </logger> <appender name="APP_SIST" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="../logs/SIST.log"/> <param name="MaxFileSize" value="10MB"/> <param name="MaxBackupIndex" value="10"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%p] %d{HH:mm:ss} - %m%n"/> </layout> </appender> </log4j:configuration>

java.util.logging API padrão do J2SE 1.4+ (JSR-47) Semelhante à Log4J, mas não igual/compatível Menos poderosa; Mais leve, simples, eficiente Log4J ou java.util.logging? Log4J não é o padrão, mas ainda é mais popular java.util.logging melhor para componentes reusáveis (não impõe dependência da Log4J para projetos) A Jakarta Commons Logging só piora as coisas  http://java.sun.com/j2se/1.5.0/docs/guide/logging/

java.util.logging: Exemplo Logger logger = Logger.getLogger("SIST"); logger.fine("x=“ + x); logger.log(Level.FINE, "x=“ + x); if (logger.isLoggable(Level.FINE)) // Se não estiver habilitado... logger.fine(a+b+c+d+e+f); // ...evita custo de gerar dados

java.util.logging: logging.properties handlers= java.util.logging.FileHandler SIST.level = INFO java.util.logging.FileHandler.pattern = ../logs/SIST%u.log java.util.logging.FileHandler.limit = 10000000 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

JDBC

Agenda JDBC API J2EE/DataSources

A API JDBC Baseada na ODBC (Microsoft; Open Group CLI) Características Microsoft: novas APIs (OleDB, ADO, RDO, RDS...) JDBC: evolução compatível + frameworks O/R Características Baixo nível: conexões, statements, cursores, SQL Leve e eficiente Infra-estrutura para todas as outras soluções http://java.sun.com/products/jdbc/

JDBC: Connection Representa sessão com o SGBD, e transação Alto custo de criação. Usar pools! Default: auto-commit, não usar!! Connection conn = null; try { conn = DriverManager.getConnection(url, user, password); // Utiliza a conexão... } catch (SQLException e) { if (conn != null) try { conn.close(); } catch (SQLException e) {} }

JDBC: Statement e ResultSet Statement: Query, Update, ou DDL Prefira PreparedStatement sempre! ResultSet: Cursor (resultado de Statement) Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT id,nome FROM FUNC"); while (rs.next()) { System.out.println(rs.getInt(1)); System.out.println(rs.getString("nome")); } stmt.close();

JDBC: PreparedStatement Estende Statement, mais poderoso e eficiente Binding (?), reduz recompilação e formatação de SQL Cache no cliente (driver JDBC) Também é mais seguro (evita "injeção de SQL") PreparedStatement stmt = conn.prepareStatement( "SELECT id,nome FROM FUNC WHERE salario >= ?"); stmt.setDouble(1, 3000); ResultSet rs = stmt.executeQuery(); ... stmt.close();

JDBC: CallableStatement Invocação de stored procedures / functions “Anti-OO”, mas reduz tráfego com SGBD CallableStatement stmt = conn.prepareCall( “{call CALCULA_SALARIO (?,?)}"); stmt.setInt(1, idFuncionario); stmt.registerOutParameter(2, Types.DOUBLE); stmt.executeUpdate(); double salario = stmt.getDouble(2); stmt.close();

Gerenciamento de Recursos Invocação dos métodos close() Connection.close(): fecha todos Statements e blobs Statement.close(): fecha ResultSet corrente Statemet.execute*(): também fecha ResultSet anterior ResultSet.close(): não fecha seus blobs! Regra: fechar só o objeto “raiz local” do método Ex.: Se um método recebe a Connection como parâmetro, basta fechar os Statement criados Evite dividir responsabilidades (um método cria, outro faz o close())  bugs, bugs, bugs!!

Opções: Connection TRANSACTION_READ_UNCOMMITTED Permite dirty/non-repeatable/phantom reads TRANSACTION_READ_COMMITTED Permite non-repeatable/phantom reads TRANSACTION_REPEATABLE_READ Permite phantom reads TRANSACTION_SERIALIZABLE Isolamento ACID total CONFIABILIDADE DESEMPENHO

Opções: ResultSet FETCH_FORWARD/REVERSE/UNKNOWN Direção da leitura (hints para o driver) CONCUR_READ_ONLY/UPDATABLE Somente leitura, ou cursor atualizável TYPE_FORWARD_ONLY/ SCROLL_SENSITIVE/SCROLL_SENSITIVE Leitura randômica ou aleatória PRODUTIVIDADE DESEMPENHO

DataSource Abstração sobre obtenção de conexões J2EE, mas também pode ser usada sem container Suporte a JNDI, pools, transações distribuídas Configuração no container Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/Sistema"); ... Connection conn = ds.getConnection();

Testes Unitários

Agenda Testes Unitários JUnit

Testes Unitários TDD (Test-Driven Development), XP 1 funcionalidade = 1 teste Funcionalidade: método, classe, caso de uso, cenário Escrever teste antes do código a testar Objetivos: melhorar qualidade e produtividade Planejar componentes, do ponto de vista do cliente Proteção contra bugs de regressão Otimizações, refactoring... "fearless programming" http://www.extremeprogramming.org/rules/unittests.html

JUnit Framework para testes unitários em Java Kent Beck (XP) + Erich Gamma (Patterns, Eclipse) Simples Extensível Exemplos públicos para examinar... J2SE/TCK (45.000 testes) Eclipse (feito com o JUnit) http://www.junit.org/

public class TestaRaizes extends TestCase { public void testOk () { double[] x = Raizes.calcula(3, 4, 1); // 3x2+4x+1=0 assertTrue(x[0] == -3 && x[1] == -9); System.out.println(x[0] + "," + x[1]); } public void testDeltaNegativo () { try { double[] x = Raizes.calcula(3, 0, 1); // 3x2=-1 fail(); catch (IllegalArgumentException e) {}

public class Raizes { public static double[] calcula (double a, double b, double c) { double delta = Math.sqrt(b*b-4*a*c); if (Double.isNaN(delta)) throw new IllegalArgumentException("Delta negativo"); double x1 = (-b+delta)/2*a; double x2 = (-b-delta)/2*a; return new double[]{x1,x2}; }

Servlets

Agenda Servlet Inicialização Filtros Redirecionamento Sessões Cookies

Servlet Servlet = Classe Java que responde a HTTP Exige um conector HTTP (webserver) Servlet recebe um request Conector cuida de headers, TCP/IP, etc. Base para todo stack Java Web JSP, JSTL, JSF, Struts, Velocity, Spring, etc. http://java.sun.com/products/servlet/

public class AloMundo extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { resp.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Alô Mundo</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Alô, Mundo!</h1>"); out.println("</body>"); out.println("</html>"); }

Web.xml: <servlet> <servlet-name>AloMundo</servlet-name> <servlet-class>AloMundo</servlet-class> </servlet> <servlet-mapping> <url-pattern>/alo</url-pattern> </servlet-mapping> </web-app>

Inicialização e Shutdown Servlet.init(), Servlet.destroy() init() na primeira invocação, ou load-on-startup=true ServletContextListener Mecanismo apropriado para ciclo de vida da aplicação como um todo

public class MeuListener implements ServletContextListener{ public void contextInitialized (ServletContextEvent sce) { System.out.println("inicializando..."); } public void contextDestroyed (ServletContextEvent sce) { System.out.println("terminando..."); Web.xml: <listener> <listener-class>TesteListener</listener-class> </listener>

Filtros Interceptação de requests Verificação de desempenho Logging automatizado Controle de segurança, transações, etc. Transformações, ex.: via XSLT Implementação de frameworks dinâmicos, ex.: Struts Implementação do próprio container

public class PSSFilter implements Filter { // Omitidos: init(), destroy() public void doFilter (ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { try { chain.doFilter(req, resp); } finally { Catalog.closeConnection(); } } Web.xml: <filter> <filter-name>PSSFilter</filter-name> <filter-class>com.visionnaire.PSS.servlet.PSSFilter</filter-class> </filter> <filter-mapping> <filter-name>PSSFilter</filter-name><url-pattern>*.jsp</url-pattern> </filter-mapping>

Forward e Include Forward: Desvio para outra URL request.getRequestDispatcher("/Header.jsp") .forward(request, response); Include: Cópia do output de uma URL request.getRequestDispatcher("/OK.jsp") .include(request, response);

Contexto, Sessões e Cookies ServletContext: Representa a web-app MIME, dispatchers, resources, servlets, atributos, log HttpSession: Permite armazenar informações sobre um cliente, através de várias páginas ID, atributos, criação, último acesso, timeout Cookies ou URL rewriting Cookie: Pacote de dados armazenável no browser Utiliza headers do HTTP Pode ser restrito pelo cliente (número, tamanho)

JSP

Agenda JSP Taglibs Expression Language JSTL

JSP Servlet: Java com HTML, JSP: HTML com Java Semelhante a ASP, PHP, etc. JSP gera uma Servlet Compilado pelo container, em demanda ou deploy Acesso a toda a API de Servlets Diretrizes de página Scriptlets Ações

JSP: Sintaxe Comentário Expressão Scriptlet Declaração Diretiva include Diretiva page <%-- comentário --> <%= expressão %> <% statement %> <%! declaração %> <%@include file="url-absoluta"> <%@page atrib="valor" %> language="java", import="pkg" errorPage="url", extends="classe" info="msg", contentType="MIME" buffer="kb|none", isErrorPage, session, autoflush, isThreadSafe

JSP: Ações Ação include Ação useBean Ação getProperty Ação forward Ação plugin <jsp:include page="url"> <jsp:useBean atrib="valor"/> id="nome" scope="page|request| session|application" type="class" class="class" beanName="class" <jsp:getProperty name="name" value="valor"/> <jsp:forward page="url"/> <jsp:plugin atrib="valor"/>

JSP: Variáveis predefinidas As mesmas que estariam disponíveis na Servlet HttpServletRequest request HttpServletResponse response HttpSession session PrintWriter out <h2>Seu host é: <%= request.getRemoteHost() %></h2>

<%@page language="java"%> <%@page import="java.util.Date"/> <jsp:include page="Titulo.html"/> <jsp:include page="Navegacao.jsp"/> <html><head/> <body> <p> Alo, mundo! Agora são <%= new Date() %> </p> </body> </html>

Taglibs Declaração e Uso (JSP) Configuração (web.xml) <%@taglib prefix="opd" uri="/tags/osvaldo" %> <tt:alo name="Osvaldo"> ... </tt:alo> Configuração (web.xml) <jsp-config> <taglib> <taglib-uri>/tags/osvaldo</taglib-uri> <taglib-location>/WEB-INF/tags/osvaldo.tld</taglib-location> </taglib> </jsp-config>

<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <taglib> <tlibversion>1.0.0</tlibversion> <jspversion>1.1</jspversion> <shortname>Taglib Demo</shortname> <tag> <name>alo</name> <tagclass>tags.AloTag</tagclass> <bodycontent>empty</bodycontent> <attribute> <name>nome</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <type>java.lang.String</type> </attribute> </tag> </taglib>

public class AloTag extends BodyTagSupport { private String nome; public void setNome (String nome) { this.nome = nome; } public int doEndTag () throws JspException { try { pageContext.getOut().write("Alo, " + nome); catch (IOException e) {} return SKIP_BODY;

EL (Expression Language) Parâmetros de tags; reduz uso de scriptlets Sintaxe: ${var} (= var) ${var.x.y} (= var.getX().getY()) Operadores extra; números e strings div, mod, and, or, not, eq, ne, lt, gt, le, ge, empty Ex.: ${(10 mod 4 == 5) and empty x} ${(10 % 4 == 5) && x == null}

EL (Expression Language) Variáveis predefinidas pageContext (servletContext, session, request, response) param, paramValues header, headerValues cookie, initParam pageScope, requestScope, sessionScope, applicationScope Sintaxe [ ] para acesso a variáveis Map (get()) ${header["host"]} ${pageScope.departamentos[nomeDepto]}

JSTL (JSP Standard TagLib) JSR-52: Biblioteca padrão de tags para JSP Core: Iteração, Condições, Output… FMT: Formatação, Internacionalização SQL: Acesso a dados via JDBC XML: Parsing, Xpath, XSLT Functions: Manipulação de strings

<%@ taglib prefix="sql" uri="http://java. sun <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>Demo de JSTL</title></head> <body> <sql:transaction dataSource=“jdbc/MinhaDatabase"> <sql:query var=“produtos"> SELECT * FROM PRODUTO </sql:query> </sql:transaction> <h2>Componentes de Hardware</h2> <table border="1"> <c:forEach var="row" items="${produtos.rowsByIndex}"> <tr> <c:forEach var="col" items="${row}"> <td><c:out value="${col}"/></td> </c:forEach> </tr> </table> </body></html>

JSTL: Core <c:out value="texto“/> <c:set var="nome" value="valor" scope="page|request|session|application"/> <c:remove var="nome" scope="page|request|session|application"/> <c:catch var="nome"> ... </c:catch> <c:if test="condição" var,scope> ... </c:if> <c:choose> <c:when test="condição">...</c:when> <c:otherwise>...</c:otherwise> </c:choose>

JSTL: Core <c:forEach var="nome" items="coleção" varStatus="status" begin="n" end="n" step="n"> <c:forTokens var="nome" items="string" delims="sep" varStatus="status" begin="n" end="n" step="n"> <c:import url="url" charEncoding="encoding" context="contexto" varReader="nome" var,scope> <c:param name="nome" value="valor"/> <c:url value="url" context="contexto" var,scope/> <c:redirect url="url" context="contexto" >

JSTL: Formatação <fmt:setTimeZone value="timeZone"/> <fmt:timeZone var,scope> corpo </fmt:timeZone> <fmt:formatNumber value="valor" currencyCode="code" currencySymbol="symbol" type="number|currency|percent" var,scope groupingUsed="bool" pattern="pattern" maxIntegerDigits="n" minIntegerDigits="n" maxFractionDigits="n" minFractionDigits="n"> <fmt:parseNumber value="valor" parseLocale="locale" type="number|currency|percent" integerOnly="bool" var,scope/>

JSTL: 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: 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: 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... JSTL JSR-128: JESI, JSP TagLib for Edge Side Includes XML (<x:...>) Internacionalização (<fmt:...>) Funções EL definidas pelo usuário JSR-128: JESI, JSP TagLib for Edge Side Includes JSR-267: JSP TagLib for Web Services

Deployment

Agenda Pacotes jar, war, ear Deploy em servidores J2EE

Pacotes jar, war, ear JAR: J2SE WAR: J2EE EAR: J2EE (EJB) /  Classes, Resources /META-INF/  Manifest.MF WAR: J2EE /  Páginas (e subdiretórios) /WEB-INF  Configurações, TLDs /WEB-INF/classes  Classes /WEB-INF/lib  JARs /WEB-INF/tags  tagfiles EAR: J2EE (EJB)

Deploy em servidores J2EE "Hot deploy", copiar WAR/EAR para diretório Tomcat: /webapps JBoss: server/config/deploy DataSources: deploy de .XML Outros (JBoss): RAR (Resource Adapter) SAR (Service) Deploy "explodido" (opcional / debug) Ferramentas GUI de Deploy: overrides

Struts

Agenda Model (forms) View Controller (actions) Configuração Taglibs Tiles Validação

Controller View Model Requisição Envio de Dados Seleção do Visualizador Resposta do Envio de dados Resposta View Model

View Página JSP "amarrada" à Struts <html:form action>  Action (Controller) Campos  Form (View)

Controller Herda Action Implementar execute() Predefinidas: Tiles, Download, Forward, Include... Implementar execute() Uma ou mais actions: request.getParameter("action") Dispara alguma ação de negócio Determina próxima página (forward) DispatchAction: implementar métodos similares ao execute(), mas com nome igual à da ação

Configuração WEB-INF/struts-config.xml WEB-INF/web.xml Mapeamento MVC, page flow WEB-INF/web.xml Configuração padrão da Struts, ex.: ActionServlet WEB-INF/: Outros arquivos da Struts WEB-INF/lib: Binários da Struts WEB-INF/.struts-config.mex: Layout visual para o struts-config.xml (MyEclipse)

public class ContatoForm extends ActionForm { private String nome="", sobrenome="", email="", fone="", warning=""; public String getNome () { return nome; } public void setNome (String nome) { this.nome = nome; } // Omitido: outros getters/setters public String valida () { if (nome == null || nome.length() == 0) return "nome"; if (sobrenome == null || sobrenome.length() == 0) return "sobrenome"; if (email == null || email.length() == 0 || email.indexOf('@') == -1) return "email"; if (fone == null || fone.length() == 0) return "fone"; return null; }

public class MessageBean { private String message = ""; public String getMessage () { return message; } public void setMessage (String message) { this.message = message;

public class AssinaAction extends Action { public ActionForward execute (ActionMapping map, ActionForm aForm, HttpServletRequest req, HttpServletResponse resp) throws Exception { ContatoForm form = (ContatoForm)aForm; String campoRuim = form.valida(); if (campoRuim != null) { warn(req, campoRuim); return map.findForward("valor-errado"); } else return map.findForward("sucesso"); protected void warn (HttpServletRequest req, String msg) { MessageBean msgBean = new MessageBean(); msgBean.setMessage(msg); req.setAttribute("messageBean", msgBean);

assina.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <html><head><title>Assinatura</title></head> <body><h1 align="center">Assinatura</h1> Digite seus dados de contato para receber nossa Newsletter!<p/> <center> <html:form action="/assina"> <table> <tr><td>Nome:</td><td><html:text property="nome"/></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>Fone:</td><td><html:text property="fone"/></td></tr> </table> <html:submit value="Assine!"/> </html:form> </center> </body></html>

confirma.jsp: (Usando taglib Struts Beans – NÃO PROGRAMAR ASSIM!!!) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <html><head><title>Confirmação</title></head> <body><center><h1>Confirmação</h1> Muito obrigado, prepare seu Inbox para nosso spam! <table> <tr><td>Nome:</td> <td><bean:write name="contatoForm" property="nome"/></td></tr> <tr><td>Sobrenome:</td> <td><bean:write name="contatoForm" property="sobrenome"/></td></tr> <tr><td>Email:</td> <td><bean:write name="contatoForm" property="email"/></td></tr> <tr><td>Fone:</td> <td><bean:write name="contatoForm" property="fone"/></td></tr> </table> </center> </body></html>

confirma.jsp: (Usando taglib JSTL Core – FAZER DESSA MANEIRA!!!) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html><head><title>Confirmação</title></head> <body><center><h1>Confirmação</h1> Muito obrigado, prepare seu Inbox para nosso spam! <table> <tr><td>Nome:</td> <td><c:out value="${contatoForm.nome}"/></td></tr> <tr><td>Sobrenome:</td> <td><c:out value="${contatoForm.sobrenome}"/></td></tr> <tr><td>Email:</td> <td><c:out value="${contatoForm.email}"/></td></tr> <tr><td>Fone:</td> <td><c:out value="${contatoForm.fone}"/></td></tr> </table> </center> </body></html>

valor-errado.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>Valor faltando ou incorreto!</title></head> <body><center> <h2>Valor faltando ou incorreto: <c:out value="${messageBean.message}"/>!</h2> Por favor, <a href="assina.jsp">Tente novamente</a>. </center> </body></html>

assina2.jsp: <!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-bean" prefix="bean" %> <html><head><title>Assinatura</title></head> <body><h1 ALIGN="CENTER">Assinatura</h1> Digite seus dados de contato para receber nossa Newsletter!<p/><center> <html:form action="/assina2"> <c:if test="${not empty contatoForm.warning}"> Campo faltando ou inválido: <bean:write name="contatoForm" property="warning" filter="false"/> </c:if> <table> <tr><td>Nome:</td><td><html:text property="nome"/></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>Fone:</td><td><html:text property="fone"/></td></tr> </table> <html:submit value="Assine!"/> </html:form></center></body></html>

struts-config.xml: <struts-config> <form-beans> <form-bean name="contatoForm" type="ContatoForm"/> </form-beans> <global-forwards> <forward name="sucesso" path="/confirma.jsp"/> </global-forwards> <action-mappings> <action path="/assina" type="AssinaAction" name="contatoForm" scope="request"> <forward name="valor-errado" path="/valor-errado.jsp"/> </action> <action path="/assina2" type="AssinaAction2" name="contatoForm" scope="request"> <forward name="valor-errado" path="/assina2.jsp"/> </action-mappings> </struts-config>

Struts Taglibs Struts inclui várias taglibs: Bean, Logic (maior parte obsoleta; usar JSTL) HTML: Gera elementos, útil para forms http://struts.apache.org/userGuide/struts-html.html Nested: Relacionamentos entre tags (pai/filho) Utilities: Diversos Tiles

Tiles Taglib da Struts Permite compor páginas complexas, juntando fragmentos (tiles) reutilizáveis Como <jsp:include>, mas mais flexível e estruturado Facilidade de template Separa estrutura, layout e componentes Permite recombinar estes elementos facilmente http://struts.apache.org/userGuide/dev_tiles.html

Tiles: 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: Planejando Comece planejando seu layout "master"... Cabeçalho Menu Corpo Rodapé

Tiles: Planejando Defina estrutura de página/layout/fragmentos página1 Menu Cabeçalho Rodapé Corpo

Tiles: Implementando Página (instancia/parametriza o layout) pagina1.jsp: <%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>  <tiles:insert page="/layout.jsp" flush="true">   <tiles:put name="titulo" value="Página 1"/>   <tiles:put name="cabecalho" value="/cabecalho.html"/>   <tiles:put name="menu" value="/menu.jsp"/>   <tiles:put name="rodape" value="/rodape.jsp"/>   <tiles:put name="corpo" value="/corpo1.jsp"/> </tiles:insert>

Tiles: Implementando Layout layout.jsp: <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>   <html><head> <title><tiles:getAsString name="titulo"/></title></head>  <body><table width="100%">    <tr><td colspan="2"><tiles:insert attribute="cabecalho"/></td></tr>   <tr><td width="120"><tiles:insert attribute="menu"/></td>     <td><tiles:insert attribute="corpo"/></td></tr>   <tr><td colspan="2"><tiles:insert attribute="rodape"/></td></tr> </ table></body></html>

Tiles: Implementando os Tiles JSPs, HTMLs ou imagens, normais Exemplo: cabecalho.html <a href="http://www.companhia.com">    <img src="/BannerEsq.gif" align="left" border="0"> </a> <img src="/BannerDir.gif" align="right" border="0">

Tiles: Usando Definitions Especificação declarativa das páginas Suporta herança de páginas JSPs 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: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd"> <tiles-definitions> <definition name=".layoutBase" path="/layout.jsp"> <put name="titulo" value=""/> <put name="cabecalho" value="cabecalho.html"/> <put name="menu" value="menu.jsp"/> <put name="rodape" value="rodape.jsp"/> <put name="corpo" value=""/> </definition> <definition name="pagina1.page" extends=".layoutBase" > <put name="titulo" value="Página 2"/> <put name="corpo" value="corpo2.jsp"/> </tiles-definitions>

pagina1.jsp layout.jsp (titulo="Página 1") cabecalho.html menu.jsp corpo1.jsp rodape.jsp pagina2.jsp pagina3.jsp layout.jsp (titulo="Página 2") layout.jsp (titulo="Página 3") cabecalho.html cabecalho.html menu.jsp corpo2.jsp menu.jsp corpo3.jsp rodape.jsp rodape.jsp

Validação Opções de validação Código de validação, onde? Sem Validator: ad-hoc Validação Manual (ou semi-automática) Validação Automática Código de validação, onde? Form (e/ou JavaScript): Só regras encapsuláveis no bean; ex.: formato de string; valores mín/máx Action: Acesso à lógica de negócio, database, etc. http://struts.apache.org/userGuide/dev_validator.html

Validação Manual Implementar ActionForm.validate() public ActionErrors validate ( ActionMapping map, HttpServletRequest req) { ActionErrors ae = super.validate(map, req); if (ae == null) ae = new ActionErrors(); if (...) ae.add("nome", new ActionMessage("contatoForm.nome")); if (...) ae.add("email", new ActionMessage("contatoForm.email")); ... return ae; } Detecte todos os erros, não só o primeiro!

struts-config.xml: <action path="/assina" type="AssinaAction" name="contatoForm" scope="request" input="/assina.jsp" validate="true"> </action> <message-resources parameter="MessageResources" null="false"/> WEB-INF/classes/MessageResources.properties: contatoForm.nome=Nome não pode ser vazio contatoForm.email=Email deve ter formato "conta@host"

assina.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <html><head><title>Assinatura</title></head> <body><h1 align="center">Assinatura</h1> Digite seus dados de contato para receber nossa Newsletter!<p/> <center> <html:form action="/assina"> <table> <html:errors/> <tr><td>Nome:</td><td><html:text property="nome"/></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>Fone:</td><td><html:text property="fone"/></td></tr> </table> <html:submit value="Assine!"/> </html:form> </center> </body></html>

public class AssinaAction extends Action { public ActionForward execute (ActionMapping map, ActionForm aForm, HttpServletRequest req, HttpServletResponse resp) throws Exception { // Se chegou até aqui, é porque o Struts já // executou a validação com sucesso! return map.findForward("sucesso"); }

Validação Automática Validação declarada em arquivo XML Validação Server-Side (Validator), obrigatória Mais segura, não contornável pelo usuário Validação Client-Side (JavaScript), opcional Mais eficiente, evita request ao servidor e refresh

struts-config.xml: <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/> </plug-in> validator-rules.xml, validation.xml: extraia do struts-blank.war WEB-INF/classes/MessageResources.properties: # Mensagens-padrão (copiar do comentário no validator-rules.xml): errors.required={0} é obrigatório. errors.minlength={0} não pode ter menos que {1} caracteres. ...

validation.xml: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN" "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd"> <form-validation> <formset> <form name="contatoForm"> <field property="nome" depends="required"><arg key="contatoForm.nome"/></field> <field property="sobrenome" depends="required"> <arg key="contatoForm.sobrenome"/> </field> <field property="email" depends="required,mask"> <arg key="contatoForm.email"/> <var> <var-name>mask</var-name> <var-value>^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$</var-value> </var> </field> <field property="fone" depends="required"> <arg key="contatoForm.fone"/> </field> </form> </form-validation>

assina.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <html><head><title>Assinatura</title></head> <body><h1 align="center">Assinatura</h1> <p align="center">Digite seus dados de contato para receber nossa Newsletter!</p> <center> <html:form action="/assina" onsubmit="return validateContatoForm(this);"> <table> <tr><td>Nome:</td><td><html:text property="nome"/> <html:errors property="nome"/></td></tr> <tr><td>Sobrenome:</td><td><html:text property="sobrenome"/> <html:errors property="sobrenome"/> </td></tr> <tr><td>Email:</td><td><html:text property="email"/> <html:errors property="email"/> </td></tr> <tr><td>Fone:</td><td><html:text property="fone"/> <html:errors property="fone"/> </td></tr> </table> <html:submit value="Assine!"/> </html:form><html:javascript formName="contatoForm"/></center></body></html>

public class ContatoForm extends ValidatorForm { private String nome=""; private String sobrenome=""; private String email=""; private String fone=""; public String getNome () { return nome; } public void setNome (String nome) { this.nome = nome; } public String getSobrenome () { return sobrenome; } public void setSobrenome (String sn) {this.sobrenome = sn;} public String getEMail () { return email; } public void setEMail (String email) { this.email = email; } public String getFone () { return fone; } public void setFone (String nome) { this.fone = fone; } } // Nenhum código de validação!

Validação no Servidor

Validação no Cliente

Validação: Capacidades Validações predefinidas: required, requiredif, validwhen, minlength, maxlength mask, creditCard, email, url integer, float, double, long, short, byte, date intRange, longRange, floatRange, doubleRange Definições globais (constantes) Validadores plugáveis Validação Híbrida (Manual + Automática)

Visionnaire Informática S.A. Muito Obrigado Visionnaire Informática S.A. R. Eng Roberto Fischer, 228 CIC - Curitiba - PR 81250-025 Tel: (41) 3337-1000 vision@visionnaire.com.br http://www.visionnaire.com.br