Bienvenido al Tutorial de Ejemplo JSP para Principiantes. En los últimos posts, escribí mucho sobre Java Servlet y recibí muy buena respuesta de nuestros lectores. Así que he comenzado otra serie sobre tutoriales de JSP y este es el primer post de la serie.
Tutorial de Ejemplo JSP
En este tutorial de ejemplo JSP, veremos los conceptos básicos de JSP, ventajas de JSP sobre Servlets, Ciclo de Vida de JSP, interfaces y Clases de API de JSP y dónde podemos colocar archivos JSP en la aplicación web. También veremos los Comentarios JSP, Scriptlets, Directivas, Expresiones, Declaraciones y atributos JSP en detalle breve. Algunos de estos temas son muy importantes y los veremos con más detalle en futuros posts.
Tutorial JSP
- ¿Qué es JSP y por qué necesitamos JSP?
- ¿Ventajas de JSP sobre Servlets?
- Ciclo de vida de la página JSP
- Métodos del ciclo de vida de JSP
- Ejemplo simple de JSP con Eclipse y Tomcat
- Ubicación de archivos JSP en el archivo WAR de la aplicación web
- Interfaces y clases de API de JSP
- Interfaz JspPage
- Interfaz HttpJspPage
- Clase abstracta JspWriter
- Clase abstracta JspContext
- Clase abstracta PageContext
- Clase abstracta JspFactory
- Clase abstracta JspEngineInfo
- Clase final ErrorData
- Clase JspException
- Clase JspTagException
- Clase SkipPageException
-
Código fuente del Servlet transformado de JSP y ubicación del archivo de clase en Tomcat
-
¿Qué es JSP y por qué necesitamos JSP?
JSP (JavaServer Pages) es una tecnología del lado del servidor para crear aplicaciones web dinámicas en Java. JSP puede considerarse como una extensión de la tecnología servlet porque proporciona funciones para crear fácilmente vistas de usuario. Una página JSP consta de código HTML y ofrece la opción de incluir código Java para contenido dinámico. Dado que las aplicaciones web contienen muchas pantallas de usuario, se utilizan mucho las JSP. Para cerrar la brecha entre el código Java y HTML en JSP, proporciona características adicionales como etiquetas JSP, lenguaje de expresión y etiquetas personalizadas. Esto facilita la comprensión y ayuda a un desarrollador web a desarrollar rápidamente páginas JSP.
-
Ventajas de JSP sobre Servlets?
- También podemos generar una respuesta HTML desde servlets, pero el proceso es engorroso y propenso a errores. Cuando se trata de escribir una respuesta HTML compleja, escribir en un servlet puede convertirse en una pesadilla. JSP ayuda en esta situación y nos proporciona flexibilidad para escribir una página HTML normal e incluir nuestro código Java solo donde sea necesario.
- JSP proporciona características adicionales como bibliotecas de etiquetas, lenguaje de expresión, etiquetas personalizadas que ayudan en el desarrollo más rápido de vistas de usuario.
- Las páginas JSP son fáciles de implementar, solo necesitamos reemplazar la página modificada en el servidor y el contenedor se encarga de la implementación. Para servlets, necesitamos recompilar e implementar todo el proyecto nuevamente. De hecho, los servlets y JSP se complementan entre sí. Deberíamos usar Servlet como controlador del lado del servidor y para comunicarnos con las clases del modelo, mientras que los JSP deberían usarse para la capa de presentación.
-
Ciclo de vida de la página JSP
El ciclo de vida de JSP también es gestionado por el contenedor. Normalmente, cada contenedor web que contiene un contenedor de servlets también incluye un contenedor JSP para gestionar las páginas JSP. Las fases del ciclo de vida de las páginas JSP son las siguientes:
- Traducción – Las páginas JSP no se parecen a las clases Java normales. De hecho, el contenedor JSP analiza las páginas JSP y las traduce para generar el código fuente del servlet correspondiente. Si el nombre del archivo JSP es home.jsp, por lo general, se nombra como home_jsp.java.
- Compilación – Si la traducción es exitosa, entonces el contenedor compila el archivo fuente del servlet generado para generar el archivo de clase.
- Carga de Clase – Una vez que la JSP se compila como clase de servlet, su ciclo de vida es similar al de un servlet y se carga en la memoria.
- Creación de Instancia – Después de que la clase JSP se carga en la memoria, se instancia su objeto por el contenedor.
- Inicialización – La clase JSP se inicializa y se transforma de una clase normal a un servlet. Después de la inicialización, los objetos ServletConfig y ServletContext son accesibles para la clase JSP.
- Procesamiento de la Solicitud – Para cada solicitud del cliente, se crea un nuevo hilo con ServletRequest y ServletResponse para procesar y generar la respuesta HTML.
- Destrucción – Última fase del ciclo de vida de JSP, donde se descarga de la memoria.
-
Métodos del ciclo de vida de JSP
Los métodos del ciclo de vida de JSP son:
- jspInit() declarado en la interfaz JspPage. Este método se llama solo una vez en el ciclo de vida de JSP para inicializar los parámetros de configuración.
- _jspService(HttpServletRequest request, HttpServletResponse response) declarado en la interfaz HttpJspPage y responde al manejo de las solicitudes del cliente.
- jspDestroy() declarado en la interfaz JspPage para liberar la JSP de la memoria.
-
Ejemplo simple de JSP con Eclipse y Tomcat
We can use Eclipse IDE for building dynamic web project with JSPs and use Tomcat to run it. Please read [Java Web Applications](/community/tutorials/java-web-application-tutorial-for-beginners#first-web-app-servlet) tutorial to learn how can we easily create JSPs in Eclipse and run it in tomcat. A simple JSP example page example is: `home.jsp`
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>First JSP</title>
</head>
<%@ page import="java.util.Date" %>
<body>
<h3>Hi Pankaj</h3><br>
<strong>Current Time is</strong>: <%=new Date() %>
</body>
</html>
```
If you have a simple JSP that uses only JRE classes, we are not required to put it as WAR file. Just create a directory in the tomcat webapps folder and place your JSP file in the newly created directory. For example, if your JSP is located at apache-`tomcat/webapps/test/home.jsp`, then you can access it in browser with URL `https://localhost:8080/test/home.jsp`. If your host and port is different, then you need to make changes in URL accordingly.
We can place JSP files at any location in the WAR file, however if we put it inside the WEB-INF directory, we wont be able to access it directly from client. We can configure JSP just like servlets in web.xml, for example if I have a JSP example page like below inside WEB-INF directory: `test.jsp`
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Test JSP</title>
</head>
<body>
Test JSP Page inside WEB-INF folder.<br>
Init Param "test" value =<%=config.getInitParameter("test") %><br>
HashCode of this object=<%=this.hashCode() %>
</body>
</html>
```
And I configure it in web.xml configuration as:
```
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>FirstJSP</display-name>
<servlet>
<servlet-name>Test</servlet-name>
<jsp-file>/WEB-INF/test.jsp</jsp-file>
<init-param>
<param-name>test</param-name>
<param-value>Test Value</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/Test.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Test1</servlet-name>
<jsp-file>/WEB-INF/test.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Test1</servlet-name>
<url-pattern>/Test1.do</url-pattern>
</servlet-mapping>
</web-app>
```
Then I can access it with both the URLs https://localhost:8080/FirstJSP/Test.do and https://localhost:8080/FirstJSP/Test1.do Notice that container will create two instances in this case and both will have their own servlet config objects, you can confirm this by visiting these URLs in browser. For Test.do URI, you will get response like below.
```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =Test Value
HashCode of this object=1839060256
```
For Test1.do URI, you will get response like below.
```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =null
HashCode of this object=38139054
```
Notice the init param value in second case is null because it's not defined for the second servlet, also notice the hashcode is different. If you will make further requests, the hashcode value will not change because the requests are processed by spawning a new thread by the container. Did you noticed the use of **config** variable in above JSP example but there is no variable declared, it's because its one of the 9 implicit objects available in JSP page, read more about them at [**JSP Implicit Objects**](/community/tutorials/jsp-implicit-objects "JSP Implicit Objects with Examples").
All the core JSP interfaces and classes are defined in `javax.servlet.jsp` package. Expression Language API interfaces are classes are part of `javax.servlet.jsp.el` package. JSP Tag Libraries interfaces and classes are defined in `javax.servlet.jsp.tagext` package. Here we will look into interfaces and classes of Core JSP API.
-
Interfaz JspPage
La interfaz JspPage extiende la interfaz Servlet y declara los métodos de ciclo de vida jspInit() y jspDestroy() de las páginas JSP.
-
Interfaz HttpJspPage
La interfaz HttpJspPage describe la interacción que una Clase de Implementación de Página JSP debe cumplir al utilizar el protocolo HTTP. Esta interfaz declara el método de servicio de la página JSP para el protocolo HTTP como public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException.
-
Clase abstracta JspWriter
Similar a PrintWriter en servlets con facilidades adicionales de soporte de almacenamiento en búfer. Esta es una de las variables implícitas en una página JSP con el nombre “out”. Esta clase extiende java.io.Writer y el contenedor proporciona su propia implementación para esta clase abstracta y la utiliza al traducir la página JSP a un Servlet. Podemos obtener su objeto usando el método PageContext.getOut(). La clase concreta de Apache Tomcat para JspWriter es
org.apache.jasper.runtime.JspWriterImpl
. -
Clase Abstracta JspContext
JspContext sirve como la clase base para la clase PageContext y abstrae toda la información que no es específica para servlets. JspContext proporciona un mecanismo para obtener JspWriter para la salida, un mecanismo para trabajar con atributos y una API para gestionar los diversos espacios de nombres escalados.
-
Clase abstracta PageContext
PageContext extiende JspContext para proporcionar información de contexto útil cuando se utiliza JSP para aplicaciones web. Una instancia de PageContext proporciona acceso a todos los espacios de nombres asociados con una página JSP, brinda acceso a varios atributos de página, así como una capa por encima de los detalles de implementación. Los objetos implícitos se agregan al pageContext automáticamente.
-
Clase abstracta JspFactory
La JspFactory es una clase abstracta que define varios métodos de fábrica disponibles para una página JSP en tiempo de ejecución, con el propósito de crear instancias de varias interfaces y clases utilizadas para respaldar la implementación JSP.
-
Clase abstracta JspEngineInfo
La JspEngineInfo es una clase abstracta que proporciona información sobre el motor JSP actual.
-
ErrorData Clase final
Contiene información sobre un error, para páginas de error.
-
Clase JspException
Una excepción genérica conocida por el contenedor JSP, similar a ServletException. Si las páginas JSP lanzan JspException, se utiliza el mecanismo de errorpage para presentar información de error al usuario.
-
Clase JspTagException
Excepción que debe ser utilizada por un controlador de etiquetas para indicar algún error irreparable.
-
Clase SkipPageException
Excepción para indicar que la página que llama debe detener la evaluación. Lanzada por un controlador de etiquetas simple para indicar que el resto de la página no debe ser evaluado. Esta excepción no debe ser lanzada manualmente en una página JSP.
Since JSP is built on top of HTML, we can write comments in JSP file like html comments as `<-- This is HTML Comment -->` These comments are sent to the client and we can look it with view source option of browsers. We can put comments in JSP files as: `<%-- This is JSP Comment--%>` This comment is suitable for developers to provide code level comments because these are not sent in the client response.
Scriptlet tags are the easiest way to put java code in a JSP page. A scriptlet tag starts with `<%` and ends with `%>`. Any code written inside the scriptlet tags go into the `_jspService()` method. For example:
```
<%
Date d = new Date();
System.out.println("Current Date="+d);
%>
```
Since most of the times we print dynamic data in JSP page using _out.print()_ method, there is a shortcut to do this through JSP Expressions. JSP Expression starts with `<%=` and ends with `%>`. `<% out.print("Pankaj"); %>` can be written using JSP Expression as `<%= "Pankaj" %>` Notice that anything between `<%= %>` is sent as parameter to `out.print()` method. Also notice that scriptlets can contain multiple java statements and always ends with semicolon (;) but expression doesn't end with semicolon.
JSP Directives are used to give special instructions to the container while JSP page is getting translated to servlet source code. JSP directives starts with `<%@` and ends with `%>` For example, in above JSP Example, I am using _page_ directive to to instruct container JSP translator to import the Date class.
JSP Declarations are used to declare member methods and variables of servlet class. JSP Declarations starts with `<%!` and ends with `%>`. For example we can create an int variable in JSP at class level as `<%! public static int count=0; %>`
Once JSP files are translated to Servlet source code, the source code (.java) and compiled classes both are place in **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp** directory. If the JSP files are inside other directories of application, the directory structure is maintained. For JSPs inside WEB-INF directory, its source and class files are inside **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp/WEB\_002dINF** directory. Here is the source code generated for above test.jsp page. `test_jsp.java`
```
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.32
* Generated at: 2013-08-21 03:40:59 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp.WEB_002dINF;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=US-ASCII");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">\n");
out.write("<html>\n");
out.write("<head>\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">\n");
out.write("<title>Test JSP</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write("Test JSP Page inside WEB-INF folder.<br>\n");
out.write("Init Param \"test\" value =");
out.print(config.getInitParameter("test") );
out.write("<br>\n");
out.write("HashCode of this object=");
out.print(this.hashCode() );
out.write("\n");
out.write("</body>\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
```
Notice following points in above servlet code;
- The package of class starts with org.apache.jsp and if JSPs are inside other folders, it includes directory hierarchy too. Usually we dont care about it.
- The generates servlet class is final and can't be extended.
- It extends `org.apache.jasper.runtime.HttpJspBase` that is similar to HttpServlet except that it's internal to Tomcat JSP Translator implementation. HttpJspBase extends HttpServlet and implements HttpJspPage interface.
- Notice the local variables at the start of \_jspService() method implementation, they are automatically added by JSP translator and available for use in service methods, i.e in scriptlets.As a java programmer, sometimes it helps to look into the generated source for debugging purposes.
We can define init parameters for the JSP page as shown in above example and we can retrieve them in JSP using **config** implicit object, we will look into implicit objects in JSP in more detail in future posts.
We can override JSP init method for creating resources to be used by JSP service() method using JSP Declaration tags, we can override jspInit() and jspDestroy() or any other methods also. However we should never override \_jspService() method because anything we write in JSP goes into service method.
Apart from standard servlet attributes with request, session and context scope, in JSP we have another scope for attributes, i.e Page Scope that we can get from pageContext object. We will look it's importance in custom tags tutorial. For normal JSP programming, we don't need to worry about page scope.
¡Eso es todo para el tutorial de ejemplo de JSP para principiantes. Espero que te ayude a entender los conceptos básicos de JSP y te ayude a comenzar. Investigaremos otras características de JSP en futuras publicaciones.
Source:
https://www.digitalocean.com/community/tutorials/jsp-example-tutorial-for-beginners