1. JSP
  2. Dónde está el .java y el .class generados por el jsp...?
  3. Error
  4. Scriplet
  5. EL
  6. JSTL
  7. Ejercicios scriplet, EL y JSTL
  8. Instanciar
  9. Estructura de control IF
  10. Mandar formulario
  11. Estructura de control: bucle for
  12. Asignar valor a variables con JSTL
  13. Inclusión

JSP (java server pages)

Permiten meter código java en un fichero html en vez de código html en un fichero java.

Cuando ponemos código java en un fichero html, dicho fichero pasa a tener extensión jsp.

Los .jsp generan .java (servlets). Los servlets compilados son .class.

Es el contenedor de aplicaciones (tomcat, etc) el que convertirá los jsp en servlets.

El servidor leerá el archivo jsp. Luego, va a buscar el jsp compilado (el .class), si no lo encuentra, lo compila.
Traducción: pasar de jsp a java.
Compilación: pasar de java a .class

Descargar Workspace

Dónde está el .java y el .class generados por el jsp...?

Si tenemos el Servidor configurado de la siguiente forma en Eclipse...

configuración eclipse para web

Para poder modificar estas opciones no puede haber ningún proyecto desplegado en el servidor.

Almacenaremos los archivos jsp en la carpeta WebContent (eclipse) o web (netbeans).

Error al cargar el JRE

pantallazo eclipse

Proyecto -> Properties -> Java Build Path -> Libraries -> Add Library -> JRE

Scriplet

Hola mundo con Scriptlet

<h1>Scriptlet JSP</h1>
<%= "Hola Mundo JSP Scriplet" %>
<%= request.getParameter("nombre") %>

Comentarios

<h1>Página con comentarios</h1>
<%
//Esto es un comentario de una sola línea
/*
* y esto un comentario de varias líneas
*/
%>

Variables en Scriplet

<h1>JSP Scriplet</h1>
<%
	String texto = "Soy una cadena";
	int i = 5;
	int j = 3;
%>
<%=texto %><br/>
<%=i %>+<%=j %>=<br/>
<%=i+j %><br/>
<%=i+""+j %>

El contenedor transforma un JSP en un servlet


JSP			Servlet

			public class basicCounter_jsp extends SomeSpecialHttpServlet{
				public void _jspService(HttpServletRequest request,
				HttpServletResponse response) 
				throws java.io.IOException, ServletException{
					PrintWriter out = response.getWriter();
					response.setContenType("text/html");
<html><body>		->  		out.println("<html><body>");
<% int count=0; %> 	-> 		int count = 0;  
This page count is now:	-> 		out.write("This page count is now:");
<%= ++ count %>		-> 		out.print(++count);
</body></html>		-> 		out.write("</body></html>");

Todo el código de un scriplet cae dentro del método service.

Por tanto, las variables declaradas en un scriplet son locales.

Declaración de variables y métodos miembro

Todo lo que vaya precedido de una admiración irá declarado directamente dentro de la clase, por tanto usaré el signo de exclamación para declarar variables miembro y métodos

<html>							
<body>					public class basicCounter_jsp extends SomeSpecialHttpServlet{
<%! int doubleCount(){				int doubleCount(){		
	count = count*2;			count = count*2;
	return count;				return count;
}					}
%>
<%! int count=1; %>				int count=1;
					public void _jspService(HttpServletRequest request,
						HttpServletResponse response throws java.io.IOException){
						PrintWriter out = response.getWriter();
						response.setContentType("text/html");
						out.write("<html><body>");
The page count is now:				out.write("The page count is now:");
<%= doubleCount() %>				out.print(doubleCount());
</body>						out.write("</body></html>");
</html>

Objetos implícitos

	
JspWriter 		-> out
HttpServletRequest 	-> request
HttpServletResponse	-> response
HttpSession 		-> session
ServletContext 		-> application
ServletConfig		-> config
Throwable		-> exception
	

JSP API

jspInit();	-> ejecutado al cargar el jsp

jspDestroy();   -> ejecutado tras cargar el jsp

_jspService(); 	-> desde aquí se llama al código del jsp.

Desventajas de los scriplets

  • Son difíciles de comprender por alguien que no sea programador java.
  • Es necesario hacer el Casting de objetos y esto ocasiona que tengamos que importar más Clases en los JSP. En el siguiente ejemplo habrá que importar la clase Libro.
    <% Libro libro = (Libro)request.getAttribute("libro"); %>
    <%=libro.getTitulo()%><br/>

EL

Características:

  • Simplifican el uso de expresiones en JSPs.
  • Permite la ejecución de expresiones fuera de los elementos de scripting de JSP
  • Fue introducida con JSTL 1.0 como un mecanismo alternativo al uso de expresiones en Java para asignar valores a atributos
  • EL es mucho más tolerante con las variables null y realiza conversiones automáticas de datos Se puede habilitar o deshabilitar el uso de expresiones EL:
    <%@ page isELIgnored="false" %>

<h1>EL</h1>
${"Hola Mundo EL"}
${param.nombre}

Definir constantes en el web.xml

<servlet>
	<description></description>
	<display-name>D_sumador</display-name>
	<servlet-name>D_sumador</servlet-name>
	<servlet-class>com.pablomonteserin.jsp.servlets.D_sumador</servlet-class>
	<init-param>
	<param-name>valor</param-name>
		<param-value>
			5
		</param-value>
	</init-param>
</servlet>

Para recuperar dicho valor desde el servlet:

ServletConfig conf=getServletConfig();
int valor = Integer.parseInt(conf.getInitParameter("valor"));

Ciclo de una petición con JSP

index.jsp<form action="/ciclo/Controlador">
	<input type="text" name="nombre">

	<input type="submit" value="Como soy?">
</form>

${resultado}
Controlador.java@WebServlet("/Controlador")
public class Controlador extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//Recojo los parámetros que me vienen del jsp
		String nombre = request.getParameter("nombre");

		//Genero un resultado
		String resultado = "Hola " + nombre;
		
		//Ponemos en el objeto request los datos que vamos a enviar al jsp
		request.setAttribute("resultado", resultado);
		
		//Redireccion a index.jsp
		request.getRequestDispatcher("index.jsp").forward(request,  response);
	}
}

JSTL – (Java Server Page Standard Tag Library)

Son un conjunto de etiquetas (tags) standard que encapsulan funcionalidades de uso común para muchas aplicaciones con JSPs.

Ventajas de JSTL frente a scriptlet:
  • Debido a que las etiquetas JSTL son XML, se integran uniformemente con las etiquetas HTML y serán fáciles de usar por alguien que conozca html.
  • Las etiquetas JSTL están específicamente preparados para realizar las tareas que van a tener lugar en la lógica de la presentación.
  • EL es usado extensamente en la librería JSTL.
Desventajas:
  • Agregar mayor sobrecarga al servidor. El código Java embebido en los scriptlets es básicamente copiado en el servlet resultante. En cambio, las etiquetas JSTL, causan un poco más de código en el servlet. En la mayoría de casos esta cantidad no es mensurable pero debe ser considerado.
  • Los scriptlets son más potentes que las etiquetas JSTL. Si desea hacer todo en un script JSP pues es muy probable que insertará todo el código Java en él.

Cargar JSTL

  1. Dejamos los archivos jstl.jar y standard.jar en la carpeta lib de nuestro proyecto. Descargar librerías.
  2. Incluimos las siguientes etiquetas en la cabecera de nuestro jsp:
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    La dirección http no es buscada en internet, sino en los tld (tag library descriptor) que contienen los jar. El texto concreto de esta url carece de importancia, mientras coincida con la url que posee el tld.
  3. <c:out value="Hola Mundo JSTL!"></c:out>
    <c:out value="${param.nombre}" />

Nota: Para trabajar con jstl y con custom tags no hará falta modificar el web.xml. La etiqueta taglib quedó obsoleta en los servlets 2.4.

getAttribute() vs getParameter()

getParameter() devuelve una cadena de texto:

request.getParameter("nombre"); 
${param.nombre} // normalmente no usaremos este código en la vista

getAttribute() devuelve un objeto:

request.setAttribute("nombreAtributo", valorAtributo); // guarda un objeto en el request. 
<%=request.getAttribute("nombreAtributo");%> // devuelve un objeto
${nombreAtributo}
<c:out value="${nombreAtributo}" />"

Ejercicio saludo

El usuario debe introducir su nombre en un cuadro de texto. Dicho nombre será enviado a un Servlet que generará el mensaje "Buenas tardes [nombre]". Dicho mensaje llegará de nuevo al jsp, dónde lo mostraremos

Utilizar scriplet, JSTL y EL para recuperar la información.

Directiva para cargar JSTL:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Notas: El atributo default de la etiqueta <c:out/> contiene la información que se imprimirá en caso de que la variable nos venga nulo.

Uso de clases y objetos

Instanciar

Instanciar una clase desde un JSP utilizando scriplet.

<h1>Con scriplets JSP</h1>
<%= new com.pablomonteserin.model.StringExtendido() %>
<%@page import="com.pablomonteserin.model.StringExtendido"%>
<%= new StringExtendido() %>

Ejercicio Instanciar

Imprimir utilizando scriptlet (<%= %>) una instancia de la clase Date.

Tener en cuenta que la clase Date pertenece al paquete java.util

Ejemplo – Recuperar un Bean Libro que tiene un metodo getTitulo();

servlet.java 
Libro libro = new Libro("978-84-415-2988-5", "Java 7", 15.8); 
request.setAttribute("libro", libro); 
request.getRequestDispatcher("index.jsp").forward(request, response);
index.jsp (scriplet) 
<% Libro libro = (Libro)request.getAttribute("libro"); %>
<%=libro.getTitulo()%>
index.jsp (EL)
${requestScope.libro.titulo}
index.jsp (JSTL)
<c:out value="${requestScope.libro.titulo}"></c:out>

Obsérvese que utilizando Scriplet es necesario hacer un casteo para recuperar la información y usando EL y JSTL, no.

Ejercicio Instanciar II

La aplicación consta de un servlet, un bean Persona(dni, nombre y dirección) y un fichero jsp.

El flujo de la aplicación comienza en el servlet. Aquí instanciaremos e inicializaremos un bean Persona.

Luego, utilizando el método

request.getRequestDispatcher("rutaHastaElJSP").forward(request, response);
iremos al jsp.

Aquí mostraremos las propiedades del bean utilizando scriptlet, EL y JSTL.

Ejercicio

Hacer un formulario html con tres campos (dni, nombre y edad) de tal forma que al pulsar se muestre un texto con el siguiente formato.

El señor nombre con dni dni vive en la dirección direccion.

Al pulsar el botón de submit enviaremos la información al servlet, que recogerá los parámetros, creará un bean a partir de ellos y pondrá dicho bean en el request.

Luego, iremos a un nuevo jsp utilizando

request.getRequestDispatcher("rutaHastaElJSP").forward(request, response);

Estructura de control IF

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<h1>Scriptlet JSP</h1>
<%
	int dato1 = 3;
	int dato2 = 5;
	if(dato2 > dato1){
		out.println("dato2 es mayor que dato1");
	}else{
		out.println("dato2 es mayor que dato1");		
	}
%>

<h1>EL</h1>
${5 gt 3}- 1 -${5 > 3} - 2 - ${5 lt 3} - 3 -${5 < 3} - 4 -${5 eq 1}	


<h1>JSTL</h1>
<c:if test="${5>3}">
5 es mayor que 3!
</c:if>
solución ejercicio

Procesar el formulario en la propia página

<%
	if(request.getParameter("botonEnvio")!=null){
		out.println("boton Pulsado");
	}
%>

<form method="post" action="#">
	<input type="submit" name="botonEnvio" value="botonEnvio"></input>
</form>

Ejercicio

Repetir el ejemplo de la diapositiva anterior usando JSTL

else

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<h1>Scriptlet JSP</h1>
<%
	int dato1 = 3;
	int dato2 = 5;
	if(dato2 > dato1){
		out.println("dato2 es mayor que dato1");
	}else{
		out.println("dato2 es mayor que dato1");		
	}
%>


<h1>JSTL</h1>

 <c:choose>
        <c:when test='${5 > 3}'>
			5 es mayor que 3!
        </c:when>
        <c:otherwise>
			5 no es mayor q 3.
        </c:otherwise>
</c:choose>

Ejercicio

Añadiendo un scriplet al siguiente código, controlar que si el botón no fue pulsado se muestre el mensaje
"El botón no fue pulsado!"

<%
	if(request.getParameter("botonEnvio")!=null){
		out.println("boton pulsado");
	}//Añadir líneas aquí
%>

<form method="post" action="#">
	<input type="submit" name="botonEnvio" value="botonEnvio"></input>
</form>

Ejercicio – repetir el ejercicio de la diapositiva anterior usando JSTL

Ejercicio

Si he pulsado el botón de enviar, imprimir el value del campo de texto; si no, imprimir "Botón no pulsado". Utilizar un scriplet.

pantallazo resolución final

Ejercicio

Repetir el ejercicio de la diapositiva anterior usando JSTL.

Mandar formulario

Ejercicio – Mandar un formulario.

Resolver utilizando scriplet, EL y JSTL

Desde una página HTML mandaremos datos a un Servlet. En el Servlet introduciremos la información en un pojo de pedido y finalmente iremos a una página llamada salida.jsp donde mostraremos un mensaje con el pedido realizado.

pantallazo resolución final

Ejercicio

Repetir el ejercicio de la diapositiva anterior utilizando JSTL.

Ejercicio – cambiar color body utilizar scriplet

ver pantallazo

Ejercicio

Repetir el ejercicio anterior utilizando JSTL.

Ejercicio

La combo debe recordar la opción seleccionada tras hacer submit.

Pista!:
Una opción de una combo está seleccionada si tiene su atributo
selected con el siguiente valor:
selected = "selected"

Ejercicio

Hacer una calculadora que haga uso de los operadores aritméticos +, -, *, /. Al pulsar el botón de envío realizará la operación seleccionada.

ver solución

Ejercicio

Repetir el ejercicio anterior usando JSTL.

Estructura de control: bucle for

<%
	for(int i=0; i<10; i++){
		out.print(i);
	}
%>

Ejercicio – imprimir los números pares que hay dentro de los 1000 primeros números naturales

Nota: El operador “%” nos da el resto de dividir un número entre otro. 
Ej: 7%2=1

Bucle con JSTL

<c:forEach begin="0" step="1" end="10" var="variable">
	<c:out value="${variable}"></c:out>
</c:forEach>

Recorrer una collection

<c:forEach var="libro" items="${libros}">
	<c:out value="${libro.titulo}"></c:out>
</c:forEach>

Recorrer una collection con contador

<ul>
	<c:forEach var="persona" items="${requestScope.collection}"
		varStatus="status">
		<li>item <c:out value="${status.count}" /> - 
				 <c:out value="${status.index}" /> 
			<c:if test="${status.first}">(this is the first item!)</c:if> 
			<c:if test="${status.last}">(this is the last item!)</c:if>
		</li>
	</c:forEach>
</ul>
Salida:
  • item 1 - 0 (this is the first item!)
  • item 2 - 1
  • item 3 - 2
  • item 4 - 3 (this is the last item!)

Ejercicio – recorrer una collection de personas y maquetar el resultado de la siguiente forma. La carga de información de la colección la haremos mediante un Servlet; sin usar base de datos.

Enlace para ver tablas con estilos. pantallazo ejercicio resuelto

Asignar valor a variables con JSTL

<c:set var="nombreVariable" value="valor"/>
<c:out value="${nombreVariable}" />
${nombreVariable}

Session

Hola Servidor! Esta es mi primera petición. Te paso el parámetro nombre con el value Juan

Ok, pero no voy a recordarte. Lo mejor será que te dé un identificador de sesión. Debes pasármelo cada vez que me hagas una petición. Así sabré que eres tú.

Hola de nuevo!. Esta es mi segunda petición. Te paso el parámetro edad. Mi ID es 38... me recuerdas?

Vamos a ver... 38... oh! Aquí estás! La última vez me dijiste que te llamabas Juan!.

El identificador de sessión es una COOKIE llamada JSESSIONID

Creación de la sesión

La sesión se crea automáticamente al ingresar a la página web, o bien cuando una sesión termine.

Podemos ver el valor de JSESSIONID:

${pageContext.session.id}

Matar una sesión

Configurando un timeout en el web.xml

<web-app ...>
	<servlet>
		...
	</servlet>
	<session-config>
		<session-timeout>15</session-timeout>
	</session-config>
</web-app>
La sesión será anulada tras 15 minutos de inactividad.

Asignando un timeout desde código java:

session.setMaxInactiveInterval(60*20);
Argumento en segundos (en este caso,) 20 minutos

Método invalidate

session.invalidate();

Si el cliente tiene las cookies deshabilitadas... URL rewriting

out.println(''<a href=''\<a href=\'''' + response.encodeURL(''/BeerTest.do'')+''\''>click me</a>'';

Add the extra session ID info to this URL

Sessión

Usar variables de sesión es más rápido, pero cuesta memoria RAM.

Usar la base de datos es más lento pero no consume RAM.

En la RAM del servidor se almacenará el identificador de sesión y los objetos vinculados a ella.

En una COOKIE del cliente se almacenará dicho identificador de sesión.

Para almacenar un valor en la sessión

HttpSession session = request.getSession();
session.setAttribute("valor", valor);

Ejercicio

Hacer un proyecto web nuevo en el que a través de un formulario se vayan sumando dos números introducidos por el usuario.

En un campo de tipo input aparecerá la suma de los dos números introducidos

En otro campo aparecerá la suma de todos los números introducidos desde el comienzo de la sesión.

En otro campo más aparecerá la suma desde que arrancamos el servidor

Para ello, desde una página index.jsp enviaremos la información a un controlador servlet que realizará las operaciones necesarias. El resultado de estas operaciones será devuelto a la página de inicio index.jsp.

El botón limpiar mata la sesión. Esto será procesado por el controlador servlet.

Para acceder al ámbito de la aplicación usaremos:

ServletContext ctx = getServletContext();

Listener de sesión

Crear un listener de sesión: Btn derecho sobre un package → new → Listener → Escribo el nombre → next → HTTP session events → Livecycle → marco la check

Será posible modificar el contenido inicial de la sesión desde el session listener:

public void sessionCreated(HttpSessionEvent arg0){
	HttpSession session = arg0.getSession();
}

Recuperar y guardar un ArrayList en la sesión

HttpSession session = request.getSession();
	
ArrayList al = (ArrayList) session.getAttribute("palabras");
if(al==null){
	al = new ArrayList();
}
al.add(valorRecuperadoDelFormulario);
//Nota: en caso de que session.getAttribute nos devuelva null, será necesaria la siguiente línea. Si no devuelve null, no será necesaria, ya que el ArrayList estaría apuntando a la sesión y al modificar el ArrayList se estaría modificando directamente el valor que está en la sesión.
//session.setAttribute("palabras", al);

Ejercicio – Lista de palabras

Hacer un formulario que permita añadir palabras a un ArrayList. Dicho ArrayList será almacenado en la sesión. Con código EL iremos visualizando el contenido del ArrayList:

${ArrayListPalabras}

Inclusión de JSP's

<%@ include file="Header.html" %>

La inclusión se ejecuta en tiempo de traducción, se genera un único fichero java a partir de uno o varios JSP.

No permite importar una dirección url.

<jsp:include page="Header.jsp" />

Esta es la etiqueta que usualmente usamos.

Es la versión xml de la directiva anterior.

<c:import url="http://google.es" />

Para usarla hay que importar la librería jstl.

Es igual que <jsp:include, pero con más posibilidades.

Permite importar url's externas.

Ejercicio

Hacer dos páginas web cuyas secciones cabecera y botonera sean cargadas con la etiqueta <jsp:include ... />

Para realizar este ejercicio tendremos que crear cuatro documentos:

  • cabecera.html
  • botonera.html
  • pagina1.jsp
  • pagina2.jsp

ver solución ejercicio

Ejercicio

Ahora los links de la botonera enlazarán con la propia página, pasándole un parámetro que será recogido y usado para que una etiqueta <c:choose> procese el parámetro y cargue el contenido correspondiente.

Para realizar este ejercicio necesitaremos 3 páginas:
  • contenido1.html
  • contenido2.html
  • index.jsp
icono de mandar un mail¡Contacta conmigo!
contacta conmigoPablo Monteserín

¡Hola! ¿En qué puedo ayudarte?