====== JSPs ====== ===== Tipos de etiquetas ===== * Comentarios <%-- comentario --%> * Scriptlets (código java) <% if (i == 3) { %> Buenos días <% } %> * Expresiones, llamadas a funciones de java para que lo que estas devuelvan sea insertado en la salida formada. <%= clock.getDayOfMonth() %> Fíjate que no lleva el ';' al final de la línea de código. * Declaraciones de variables <%! int time = Calendar.getInstance().get(Calendar.AM_PM); %> * Acciones Sintaxis: \\ '' \\ '' * Directivas (instrucciones para la compilación de JSP) <%@ page language=="java" imports=="java.util.*" %> <%@ include file=="copyright.html" %> ===== Cómo programar con JSP? ===== * Insertaremos el código JSP entre el html de una página, como si de un .php o un .asp se tratase. * Podríamos llamar a las clases que tenemos en ''WEB-INF'' (aunque no hereden de //HttpServlet// ni estén enlazadas en el fichero //web.xml//) de la misma forma que lo haríamos con una clase normal: ''paquete.clase''. * Si utilizasemos un fichero .jar para el código java externo lo deberemos de colocar en ''WEB-INF/lib''. * La diferencia entre acciones y directivas es que las primeras se ejecutan cuando la página es enviada al cliente, las directivas en cambio se realizan antes de que empiece a procesarse la página. * Para que en las acciones puedan usarse las variables ya declaradas en el código java anterior haremos algo así: //// * Si almacenamos las páginas JSP en WEB-INF no serán directamente accesibles por el cliente pero sí que podremos enviarles a ellas mediante el método ''request.getRequestDispatcher''. Además la dirección mostrada seguirá siendo la del servlet y no verá la dirección real del JSP, con //sendRedirect// no podremos enviarles a una página en WEB-INF (además, en el cliente se actualiza la dirección). response.sendRedirect("WEB-INF/pp.jsp"); request.getRequestDispatcher("WEB-INF/pp.jsp").forward(request, response); Piensa que esto haría que las url de los elementos cambiasen por lo que las direcciones relativas en los links o css ya no serán válidas, tendrás hacer cambios del estilo: //href="download/app.zip"// por //href="/pages/download/app.zip".// ==== Cómo unir todo? ==== - Usaremos beans para representar los datos - Usaremos los servlets para procesar los datos de entrada. - El servlet almacenará\leerá en la Base de Datos o realizará las acciones que deba. - El servlet almacenará los datos de salida en beans que serán introducidos en el contexto debido mediante el //setAttribute//. - El servlet eligirá qué JSP cargar mediante el //forward// del //RequestDispatcher//. - En el JSP mediante el //jsp:getProperty// se mostrarán los datos. * Este procedimiento indica que un bean no debería modificar los datos. ===== La tag de declaraciones ===== El hecho que haya un tag para las declaraciones tiene su motivo bien fundado, por ejemplo, para definir métodos: <%! private String holaIndio () { return "jau!"; } %> <%= holaIndio() %> Piensa que estas declaraciones son estáticas, por lo que si tu declaras una variable y la vas modificando, si se conecta otro usuario se puede topar con que esté modificada. El siguiente código lo demuestra sacando el número de veces que la página ha sido cargada desde que el server se inició: <%! private int accessCount = 0; %> Veces que la página se ha cargado: <%= ++accessCount %> ===== La tag de directivas ===== * //<%@ page import="java.util.*,coreservlets.*" %>// Realiza un import como en un archivo java. * //<%@ page contentType="MIME-Type" %>// Indica el tipo de datos que contiene la página * //<%@ page session="false" %>// Para utilizar esta página en nuestra sesión HTTP o no. Por defecto está a true. * //<%@ page buffer="32kb" %>// Indica el tamaño mínimo del buffer, la página no será enviada al cliente hasta que no lleve formados 32kb o se haga un flush explícito (''response.FlushBuffer''). También podemos indicar que no haya buffer (//<%@ page buffer="none" %>//); esta directiva es útil cuando la página puede tardar un tiempo considerable en formarse. * //<%@ page autoFlush="true" %>// Hace que el flush de una página sea controlado automáticamente o no, por defecto es que sí, true. Ponerlo a flase y poner también el buffer a none no está permitido. * //<%@ page isThreadSafe="true" %>// Indica que la página es segura ante threads. Realmente lo mejor para programar con threads es utilizar código en un bloque synchronized, esto significa que dos threads no podrán entrar a la vez en este bloque hasta que el primero que ha entrado no salga de él. synchronized (this) { out.print(i); } ===== Variables predefinidas ===== Existen objetos que se crean automáticamente al hacerse una llamada a un archivo .jsp, estos sustituyen a los elementos accesibles desde los métodos //doGet// o //doPost// de un Servlet. * **request** (el HttpServletRequest) * **response** (el HttpServletResponse) * **session** (el HttpSession) * **out** (el Writer) * **application** (el ServletContext). El objeto **ServletContext** es un objeto que se comparte entre todos los Servlets y JSP; sirve para almacenar datos que se quedan en el servidor y que pueden ser accedidos desde cualquier Servlet o JSP. Estos datos quedarán guardados hasta que el servidor se reinicie y si ese atributo no ha sido definido lo que devolverá será un //null//. Para utilizarlo debemos hacer uso de sus métodos //getAttribute(String)// y //setAttribute(String, Object)//. Para recogerlo en un servlet tendrás que llamar al método //getServletContext//. * **config** (el ServletConfig) * **pageContext** (el PageContext). El objeto **pageContext** almacena todos los objetos anteriores y los devuelve mediante métodos como //getRequest//, //getResponse//... * **page** Corresponde a la misma página, lo que sería un ''this''. ===== Añadir contenido dinámicamente ===== Podemos añadir contenido de forma dinámica a nuestro JSP. Una de las ventajas que esto nos dá es que podemos montar plantillas para nuestras páginas y no repetir así cabeceras, menús... Podemos insertar el contenido de una página html, el de un documento de texto plano, la salida de otro jsp o la de un servlet. Para añadir contenido utilizamos la acción include: ////. Podemos pasar parámetros a las páginas que incluimos, para ello usaremos el //jsp:param//: Para recoger el valor de bgColor dentro del código de //StandardHeading.jsp// haremos un: //request.getParameter("bgColor")//. Si a la página que ha incluido StandardHeading.jsp también se le han pasado parámetros (no tiene por qué ser por código, sino por dirección, algo así: //direccion?fgColor=WHITE//) estos podrán ser accedidos con el //response.getParameter// desde StandardHeading. Para enviar el contenido de otra página (aunque en la dirección seguirá apareciendo la misma que a la que se llamó) utilizaremos ''jsp:forward'': ===== JavaBeans ===== Son unos tags que equivalen a código java en las páginas JSP. Su sintaxis es muy sencilla, para crear un objeto haremos ////. Jugaremos con la clase Prueba: package pck; public class Prueba { String msg = ""; String name = ""; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ==== Uso ==== * '''' equivale a ''pck.Prueba obj = new pck.Prueba();'', luego podremos hacer: ''<%= obj.getMsg() %>''. Es decir, podremos combinar los distintos tipos de tags. Si queremos jugar con las propiedades de los objetos usados en los beans sus clases tendrán que tener métodos getters y setters. Para ello usamos los tags: //jsp:setProperty// y //jsp:getProperty//, combinando sus atributos: //name// (nombre del objeto), //property// (nombre de la propiedad, sin get ni set y con la primera letra en minusculas) y //value// (el valor, esta sólo para setProperty). * '''' equivale a ''<% obj.setMsg("Mi mama me mima"); %>'' * '''' equivale a ''<%= obj.getMsg() %>'' Imaginemos que la página .jsp que tenemos que llamar para que se ejecute el código es //page.jsp//. Ahora lo que queremos es asignar los parámetros incluidos en la dirección de la página a las propiedades de nuestro objeto, para ello la sintaxis es la siguiente: : * Si llamamos a la página: //page.jsp?m=hola// podremos hacer: ''''. Si por alguna de esas grandes casualidades de la vida, el parámetro pasado se llama igual que la propiedad que queremos asignar sólo tendremos que indicar el atributo //property//: * Si llamamos a la página: //page.jsp?msg=hola// haremos '''' Otro atajo lo encontramos cuando los parámetros que nos vienen en la dirección tienen igual nombre que las propiedades del objeto, sólo tendremos que indicar el property como * y todas quedarán asignadas automáticamente. * Si llamamos a la página: //page.jsp?msg=hola// o //page.jsp?msg=hola&name=juan// haremos '''' Otra de las cosas que podemos hacer es anidarlo todo de la forma siguiente: ==== Scope ==== El //scope// es otro atributo de //jsp:useBean// y se refiere a donde se guardan (y por tanto donde son accesibles), el contexto de los bean. Se usa con la siguiente sintaxis: '''' Tiene cuatro posibles valores: * **page** Valor por defecto, el contexto es la página en sí, es decir, cuando la página se vuelve a cargar el objeto también se vuelve a crear y por lo tanto pierde sus propiedades. Es accesible por los servlets desde el PageContext mediante el getAttribute. * **request** El bean se incluye en el HttpServletRequest, será accesible mientras dure el request y para acceder a él mediante un servlet se usará el getAttribute de este. * **session** El bean se almacenará en el HttpSession y será accesible mientras dure la sesión mediante el parámetro getAttribute. * **application** El bean se almacenará en el ServletContext y será accesible mientras el servidor no se reinicie mediante el getAttribute. ===== Expression Language (EL) ===== Se basa en escribir expresiones en los JSP de forma: //${expresión}//. (Si quisiesemos poner esta sintaxis textualmente haríamos: //\${expresión}//). Podemos desactivar esta característica usando //<%@ page isELEnabled="false" %>// ... pero con lo que mola... Aquí van unos cuantos ejemplos de EL: * ${1+1} * En el servlet: request.setAttribute("hola", "buenos días"); request.getRequestDispatcher("pp.jsp").forward(request, response); En el JSP: ${hola} * Con el ejemplo anterior, el de la clase Prueba, pasándole los parámetros msg y name: ${obj.msg}
${obj.name}
* Podemos también acceder a elementos de una collection (un Array, un ArrayList...) como si accediesemos a un array normal: ${obj.vect[0]} * Podemos usar también operadores como (+, *, div, %, ==, !=, >, <= ...) que devuelven resultados numéricos, booleanos... También podemos usar //empty//, por ejemplo, ''${empty ""}'' devolvería ''true''. O también podriamos usar el: ${expresión ? valor1 : valor2} ${cliente.dinero} * Podemos acceder a los parámetros usando //${param.nombre del parámetro}//: ''${param.msg}'' ===== Archivos ===== * {{sp:jsp:javaserver_pages_a_developer_s_perspective.pdf|JSP a developers perspective}}