A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Desenvolvimento Java para Web

Apresentações semelhantes


Apresentação em tema: "Desenvolvimento Java para Web"— Transcrição da apresentação:

1 Desenvolvimento Java para Web
Osvaldo Pinali Doederlein Visionnaire

2 Introdução à Plataforma J2EE 1.4

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

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

5

6 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

7

8 APIs do J2EE 1.4: Diversos JavaMail JavaBeans Activation Framework
Envio e recepção de 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

9 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

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

11 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

12 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

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

14 Tomcat 5.5 Apache + Sun; RI de JSRs de Servlet, JSP, etc.
Container Web do JBoss, Sun AppServer, … Conectores para Apache e IIS

15 JBoss 4.0 JBoss Group Open Source & Comercial
Arquitetura: Microkernel (JMX), AOP

16 Design Patterns para J2EE

17 Agenda Design Patterns Singleton Façade Factory DAO MVC

18 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

19 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”

20 Singleton: Estrutura

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

22 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

23 Façade: Estrutura

24 Façade (Session / J2EE)

25 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(" ", );

26 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

27 Factory Method: Estrutura

28 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

29 Abstract Factory: Estrutura

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

31 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

32 DAO: Estrutura

33 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

34 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

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

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

37 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

38 Logging

39 Agenda Log4J java.util.logging

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

41 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

42 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

43 Log4J: log4j.xml <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns: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>

44 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 

45 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

46 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 = java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

47 JDBC

48 Agenda JDBC API J2EE/DataSources

49 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

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

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

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

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

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

55 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

56 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

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

58 Testes Unitários

59 Agenda Testes Unitários JUnit

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

61

62

63 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 ( testes) Eclipse (feito com o JUnit)

64

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

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

67 Servlets

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

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

70

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

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

73 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

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

75 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

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

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

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

79 JSP

80 Agenda JSP Taglibs Expression Language JSTL

81 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

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

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

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

85 <%@page language="java"%>
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>

86 Taglibs Declaração e Uso (JSP) Configuração (web.xml)
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>

87 <?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" " <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>

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

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

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

91 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

92 <%@ taglib prefix="sql" uri="http://java. sun
taglib prefix="c" uri=" %> <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>

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

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

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

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

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

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

99 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

100 Deployment

101 Agenda Pacotes jar, war, ear Deploy em servidores J2EE

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

103

104 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

105 Struts

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

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

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

109 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

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

111

112 public class ContatoForm extends ActionForm {
private String nome="", sobrenome="", ="", 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 ( == null || .length() == 0 || == -1) return " "; if (fone == null || fone.length() == 0) return "fone"; return null; }

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

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

115 assina.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib uri=" 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> </td><td><html:text property=" "/></td></tr> <tr><td>Fone:</td><td><html:text property="fone"/></td></tr> </table> <html:submit value="Assine!"/> </html:form> </center> </body></html>

116 confirma.jsp: (Usando taglib Struts Beans – NÃO PROGRAMAR ASSIM!!!)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib uri=" 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> </td> <td><bean:write name="contatoForm" property=" "/></td></tr> <tr><td>Fone:</td> <td><bean:write name="contatoForm" property="fone"/></td></tr> </table> </center> </body></html>

117 confirma.jsp: (Usando taglib JSTL Core – FAZER DESSA MANEIRA!!!)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib prefix="c" uri=" %> <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> </td> <td><c:out value="${contatoForm. }"/></td></tr> <tr><td>Fone:</td> <td><c:out value="${contatoForm.fone}"/></td></tr> </table> </center> </body></html>

118 valor-errado.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib prefix="c" uri=" %> <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>

119 assina2.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib uri=" prefix="html" %> taglib uri=" 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> </td><td><html:text property=" "/></td></tr> <tr><td>Fone:</td><td><html:text property="fone"/></td></tr> </table> <html:submit value="Assine!"/> </html:form></center></body></html>

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

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

122 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

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

124 Tiles: Planejando Comece planejando seu layout "master"... Cabeçalho
Menu Corpo Rodapé

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

126 Tiles: Implementando Página (instancia/parametriza o layout)
pagina1.jsp: 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>

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

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

129 Tiles: Usando Definitions
Especificação declarativa das páginas Suporta herança de páginas JSPs de página reduzidas 1 insert: 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

130 Tiles-defs.xml: <?xml version="1.0" encoding="ISO " ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN" " <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>

131 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

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

133 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(" ", new ActionMessage("contatoForm. ")); ... return ae; } Detecte todos os erros, não só o primeiro!

134 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. = deve ter formato

135 assina.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib uri=" 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> </td><td><html:text property=" "/></td></tr> <tr><td>Fone:</td><td><html:text property="fone"/></td></tr> </table> <html:submit value="Assine!"/> </html:form> </center> </body></html>

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

137 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

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

139 validation.xml: <?xml version="1.0" encoding="ISO " ?> <!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN" " <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=" " depends="required,mask"> <arg key="contatoForm. "/> <var> <var-name>mask</var-name> </var> </field> <field property="fone" depends="required"> <arg key="contatoForm.fone"/> </field> </form> </form-validation>

140 assina.jsp: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> taglib uri=" 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> </td><td><html:text property=" "/> <html:errors property=" "/> </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>

141 public class ContatoForm extends ValidatorForm {
private String nome=""; private String sobrenome=""; private String =""; 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 get () { return ; } public void set (String ) { this. = ; } public String getFone () { return fone; } public void setFone (String nome) { this.fone = fone; } } // Nenhum código de validação!

142 Validação no Servidor

143 Validação no Cliente

144 Validação: Capacidades
Validações predefinidas: required, requiredif, validwhen, minlength, maxlength mask, creditCard, , 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)

145 Visionnaire Informática S.A.
Muito Obrigado Visionnaire Informática S.A. R. Eng Roberto Fischer, CIC - Curitiba - PR Tel: (41)


Carregar ppt "Desenvolvimento Java para Web"

Apresentações semelhantes


Anúncios Google