560 likes | 679 Views
Java Server Pages. 2721- Sistemes Oberts amb Arquitectura J2EE Miquel Mascaró. Un repàs al HTTP. Un repàs al HTTP. GET: Obtenir dades del servidor (1 paquet, direcció + formulari) POST: Canviar dades del servidor (2 paquets, direcció i formulari)
E N D
Java Server Pages 2721- Sistemes Oberts amb Arquitectura J2EE Miquel Mascaró
Un repàs al HTTP • GET: Obtenir dades del servidor (1 paquet, direcció + formulari) • POST: Canviar dades del servidor (2 paquets, direcció i formulari) • Adreça: IP:<port><path> (per defecte el servei web és al port 80)
Aplicació WEB • Tecnologia de client servidor • Antigament serveis amb CGI (perl, c, c++, ...) • Manipulació per Web de les dades de la BD del servidor
Contenidors WEB de J2EE • Administra continguts Web, servlets i planes JSP, a més de qualsevol servei que pugui ser necessari • Els components del contenidor són els responsables de la navegació i presentació de la plana Web • Els servlets són una solució escalable i basada en fils d’execució
Contenidors WEB de J2EE • Servlets: • Són classes Java que implementen la interfícia HttpServlet de l’API java servlet • El mateix contenidor Web proporciona als servlets residència i administració de les sol·licituds • El contenidor Web pot obrir i administrar múltiples servlets (thread per sol·licitud) més rendiment que els processos (fork) de CGI • JSP (no print HTML tags). (MVC: separa contingut de presentació) • EJB: El contenidor Web es comunica amb ell per accedir al contingut empresarial
El model basat en servlets • Servlet simple: El servlet ho te tot, la presentació, la lògica de programa i el codi de navegació. Actualment hi ha solucions millors
El model JSP • JSP: Segueix tenint, la presentació, la lògica de programa i el codi de navegació • Tota l’aplicació està escrita amb planes JSP • Moltes aplicacions actuals segueixen aquest model
El model MVC • Un controlador administra la navegació • Un visor presenta les dades a l’usuari • Un model emmagatzema el conjunt de dades • Presentació de les mateixes dades amb múltiples formats (SWING) • Integrants: • El controlador ve representat per un servlet Java • El contenidor de les dades per un Java Bean (EJB) • La presentació corre a càrrec de les planes JSP • Aquesta arquitectura presenta un únic punt d’entrada • Proporciona una elevada escalabilitat
¿Cóm processa JSP? • Un contenidor Web J2EE te un motor de servlet que és el que oferta el resultat de la plana JSP
¿Cóm processa JSP? • El primer pic que es demana una plana JSP el motor de servlet llegeix l’arxiu i genera el codi del servlet corresponent • El codi es compilat i se inicia el servlet • Sols es torna compilar i reiniciar quan canvia el JSP • Problemes de rendiment: • Si una aplicació Web te moltes JSP la primera persona podria esperar molt de temps • Possibilitat de compilar prèviament • Així també se eviten errors a les planes • A la primera execució es crida a _jspInit() • Un cop executat es crida a _jspService() • Al final del servei es crida a _jspDestroy()
¿Cóm processa JSP? • Els mètodes _jspInit() i _jspDestroy() es poden anular a la declaració de la plana JSP • El mètode _jspService() és generat pel sistema i no es pot anular. Conté el cos de la plana JSP <% public void jspInit() { // inicialitzacions (DB, connexions de recursos) } public void jspDestroy() { // tancar els recursos i netejar el sistema d’arxius } %>
Estructura de les planes JSP • A més del codi HTML una plana JSP conté una sèrie de directives, declaracions, expressions i guions • Cada element es pot expressar en sintaxis JSP estàndard o en sintaxi XML • No es poden mesclar les sintaxis a un mateix document JSP
Estructura de les planes JSP: Directives • Apareixen al principi de la plana JSP • Contenen instruccions especials pel contenidor Web. Exemple: <%@ page import=“java.util.Date, java.io.*” extends=“myJSPpage” buffer=“32k” autoflush=“false” %> <jsp:directive.page import=“java.util.Date, java.io.*” extends=“myJSPpage” buffer=“32k” autoflush=“false” />
Estructura de les planes JSP: Directives • Una altra directiva important és la de inclusió. Exemple: <%@ include file=“/mapes/mallorca.html” %> <jsp:directive.include file =“/mapes/mallorca.html” />
Estructura de les planes JSP: Declaracions • Comencen amb l’etiqueta <%! i acaben amb %> . Exemple: <%! int area = 0; %> <%! public int retornaArea() { return area; } %> <jsp:declaration> public int retornaArea() { return area; } </jsp:declaration>
Estructura de les planes JSP: Expressions • S’empren per executar continguts dinàmics dins les planes JSP. Exemple (dues alternatives): El total de l’àrea és: <%= getArea() %>. Ja està <% StringBuffer sb=new StringBuffer(); sb.append(“El total de l’àrea és: “); sb.append(getArea()); sb.append(“. Ja està”); out.println(sb.toString()); %> • Amb XML, <jsp:expression> i </jsp:expression> per <%= i %>
Estructura de les planes JSP: Scriplets • Es poden emprar a qualsevol lloc de la plana • Són bocins de Java que apareixen inserits al mètode jspService() del servlet generat <% for (int i=0; i<23; i++) { out.println(i); out.println(“<br>”); //bot de línia HTML } %> <jsp:scriplet> for (int i=0; i<23; i++) { out.println(i); out.println(“<br>”); //bot de línia HTML } </jsp:scriplet>
Entorn de desenvolupament • Es convenient emprar un IDE integrat de desenvolupament • Escollir un servidor d’aplicacions: • Comercial: (IBM, Iplanet, BEA, etc) • Software lliure: JBoss per EJB i Tomcat com a contenidor Web • Escollir un SGBD. Per exemple MySQL • Netbeans enterprise que és lliure és una bona opció per tenir tot el necessari per programar aplicacions JSP
El servidor Tomcat • Es un contenidor de servlet de codi obert que es pot trobar a http://www.jakarta.apache.org • Si no usam el del netbeans o quan hem acabat de desenvolupar, haurem d’instal·lar un Tomcat per posar l’aplicació Web operativa
Configuració del servidor Tomcat • Configurar els scripts d’inici a \bin • Configurar (si cal) l’arxiu server.xml a \conf • Des de el directori \webapps cal crear la següent estructura: \webapps \meu_dir \WEB-INF \lib
Configuració del servidor Tomcat • Afegir a l’arxiu server.xml el següent: <context path=“meu_dir” docBase=“webapps/meu_dir” crossContext=“true” debog=“0” reloadable=“true” trusted=“false” </context> • Així l’adreça http//localhost:8080/meu_dir ja es accessible amb un visor Web
Configuració del servidor Tomcat • Es poden posar utilitats comunes al servidor Tomcat al directori de llibreries comunes • Un exemple d’això és el connector de Java per a un SGBD
Una simple aplicació JSP • Dissenyar una plana HTML preparant el lloc que ocuparan les dades dinàmiques • Un cop dissenyada la plana HTML cal obrir l’arxiu per incorporar el codi JSP • Incorporam la llibreria de connexió amb un SGBD <%@ page import=“java.sql.*” %> • Declaram una variable ResultSet per tenir-la disponible a tota la plana JSP <%! ResultSet rs = null; %>
Una simple aplicació JSP • Cream la connexió a la BD i consultam dades • Suposam un SGBD MySql i empram el JDBC per connectar amb ell (connector) <% try { Class.forName(“org.gjt.mm.mysql.Driver”); Connection db = DriverManager.getConnection( “jdbc:mysql://localhost:3306/lamevabase”); Statement s = db.createStatement(); rs = s.executeQuery(“Select * from persones”); } catch (Exception e) { System.out.println(e.toString()); } %>
Una simple aplicació JSP • Mostram la consulta a la plana JSP <% try { while (rs.next()) { %> ......... CODI HTML ....... ..... <%= rs.getString(1) %> i <%= rs.gerInt(2) ... <% } } catch (SQLException e) { System.out.println(e.toString()); } %>
Gestió d’errors (informe) • JSP permet quan es produeix un error no especificat, redirigir el flux d’execució a una plana d’error • Una plana d’error hauria de: • Agafar l’excepció i reportar-la a l’administrador • Notificar a l’usuari de l’error succeït • El primer que cal fer és declarar la plana com a plana d’error (directiva) <%@ page isErrorPage=“true” %>
Gestió d’errors (informe) • És útil informar també de la plana que ha produït l’excepció (getParameter()) <% String from= (String) request.getParameter(“from”); %> • L’objecte excepció és implícit per les planes declarades com a error (no cal declarar-lo) <%@ page isErrorPage=“true” %> • Vegem a continuació una simple plana d’error a on observar els detalls esmentats
Gestió d’errors (informe) • Plana “myError.jsp”: <%@ page isErrorPage=“true”; %> <html> <head> <title> Error! </title> </head> <body> <br> <% String from= (String) request.getParameter(“from”); %> Ha ocorregut un error a la plana <b> <%= from %> </b>. <br> L’excepció és: <b> <%= exception %> </b> <!-- Aquí enviam l’informe a l’administrador --> <% System.out.println(exception.toString()); %> </body> </html>
Gestió d’errors (emissió) • Quan es te definida una plana d’error cal invocar-la des de les altres quan aquest hi sigui • Això es fa amb la directiva errorPage • Com podeu observar a sota cal declarar el paràmetre de l’origen de l’error • Plana “actual.jsp”: <%@ page import=“java.sql.*” %> <%@ page errorPage=“myError.jsp?from=actual.jsp” %> <html> <head> ...
Inclusió d’arxius • Sovint a una aplicació web hi sol haver repeticions: • Capçaleres • Peus de plana • Menús • Continguts estàtics • Continguts dinàmics • Si aquest continguts es posen a un altre lloc, per separat, apareixen problemes: • Manteniment dificultós • Falta d’integritat (uns es modifiquen i els altres no) • La solució òptima és incloure aquestes dins la JSP
Inclusió d’arxius • La inclusió d’arxius es pot dur a terme: • En temps de compilació (Estàtic) • En temps d’execució (Dinàmic) • En temps de compilació: <%@ include file=“meuArxiu.html” %>
Inclusió d’arxius • En temps d’execució: < jsp:include page=“meuinclos.jsp” flush=“true” > <jsp:param name=“area” value=34” /> < /jsp:include > flush=“true”: indica al motor de servlet que ha d’activar el buffer de sortida abans d’incloure l’arxiu
Processar formularis • A una aplicació J2EE el formulari es pot enviar a: • Un servlet • Una plana JSP • La plana JSP recupera les dades de l’usuari emprant l’objecte request (objecte implícit) • El servlet recupera les dades de l’usuari emprant l’objecte HttpServletRequest • Els mètodes declarats als dos objectes són els mateixos • El mètode més important de request és getParameter <% String nom = request.getParameter(“nom_parametre”); %>
Processar formularis • request amb un camp de múltiples valors: <% String noms[] = request.getParameterValues(“multiple”); for (int i=0; i<noms.lenght; i++) { out.println(“Nom: “ + noms[i]); // sol ser la plana web } %> • Captar els noms dels paràmetres: <% java.util.enumeration noms = request.getParameterNames(); while (noms.hasMoreElements()) { String nom = (String) noms.nextElement(); out.println(nom + “: “ + request.getParameter(nom); } %>
Mantenim de l’estat de l’aplicació • El HTTP no té funcions de manteniment de l’estat d’una plana a una altra • Per guardar el manteniment de l’estat amb JSP ho podem fer de dues formes: • Mitjançant l’ús d’una base de dades • Utilitzant una coockie de sessió • L’objecte session: • Únic per a cada usuari. Administrat pel contenidor del servlet • Cada sessió té un identificador d’usuari • Les dades circulen entre l’usuari i el servlet de la JSP mitjançant una coockie (implícita en alguns entorns) • <% HttpSession sessio = request.getSession(true); %>
Mantenim de l’estat de l’aplicació • Amb l’objecte session es poden obtenir, escriure i esborrar atributs • Cada atribut té un nom clau • Per escriure s’utilitza el mètode setAttribute • <% sessio.setAttribute(“nom”,”Antoni”); %> • Per obtenir s’utilitza el mètode getAttribute • <% String pal = sessio.getAttribute(“nom”); %> • Per esborrar s’utilitza el mètode removeAttribute • <% sessio.removeAttribute(“nom”); %>
Un exemple complet d’això • Formulari que accepta el nom d’una persona • Enviam les dades a una plana JSP que crearà la sessió amb les dades • Hi haurà dos vincles més a dues planes JSP que recuperaran i mostraran la informació
Un exemple complet d’això • sessionExample.html: <html> <head> <title> Sessió d’exemple </title> </head> <body> </center> <h1> Exemple de sessió </h1> <form action=“sessionExample.jsp”> NOM: <input type=“Text” name=“nom”/> <br> <input Type=“Submit” value=“submit” /> </form> </center> </body> </html>
Un exemple complet d’això • sessionExample.jsp: <html> <head> <title> Sessió d’exemple </title> </head> <body> <% String val=request.getParameter(“nom”); if (val != null) session.SetAttribute(“nom”,val); %> <center> <h1> Exemple de sessió </h1> Indica la plana a la que vols anar: <a href=“sessionExamplePage1.jsp”> plana 1 </a> <a href=“sessionExamplePage2.jsp”> plana 2 </a> </center> /body> </html>
Un exemple complet d’això • sessionExamplePage1.jsp i sessionExamplePage2.jsp: <html> <head> <title> Sessió d’exemple </title> </head> <body> <center> Hola <%= session.getAttribute(“nom”) %> , benvingut a la plana 1. </center> </body> </html> <html> <head> <title> Sessió d’exemple </title> </head> <body> <center> Hola <%= session.getAttribute(“nom”) %> , benvingut a la plana 2. </center> </body> </html>
Comunicació applet servlet • Un applet no te privilegis per dur a terme la majoria de tasques • Usant una comunicació applet – servlet podem: • Realitzar les tasques en un servlet (si té privilegis) • Emprar interfícies swing avançades a les aplicacions web • A la seguent adreça podem veure un exemple complet de comunicació applet – servlet: http://mindy.cs.bham.ac.uk/AppletServletExample/ (si no funciona el link ho teniu com a rar a la web)
Introducció als JavaBean • Separar el disseny de la plana de la funcionalitat • Són classes de Java amb propietats i mètodes • Implementen la interfícia Serializable • Components no visuals que oculten les dades i les operacions entre aquestes • Al poder proporcionar etiquetes suplementaris el dissenyador pot accedir al codi del Bean sense necessitat de manipular codi Java • Juguen un paper fonamental a l’estructura MVC • Emmagatzemen el model i les dades d’una aplicació
Introducció als JavaBean • Recordem el MVC:
Introducció als JavaBean • La plana JSP presenta les dades contingudes dins el model. El model s’actualitza pel propi Bean o per una operació externa
Introducció als JavaBean • SimpleBean.java package mevesbean; public class simpleBean implements java.io.Serializable { // variables de la component private String lname; private String fname; // Inicialitzem les propietats public simpleBean() { setLname(“”); setFname(“”); } ...