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 versión actual de la especificación JSP, y la que cubren estos apuntes, es la 1.2. (aunque existe una beta de la versión 2.0) 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 ). |