Introducción a Java Server Pages JSP

Este tutorial es el primero de varios donde veremos que son, como funcionan y principales usos que podemos darles a las páginas JSP Java Server Pages y demás tecnologías relacionadas.

¿Qué es una página JSP?

Una JSP es un documento basados en tags HTMLs y tags propios de JSP. A continuación vemos un ejemplo de una página llamada login.jsp:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login result</title>
</head>
<body>
<%
String user = request.getParameter("user");
String pass = request.getParameter("password");
if ("edu4java".equals(user) && "eli4java".equals(pass)) {
out.println("login ok");
} else {
out.println("invalid login");
}
%>
</body>
</html>

Aquí podemos ver que todo es HTML salvo lo que se encuentra dentro de los tags <% %> que es código java. Esta página JSP hace lo mismos que el código del siguiente Servlet.

package com.edu4java.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String user = request.getParameter("user");
		String pass = request.getParameter("password");
		if ("edu4java".equals(user) && "eli4java".equals(pass)) {
			response(response, "login ok");
		} else {
			response(response, "invalid login");
		}
	}

	private void response(HttpServletResponse resp, String msg)
			throws IOException {
		PrintWriter out = resp.getWriter();
		out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"" +
			" \"http://www.w3.org/TR/html4/loose.dtd\">");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; " +
			"charset=ISO-8859-1\">");
		out.println("<title>Login result</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<t1>" + msg + "</t1>");
		out.println("</body>");
		out.println("</html>");
	}
}

Desde el punto de vista de un diseñador de páginas webs la jsp es infinitamente más sencilla que el servlet. Teniendo en cuenta que normalmente en las empresas los diseñadores web normalmente no tiene grandes conocimientos de java y viceversa se hace evidente las ventajas de JSP. Incluso para un programador java experimentado cuando la cantidad de html en la página es mucha el trabajo se puede volver una pesadilla. Imaginen páginas y páginas de out.println( ...

	<%
String user = request.getParameter("user");
String pass = request.getParameter("password");
if ("edu4java".equals(user) && "eli4java".equals(pass)) {
out.println("login ok");
} else {
out.println("invalid login");
}
%>

Si nos centramos en el código java de la JSP podremos notar no hay declaración de las variables request y out. Estas variables son conocidas como Objetos Implícitos (Implicit Objects) y están predefinidas con nombres estándares para ser utilizadas por el programador en el código java de las JSPs. A continuación se describe algunos de estos Objetos Implícitos:

request es el objeto con la información recibida desde el browser
response es el objeto que contendrá la información que enviaremos como respuesta al browser
out es un objeto Writer que podemos utilizar para enviar Html (o cualquier clase de contenido) al browser
session este objeto mantiene datos entre llamadas del mismo usuario.
application este objeto mantiene datos durante toda la vida de la aplicación

Los objetos request y response son los que se reciben como parámetros en los métodos doPost(HttpServletRequest request, HttpServletResponse response) y doGet(HttpServletRequest request, HttpServletResponse response). Los objetos request, response y application permiten almacenar información y los veremos en profundidad en un tutorial sobre Alcances o Scopes en una aplicación web.

Probando login.jsp

Copiamos login.jsp a WebContent y modificamos login.html para que en vez de llamar a /login llame directamente a login.jsp

<html>
<body>
<form action="login.jsp" method="post">
<table>
<tr>
<td>User</td>
<td><input name="user" /></td>
</tr>
<tr>
<td>password</td>
<td><input name="password" /></td>
</tr>
</table>
<input type="submit" />
</form>
</body>
</html>

Boton derecho del raton en login.html - Run as - Run on server. Se abre http://localhost:8080/first-jee/login.html. Rellenamos user, password y oprimimos el botón Submit Query.

Otra conveniencia de las JSPs es que no es nesesario declararlas en web.xml.

¿Cómo funciona una JSP en el servidor o contenedor de Servlets?

Cuando desplegamos una JSP e iniciamos el servidor, el servidor crea el código java para un servlet a partir del contenido de la JSP y lo compila. En mi instalación podemos encontrar los archivos .java y .class de este servlet en:

C:\eclipseJEE2\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\first-jee\org\apache\jsp

No es necesario entender todo el código java generado pero es interesante darle un vistazo.

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class login_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig()
		.getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig()
		.getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""+
			" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n");
      out.write("<title>Login result</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t");

		String user = request.getParameter("user");
		String pass = request.getParameter("password");
		if ("edu4java".equals(user) && "eli4java".equals(pass)) {
			out.println("login ok");
		} else {
			out.println("invalid login");
		}
	
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (Throwable t) {
      if (!(t instanceof 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);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

Algunas curiosidades:

En el próximo tutorial veremos depurar nuestra aplicación web. Debugging.

<< Despliegue (Deployment) de la aplicación Web Depurar nuestra aplicación web. Debugging. >>