JSP (JavaServer Pages) es una tecnología que permite incluir código Java en páginas web. El denominado contenedor JSP (que ser�a un componente del servidor web) es el encargado de tomar la página, sustituir el código Java que contiene por el resultado de su ejecución, y enviarla al cliente. Así, se pueden diseñar fácilmente páginas con partes fijas y partes variables. El siguiente es un ejemplo muy sencillo de página JSP:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Mi primera página JSP</title> </head> <body> <h1> Hoy es: <%= new java.util.Date() %> </h1> </body> </html>
Para ejecutar la página basta con colocarla en una aplicación
web (por ejemplo, en Tomcat, dentro de webapps/ROOT
). No es necesario
que sea en un directorio específico como ocurre con los servlets, sino
que puede ir en cualquier directorio en el que se colocaría normalmente
un HTML.
La última versión de la especificaci�n JSP es la 2.0, aunque es de reciente aparición (Tomcat 4.x implementa la versión anterior, la 1.2, misma que cubre este tema). Como se ver�, es una especificaci�n paralela al API de servlets, concretamente a la versi�n 2.3. Se puede encontrar m�s informaci�n sobre JSP en
Aunque JSP y servlets parecen a primera vista tecnologías distintas,
en realidad el servidor web traduce internamente el JSP a un servlet, lo compila
y finalmente lo ejecuta cada vez que el cliente solicita la página JSP.
Por ello, en principio, JSPs y servlets ofrecen la misma funcionalidad, aunque
sus características los hacen apropiados para distinto tipo de tareas.
Los JSP son mejores para generar páginas con gran parte de contenido
estático. Un servlet que realice la misma función debe incluir
gran cantidad de sentencias del tipo out.println()
para producir
el HTML. Por el contrario, los servlets son mejores en tareas que generen poca
salida, datos binarios o páginas con gran parte de contenido variable.
En proyectos más complejos, lo recomendable es combinar ambas tecnologías:
los servlets para el procesamiento de información y los JSP para presentar
los datos al cliente.
Como se ha comentado, la primera vez que se solicita una p�gina JSP, el servidor genera el servlet equivalente, lo compila y lo ejecuta. Para las siguientes solicitudes, solo es necesario ejecutar el c�digo compilado. El servlet generado de manera autom�tica tiene un m�todo _jspService
que es el equivalente al service
de los servlets "generados manualmente". En este m�todo es donde se genera el c�digo HTML, mediante instrucciones println
y donde se ejecuta el c�digo Java insertado en la p�gina. Por ejemplo, la p�gina primera.jsp podr�a generar un servlet con estructura similar al siguiente:
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspWriter out = null; response.setContentType("text/html;ISO-8859-1"); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">); out.println("<html>"); out.println("<head>"); out.println("<title>Mi primera pagina JSP</title>"); out.println("</head>"); out.println("<body>"); out.print("Hoy es "); out.println(new java.util.Date()); out.println("</body>"); out.println("</html>"); }
El directorio donde se coloca el servlet generado, as� como su nombre, dependen del servidor web. Por ejemplo, Tomcat utiliza su directorio work/localhost/aplicacion_web
. En caso de que la p�gina est� en ROOT
, el nombre de la aplicaci�n se sustituye por un car�cter de subrayado (_
).
Existen tres tipos de elementos JSP que podemos insertar en una p�gina web:
Se pueden poner comentarios en una p�gina JSP entre los s�mbolos <%--
y --%>
. El contenedor JSP ignorar� todo lo contenido entre ambos. Dentro de los fragmentos de c�digo Java tambi�n se pueden colocar comentarios siguiendo la sintaxis habitual del lenguaje.
Hay tres formas de insertar c�digo Java en una p�gina JSP:
<%= expresi�n %>
: en este caso, la expresi�n se eval�a, su resultado se convierte a String
y se inserta en la salida. <% c�digo %>
_jspService
del servlet generado.
<%! c�digo %>
: se insertan en el cuerpo del servlet generado, fuera de sus m�todos.
Como se ha visto, se eval�an, su resultado se convierte a un String
y se escriben en la salida (el objeto predefinido out
). La forma de traducir una expresi�n a c�digo de servlet es imprimi�ndola en out
(mediante una sentencia out.write(expresion)
) o similar.
Permiten ejecutar c�digo arbitrario, cuyo resultado no es necesario enviar a la salida. Si desde un scriptlet se desea escribir algo en �sta, bastar� con utilizar el objeto predefinido out
. Un uso com�n de los scriptlets es hacer que ciertas partes de c�digo HTML aparezcan o no en funci�n de una condici�n. Por ejemplo:
<% java.util.Calendar ahora = java.util.Calendar.getInstance(); int hora = ahora.get(java.util.Calendar.HOUR_OF_DAY); %> <b> Hola mundo, <i> <% if ((hora>20)||(hora<6)) { %> buenas noches <% } else if ((hora>=6)&&(hora<=12)) { %> buenos d�as <% } else { %> buenas tardes <% } %> </i> </b>
Permiten definir variables o m�todos que se insertar�n dentro del cuerpo del servlet generado. Esto da la posibilidad de sobreescribir los m�todos jspInit
y jspDestroy
que son el equivalente en JSP del init
y destroy
de los servlets. Las variables declaradas conservar�n su valor entre sucesivas llamadas a la p�gina, ya que son variables miembro del servlet y no locales al m�todo jspService
. Esto nos permite, por ejemplo, crear un contador de accesos a la p�gina:
<%! private int accesos = 0; %> <h1> Visitas: <%= ++accesos %> </h1>
En cualquiera de estas tres formas, se puede hacer referencia a una serie de objetos impl�citos , que se corresponden con objetos �tiles del API de servlets (petici�n, respuesta, ...) y que en realidad son variables instanciadas de manera autom�tica en el servlet generado a partir del JSP. Los objetos predefinidos en JSP se referencian en la tabla 1.
Objeto | Significado |
---|---|
request |
el objeto HttpServletRequest asociado con la petici�n |
response |
el objeto HttpServletResponse asociado con la respuesta |
out |
el Writer empleado para enviar la salida al cliente. La salida de los JSP emplea un buffer que permite que se env�en cabeceras HTTP o c�digos de estado aunque ya se haya empezado a escribir en la salida (out no es un PrintWriter sino un objeto de la clase especial JspWriter ). |
session |
el objeto HttpSession asociado con la petici�n actual. En JSP, las sesiones se crean autom�ticamente, de modo que este objeto est� instanciado aunque no se cree expl�citamente una sesi�n. |
application |
el objeto ServletContext , com�n a todos los servlets de la aplicaci�n web. |
config |
el objeto ServletConfig , empleado para leer par�metros de inicializaci�n. |
pageContext |
permite acceder desde un �nico objeto a todos los dem�s objetos impl�citos |
page |
referencia al propio servlet generado (tiene el mismo valor
que this ).Como tal, en Java no tiene demasiado sentido utilizarla,
pero est� pensada para el caso en que se utilizara un lenguaje de programaci�n
distinto. |
exception |
Representa un error producido en la aplicaci�n. Solo es accesible si la p�gina se ha designado como p�gina de error (mediante la directiva page isErrorPage ). |
Las directivas influyen en la estructura que tendr� el servlet generado a partir de la p�gina JSP. Hay tres tipos de directivas:
page
: tiene varios usos: importar clases de Java, fijar el
tipo MIME de la respuesta, controlar el buffer de salida,...include
: sirve para incluir código en la página
antes de que se realice la compilación del JSP.taglib
: se emplea cuando el JSP hace uso de etiquetas definidas
por el usuario.El formato genérico de una directiva es:
<%@ directiva atributo="valor" %>
algunas directivas admiten más de un atributo.
page
La tabla 2 recoge los distintos atributos que admite la directiva page
y su significado.
Atributo | Significado | Ejemplo |
---|---|---|
import |
el equivalente a una sentencia import de Java |
<%@ page import="java.util.Date" %> |
contentType |
genera una cabecera HTTP Content-Type |
<%@ page contentType="text/plain" %> |
isThreadSafe |
si es false , el servlet generado implementará
el interface SingleThreadModel (ún único hilo
para todas las peticiones). Por defecto, el valor es true . |
|
session |
Si es false , no se creará un objeto
session de manera automática. Por defecto, es true . |
|
buffer |
Define el tamaño del buffer para la salida
(en kb), o none si no se desea buffer. Su existencia
permite generar cabeceras HTTP o códigos de estado aunque ya se
haya comenzado a escribir la salida. |
<%@ page buffer="64kb" %> |
autoflush |
Si es true (valor por defecto), el buffer se
env�a autom�ticamente a la salida al llenarse. Si es false ,
al llenarse el buffer se genera una excepci�n. |
|
extends |
Permite especificar de qu� clase debe descender el servlet generado a partir de la p�gina JSP. No es habitual cambiarlo. | |
info |
define una cadena que puede obtenerse a trav�s del m�todo
getServletInfo |
<%@ page info="carro de la compra" %> |
errorPage |
especifica la p�gina JSP que debe procesar los errores generados y no capturados en la actual. | <%@ page errorPage="error.jsp" %> |
isErrorPage |
Si es true , indica que la p�gina act�a como
p�gina de error para otro JSP. El valor por defecto es false . |
|
language |
Permite especificar el lenguaje de programaci�n usado en el JSP. En la pr�ctica, el lenguaje siempre es Java, por lo que esta directiva no se usa. | |
pageEncoding |
define el juego de caracteres que usa la p�gina. El valor
por defecto es ISO-8859-1 . |
En JSP existen varios mecanismos para incluir elementos externos en la p�gina actual o redirigir la petici�n hacia otra p�gina
include
permite insertar c�digo en la
p�gina antes de que �sta se transforme en un servlet. De este modo se pueden
reutilizar fragmentos de c�digo JSP o HTML. <jsp:include>
<jsp:plugin>
permite incluir applets
que hagan uso de Java 2. <jsp:forward>
sirve para redirigir
la petici�n a otra p�gina JSPinclude
Es el equivalente al #include
del lenguaje C. su sintaxis es:
<%@ include file="fichero" %>
Como el c�digo se incluye en el servlet generado, los fragmentos de c�digo incluidos pueden tener efecto sobre la p�gina actual. As�, se puede utilizar esta directiva para definir constantes, generar cabeceras HTTP, ...
El problema de esta directiva es que el est�ndar no exige que el contenedor JSP detecte de manera autom�tica los cambios en los ficheros incluidos, de manera que si cambia uno de ellos puede ser necesario forzar la recompilaci�n de las p�ginas JSP que los incluyan.
La especificaci�n JSP recomienda que si la p�gina incluida no es una p�gina
JSP v�lida por s� sola (por ejemplo, porque utiliza variables que se conf�a
que se hayan declarado previamente) se utilice la extensi�n "est�ndar" .jspf
(JSP fragment) y se coloque en un directorio no p�blico del contenedor
JSP (por ejemplo, WEB-INF, que no es accesible desde el cliente, pero s� desde
la directiva).
<jsp:include>
Esta acci�n incluye en una p�gina la salida generada por otra perteneciente a la misma aplicaci�n web. La petici�n se redirige a la p�gina incluida, y la respuesta que genera se incluye en la generada por la principal. Su sintaxis es:
<jsp:include page="URL relativa" flush="true|false"/>
El atributo flush
especifica si el flujo de salida de la p�gina
principal deber�a ser enviado al cliente antes de enviar el de la p�gina incluida.
En JSP 1.2 este atributo es optativo, y su valor por defecto es false
.
En JSP 1.1 es obligatorio y siempre deb�a valer true
(el forzar
el vaciado de buffer era problem�tico porque una vez que ha sucedido esto
no se pueden hacer redirecciones ni ir a p�ginas de error, ya que ya se han
terminado de escribir las cabeceras).
Esta acci�n presenta la ventaja sobre la directiva del mismo nombre de que
cambios en la p�gina incluida no obligan a recompilar la "principal". No obstante,
la p�gina incluida solo tiene acceso al JspWriter
de la "principal"
y no puede generar cabeceras (por ejemplo, no puede crear cookies).
Por defecto, la petici�n que se le pasa a la p�gina incluida es la original,
pero se le pueden agregar par�metros adicionales, mediante la etiqueta jsp:param
.
Por ejemplo:
<jsp:include page="cabecera.jsp"> <jsp:param name="color" value="YELLOW" /> </jsp:include>
<jsp:plugin>
Esta acci�n sirve para incluir, de manera portable e independiente del navegador, applets que utilicen alguna librer�a de Java 2 (Swing, colecciones, Java 2D, ...), ya que las m�quinas virtuales Java distribuidas con algunos navegadores relativamente antiguos (Explorer 5.x, Netscape 4.x,...) son de una versi�n anterior a Java 2.
<jsp:forward>
Esta acci�n se utiliza para redirigir la petici�n hacia otra p�gina JSP que est� en la misma aplicaci�n web que la actual. Un ejemplo de su sintaxis b�sica es:
<jsp:forward page="principal.jsp"/>
La salida generada hasta el momento por la página actual se descarta (se borra el buffer). En caso de que no se utilizara buffer de salida, se produciría una excepción.
Al igual que en el caso de <jsp:include>
, se pueden a�adir
par�metros a la petici�n original para que los reciba la nueva p�gina JSP:
<jsp:forward page="principal.jsp"> <jsp:param name="privilegios" value="root" /> </jsp:forward>