JSP e JavaBeans JSP e Java Beans • O desenvolvimento de sistemas com JSP apresenta como problema principal a mistura de código e XHTML. • Em caso de alterações tanto programadores quanto web-designers devem ser envolvidos. • A melhor solução é separar a lógica em classes designadas por Java Beans. • Estas classes podem ser acedidas directamente da página JSP através de uso de propriedades. • Como não há programação, a tarefa pode ser realizada pelo webdesigner diminuindo o impacto tanto da alteração de código quanto ao do layout 1 Java Beans • Java Beans são classes Java que obdecem determinadas regras: – Deve existir um construtor público e sem parâmetros – Nenhum atributo pode ser público – Os atributos são acedidos através de métodos públicos setXxx, getXxx e isXxx • Estas regras determinam um padrão que possibilita o uso de Beans como componentes em ferramentas de desenvolvimento. • Estes componentes minimizam a necessidade de programação pois são utilizados através de suas propriedades. Tipos de Java Beans • Existem três tipos de Java Beans: – Visuais, utilizados no desenvolvimento de interfaces. – Dados, que fornecem um padrão para acesso a valores. – Serviços, usados para cálculos, acesso a tabelas e algoritmos específicos. • Em JSP apenas os dois últimos tipos são usados 2 Exemplo de Java Bean class Hora { private int hora, minuto; public Hora() { hora = minuto = 0; } public int getSegundos() { return hora*3600+60*minuto; } } Uso de Java Beans • Para utilizar Java Beans em uma aplicação comum deve-se criar um objecto e aceder aos seus métodos • Em JSP, existem Marcas especiais para criação e recuperação de propriedades que não exigem conhecimento de programação 3 Criar Java Beans • Acção <jsp:useBean> – Permite JSP gerir objectos Java •Cria objectos Java ou selecciona um objecto que já existe para que seja possível utiliza-lo numa JSP • Exemplo: <jsp:useBean id = “obj” class = “Hora”/> • Esta tag é semelhante a: Hora obj = new Hora(); Recuperar Propriedades • Para ler uma propriedade de um Bean usa-se o atributo getProperty • Exemplo: <jsp:getProperty name = “obj” property = “Segundos” /> • Esta Marca retorna no local em que estiver o valor da propriedade recuperada 4 Alterar Propriedades • Para alterar uma propriedade usa-se setProperty. • Exemplo: <jsp:setProperty name = “obj” property = “Segundos” value = “60”/> Inicializar Beans • Caso seja necessário inicializar um Beans usa-se a sintaxe: <jsp:useBean id = “obj” class = “Hora”> <%-- Inicialização do Bean --%> </jsp:useBean> • O código é executado apenas se o Bean for criado 5 Partilha dos Beans • A criação padrão disponibiliza o Bean apenas para a página actual • Para alterar o nível de acesso usa-se o atributo scope • Exemplo: <jsp:useBean id = “obj” class = “Hora” scope=“page”> • Scope pode ter quatro valores: – page, mantém o Bean até que a página seja mostrada – request, mantém o Bean até que a resposta seja toda enviada – session, o Bean existe durante a sessão – application, o Bean dura enquanto a aplicação Web actual estiver activa Propriedades Indexadas • Não existem Marcas específicas para o acesso a propriedades indexadas • Para aceder tais propriedades deve-se usar scriptlets e expressões • Exemplo: <%for(int i=0; i<10; i++) { %> <%=obj.getPropriedade(i)%> <br> <%}%> 6 Propriedades e Parâmetros • Os parâmetros (getParameter) podem ser inseridos directamente em propriedades de Java Beans. • Basta usar o nome do parâmetro no atributo param: <jsp:setProperty name=“obj” property=“nome” param = “nome”/> Propriedades e Parâmetros • Para propriedades e parâmetros com o mesmo nome é possível fazer a associação total com o uso de “*” • Exemplo: <jsp:setProperty name=“obj” property=“*” /> • A comparação dos nomes é sensível a maiúsculas e minúsculas 7 Exemplos Exemplo1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // Fig. 10.17: Rotator.java // A JavaBean that rotates advertisements. package com.deitel.advjhtp1.jsp.beans; public class Rotator { private String images[] = { "images/jhtp3.jpg", "images/xmlhtp1.jpg", "images/ebechtp1.jpg", "images/iw3htp1.jpg", "images/cpphtp3.jpg" }; private String links[] = { "http://www.amazon.com/exec/obidos/ASIN/0130125075/" + "deitelassociatin", "http://www.amazon.com/exec/obidos/ASIN/0130284173/" + "deitelassociatin", "http://www.amazon.com/exec/obidos/ASIN/013028419X/" + "deitelassociatin", "http://www.amazon.com/exec/obidos/ASIN/0130161438/" + "deitelassociatin", "http://www.amazon.com/exec/obidos/ASIN/0130895717/" + "deitelassociatin" }; Bean Rotator destinado a manter um contador sobre a íde publicidade (Parte 1). Linhas 25-28 Linhas 31-34 private int selectedIndex = 0; // returns image file name for current ad public String getImage() { return images[ selectedIndex ]; } // returns the URL for ad's corresponding Web site public String getLink() { return links[ selectedIndex ]; } Retorna o nome do ficheiro que servirá para a imagem do livro Retorna o hyperlink para o livro em Amazon.com 8 36 37 38 39 40 41 42 // update selectedIndex so next calls to getImage and // getLink return a different advertisement public void nextAd() { selectedIndex = ( selectedIndex + 1 ) % images.length; } } Altera o estado de Rotator para que chamadas seguintes a Fig. 10.17 Rotator getImage and getLink bean that maintains a return information for set of advertisements different advertisements (Part 2). Lines 38-41 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 10.18: adrotator.jsp --> <jsp:useBean id = "rotator" scope = "application" class = "com.deitel.advjhtp1.jsp.beans.Rotator" /> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>AdRotator Example</title> <style type = "text/css"> .big { font-family: helvetica, arial, sans-serif; font-weight: bold; font-size: 2em } </style> <%-- update advertisement --%> <% rotator.nextAd(); %> </head> <body> <p class = "big">AdRotator Example</p> <p> <a href = "<jsp:getProperty name = "rotator" property = "link" />"> adrotator.jsp Usa o componente Rotator Use jsp:useBean para uma action to mostrar obtain reference distinta cada toimagem Rotator object vez que é feita uma chamada à página (Parte 1). Linhas 7-8 Linhas 22 Linhas 29-23 Invoke Rotator’s nextAd method Define hyperlink to Amazon.com site <img src = "<jsp:getProperty name = "rotator" property = "image" />" alt = "advertisement" /> </a> </p> 9 36 37 </body> </html> adrotator.jsp Usa o componente Rotator para mostrar uma imagem distinta cada vez que é feita uma chamada à página (Parte 2). Exemplos Exemplo2 10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 // Fig. 10.20: GuestBean.java // JavaBean to store data for a guest in the guest book. package com.deitel.advjhtp1.jsp.beans; public class GuestBean { private String firstName, lastName, email; // set the guest's first name public void setFirstName( String name ) { firstName = name; } // get the guest's first name public String getFirstName() { return firstName; } GuestBean armazena a informação sobre um utilizador (Parte 1). Linha 6 GuestBean define três propriedades: firstName, lastName e email // set the guest's last name public void setLastName( String name ) { lastName = name; } // get the guest's last name public String getLastName() { return lastName; } // set the guest's email address public void setEmail( String address ) { email = address; } // get the guest's email address public String getEmail() { return email; } Fig. 10.20 GuestBean stores information for one guest (Part 2). } 11 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 // Fig. 10.21: GuestDataBean.java // Class GuestDataBean makes a database connection and supports // inserting and retrieving data from the database. package com.deitel.advjhtp1.jsp.beans; // Java core packages import java.io.*; import java.sql.*; import java.util.*; public class GuestDataBean { private Connection connection; private PreparedStatement addRecord, getRecords; // construct TitlesBean object public GuestDataBean() throws Exception { // load the Cloudscape driver Class.forName( "COM.cloudscape.core.RmiJdbcDriver" ); // connect to the database connection = DriverManager.getConnection( "jdbc:rmi:jdbc:cloudscape:guestbook" ); getRecords = connection.prepareStatement( "SELECT firstName, lastName, email FROM guests" ); GuestDataBean realiza o acesso a base de dados sob o comando de guestBookLogin.jsp (Parte 1). Linhas 22-23 GuestDataBean liga-se a base de dados to guestbook addRecord = connection.prepareStatement( "INSERT INTO guests ( " + "firstName, lastName, email ) " + "VALUES ( ?, ?, ? )" ); } // return an ArrayList of GuestBeans public ArrayList getGuestList() throws SQLException { ArrayList guestList = new ArrayList(); // obtain list of titles ResultSet results = getRecords.executeQuery(); // get row data while ( results.next() ) { GuestBean guest = new GuestBean(); guest.setFirstName( results.getString( 1 ) ); guest.setLastName( results.getString( 2 ) ); guest.setEmail( results.getString( 3 ) ); GuestDataBean realiza o acesso a base de dados sob o comando de guestBookLogin.jsp (Parte 2). Linhas 39-68 GuestDataBean disponibliza métodos que permitem o acesso a base de dados (getGuestList e addGuest) guestList.add( guest ); } return guestList; } // insert a guest in guestbook database public void addGuest( GuestBean guest ) throws SQLException { addRecord.setString( 1, guest.getFirstName() ); addRecord.setString( 2, guest.getLastName() ); addRecord.setString( 3, guest.getEmail() ); addRecord.executeUpdate(); } 12 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 // close statements and terminate database connection protected void finalize() { // attempt to close database connection try { getRecords.close(); addRecord.close(); connection.close(); } GuestDataBean realiza o acesso a base de dados sob o comando de guestBookLogin.jsp (Parte 3). // process SQLException on close operation catch ( SQLException sqlException ) { sqlException.printStackTrace(); } } } <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 10.22: guestBookLogin.jsp --> <%-- page settings --%> <%@ page errorPage = "guestBookErrorPage.jsp" %> <%-- beans used in this JSP --%> <jsp:useBean id = "guest" scope = "page" class = "com.deitel.advjhtp1.jsp.beans.GuestBean" /> <jsp:useBean id = "guestData" scope = "request" class = "com.deitel.advjhtp1.jsp.beans.GuestDataBean" /> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Guest Book Login</title> Directiva page page JavaServer define informação que é guestBookdisponbilizada na JSP permite Login.jsp introduzir três parametros que Acção jsp:useBean serãoobter armazenados permite uma numaaos base de dados referencia objectos (Parte1) GuestBean e GuestDataBean Linha 8 Linha 11-14 <style type = "text/css"> body { font-family: tahoma, helvetica, arial, sans-serif; } table, tr, td { font-size: .9em; border: 3px groove; padding: 5px; background-color: #dddddd; } </style> </head> 13 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 <body> <jsp:setProperty name = "guest" property = "*" /> As propriedade de JavaServer são page GuestBean guestBookcopiadas dos valores Login.jsp permite contidos nos parâmetros introduzir análogostrês parametros que serão armazenados numa base de dados (Parte2) <% // start scriptlet if ( guest.getFirstName() == null || guest.getLastName() == null || guest.getEmail() == null ) { %> <%-- end scriptlet to insert fixed template data --%> <form method = "post" action = "guestBookLogin.jsp"> <p>Enter your first name, last name and email address to register in our guest book.</p> <table> <tr> <td>First name</td> Linha 36 <td> <input type = "text" name = "firstName" /> </td> </tr> <tr> <td>Last name</td> <td> <input type = "text" name = "lastName" /> </td> </tr> <tr> <td>Email</td> <td> <input type = "text" name = "email" /> </td> </tr> <tr> <td colspan = "2"> <input type = "submit" value = "Submit" /> </td> </tr> </table> </form> JavaServer page guestBookLogin.jsp permite introduzir três parametros que serão armazenados numa base de dados (Parte3) <% // continue scriptlet } // end if else { guestData.addGuest( guest ); Linha 93 %> <%-- end scriptlet to insert jsp:forward action --%> <%-- forward to display guest book contents --%> <jsp:forward page = "guestBookView.jsp" /> <% // continue scriptlet } // end else Redereciona o pedidos para guestBookView.jsp %> <%-- end scriptlet --%> </body> </html> 14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 10.23: guestBookView.jsp --> <%-- page settings --%> <%@ page errorPage = "guestBookErrorPage.jsp" %> <%@ page import = "java.util.*" %> <%@ page import = "com.deitel.advjhtp1.jsp.beans.*" %> Directiva page page JavaServer guestBookimport indica quais os packages View.jsp e classes quemostra o conteudo são utilizados no do livro de visitas (Parte 1). contexto da JSP <%-- GuestDataBean to obtain guest list --%> <jsp:useBean id = "guestData" scope = "request" class = "com.deitel.advjhtp1.jsp.beans.GuestDataBean" /> <html xmlns = "http://www.w3.org/1999/xhtml"> Acção jsp:useBean Linhas 9-10 permite obter uma referencia para Linhas 13-14 GuestDataBean <head> <title>Guest List</title> <style type = "text/css"> body { font-family: tahoma, helvetica, arial, sans-serif; } table, tr, td, th { text-align: center; font-size: .9em; border: 3px groove; padding: 5px; background-color: #dddddd; } </style> </head> <body> <p style = "font-size: 2em;">Guest List</p> <table> <thead> <tr> <th style = "width: 100px;">Last name</th> <th style = "width: 100px;">First name</th> <th style = "width: 200px;">Email</th> </tr> </thead> <tbody> <% // start scriptlet JavaServer page guestBookView.jsp mostra o conteudo do livro de visitas (Parte 2). Linhas 50-68 Scriptlet mostra lista de last name, first name e email para List guestList = guestData.getGuestList(); Iterator guestListIterator = guestList.iterator(); GuestBean guest; while ( guestListIterator.hasNext() ) { guest = ( GuestBean ) guestListIterator.next(); %> <%-- end scriptlet; insert fixed template data --%> <tr> <td><%= guest.getLastName() %></td> <td><%= guest.getFirstName() %></td> <td> <a href = "mailto:<%= guest.getEmail() %>"> <%= guest.getEmail() %></a> </td> </tr> 15 71 72 73 74 75 76 77 78 79 80 81 82 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <% // continue scriptlet } // end while %> <%-- end scriptlet --%> </tbody> </table> </body> JavaServer page guestBookView.jsp mostra o conteudo do livro de visitas (Parte 3). </html> <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 10.24: guestBookErrorPage.jsp --> <%-- page settings --%> <%@ page isErrorPage = "true" %> <%@ page import = "java.util.*" %> <%@ page import = "java.sql.*" %> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Error!</title> <style type = "text/css"> .bigRed { font-size: 2em; color: red; font-weight: bold; } </style> </head> Directiva page page JavaServer guestBookErrorisErrorPage indica que View.jsp é chamda guestBookErrorPage é em umaresposta página dea excepções tratamento de errosque possam acontecer em guestBookLogin.jsp e guestBookView.jsp (Parte 1). Linha 8 Linha 31 <body> <p class = "bigRed"> <% // scriptlet to determine exception type // and output beginning of error message if ( exception instanceof SQLException ) %> Uso do objecto implicito exception para determinar o erro que deve ser mostrado An SQLException 16 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 <% else if ( exception instanceof ClassNotFoundException ) %> A ClassNotFoundException <% else JavaServer page Uso do objecto implicito exception para guestBookErrordeterminar o erro que View.jsp é chamda deve ser mostrado %> An exception <%-- end scriptlet to insert fixed template data --%> <%-- continue error message output --%> occurred while interacting with the guestbook database. </p> <p class = "bigRed"> The error message was:<br /> <%= exception.getMessage() %> </p> em resposta a excepções que possam acontecer em guestBookLogin.jsp e guestBookView.jsp (Parte 2). Linha 37 <p class = "bigRed">Please try again later</p> </body> </html> Acção <jsp:useBean> (cont.) 17 Acção <jsp:useBean> (cont.) 18