Usar Elementos de Scripting

En el algún momento, probablemente querramos añadir algún viejo código a nuestras ficheros JSP. Las etiquetas JSP son poderosas y encapsulan tareas que serían difíciles o llevarián mucho tiempo de programar. Pero por eso, probablemente querramos usar fragmentos de lenguaje de script para suplementar las etiquetas JSP.

Los lenguajes de script que tenemos disponibles dependen del motor JSP que estemos usando. Con la implementación JSP de Sun, debemos usar el lenguaje Java como lenguaje de script, pero otros motores de JSP de terceras partes podrían incluir soporte para otros lenguajes.

¿Cómo añadir Scripting?

Primero, necesitaremos conocer una pocas reglas generales sobre la adicción de elementos script a un fichero fuente JSP:
  1. Usamos una directiva page para definir el lenguaje de script utilizado en la página JSP (a menos que estemos usando el lenguaje Java, que es el valor por defecto).
  2. La declaración <%! .. %> declara variables o métodos.
  3. La expresión <%= .. %> define una expresión del lenguaje script y fuerza el restulado a un String.
  4. El scriptlet <% .. %> puede manejar declaraciones, expresiones o cualquier otro tipo de fragmento de código válido en el lenguaje script de la página.
  5. Cuando escribimos un scriptlet, lo terminamos con %> antes de cambiar a HTML, texto u otra etiqueta JSP.

La Diferencia entre <%, <%=, y <%!

Declaraciones, expresiones y scriptlets tienen una síntaxis y un uso similar, pero también tienen diferencias importantes.

Declaracioness (entre las etiquetas <%! y %>) contiene una o más declaraciones de variables o métodos que terminan o están separadas por puntos y comas:

<%! int i = 0; %>
<%! int a, b; double c; %>
<%! Circle a = new Circle(2.0); %>
Debemos declarar una variable o método en una página JSP antes de usarla en la página. El ámbito de la declaración normalmente es el fichero JSP, pero si el fichero JSP incluye otros ficheros con la directiva include, el ámbito se expande para incluir también estos ficheros incluidos.

Expresiones (entre las etiquetas <%= y %>) pueden contener cualquier expresión del lenguaje que sea válida en el lenguaje de script de la página, pero sin punto y coma:

<%= Math.sqrt(2) %>
<%= items[i] %>
<%= a + b + c %>
<%= new java.util.Date() %>
La definición de una expresión válida depende del lenguaje de script. Cuando usamos lenguaje Java, lo que hay entre las etiquetas de expresión puede ser cualquier expresión definida en la Expecificación del Lenguaje Java. Las partes de la expresión se evalúan de izquierda a derecha. Una diferencia clave entre expresiones y scriptlets es que dentro de las etiquetas de expresión no se permiten puntos y comas, incluso si la misma expresión lo requiere.

Scriptlets (entre las etiquetas <% y %>) nos permite escribir cualquier número de sentencias del lenguaje Script, de esta forma:

<%
	String name = null;
	if (request.getParameter("name") == null) {
%>
Recuerda que en un scriptlet debemos terminar una sentencia de lenguaje con un punto y coma si el lenguaje los requiere.

Cuando escribamos un scriptlet podemos usar cualquiera de los objetos o clases implícitos de JSP importados por la directiva page, declarada en una declaración, o nombrada en una etiqueta <jsp:useBean> .

The Number Guess Game

El juego Number Guess es divertido y hace buen uso de scriptlets y expressions, así como de los conocimientos de los formularios HTML que aprendimos en la página anterior.

Sobre "Guess a Number":

Código de Ejemplo

Mostrar la pantalla de "Number Guess" (numguess.jsp)

<!--
    Number Guess Game
    Written by Jason Hunter, CTO, K&A Software
    jasonh@kasoftware.com, http://www.servlets.com
    Copyright 1999, K&A Software
    Distributed by Sun Microsystems with permission
-->

<%@ page import = "num.NumberGuessBean" %>

<jsp:useBean id="numguess" class="num.
        NumberGuessBean" scope="session" />
<jsp:setProperty name="numguess" property="*" />

<html>
<head><title>Number Guess</title></head>
<body bgcolor="white">
<font size=4>

<% if (numguess.getSuccess() ) { %>
	Congratulations!  You got it.
	And after just <%= numguess.getNumGuesses() %>
      tries.<p>

	<% numguess.reset(); %>
	Care to <a href="numguess.jsp">try again</a>?

<% } else if (numguess.getNumGuesses() == 0) { %>

	Welcome to the Number Guess game.<p>
	I'm thinking of a number between 1 and 100.<p>

      <form method=get>
      What's your guess? <input type=text name=guess>
      <input type=submit value="Submit">
      </form>

<% } else { %>
      Good guess, but nope.  Try <b><%= numguess.
      getHint() %></b>.
      You have made <%= numguess.getNumGuesses() %> 
      guesses. 

      I'm thinking of a number between 1 and 100.<p>

      <form method=get>
      What's your guess? <input type=text name=guess>
      <input type=submit value="Submit">
      </form>

<% } %>
</font>
</body>
</html>

Manejar el Guess (NumberGuessBean.java)

// Number Guess Game
// Written by Jason Hunter, CTO, K&A Software
// jasonh@kasoftware.com, http://www.servlets.com
// Copyright 1999, K&A Software
// Distributed by Sun Microsystems with permission

package num;

import java.util.*;
public class NumberGuessBean {

	int answer;
	boolean success;
	String hint;
	int numGuesses;

public NumberGuessBean() {
	reset();
}

public void setGuess(String guess) {
	numGuesses++;

	int g;
	try {
	g = Integer.parseInt(guess);
	}
	catch (NumberFormatException e) {
		g = -1;
	}
	if (g == answer) {
		success = true;
	}
	else if (g == -1) {
		hint = "a number next time";
	}
	else if (g < answer) {
		hint = "higher";
	}
	else if (g > answer) {
		hint = "lower";
	}
}
	public boolean getSuccess() {
		return success;
	}

	public String getHint() {
		return "" + hint;
	}

	public int getNumGuesses() {
		return numGuesses;
	}

	public void reset() {
	    answer = Math.abs(new Random().nextInt() % 100)
              + 1;
	    success = false;
	    numGuesses = 0;
	}
}

Usar Elementos Script en un fichero JSP

El fichero numguess.jsp es un ejemplo interesante del uso de elementos script, porque está estructurado como nosotros estructurariamos un fichero fuente con un una larga sentencia if ... else dentro de las etiquetas scriptlet. La diferencia es que el cuerpo de cada clausula de sentencia están escritas en HTML y etiquetas JSP, en vez del lenguaje de programación.

No es necesario que escribamos scriptlets mezclados con HTML y etiquetas JSP,como se muestra en numguess.jsp. Entre las etiquetas <% y %>. Podemos escribir cuantas línea de código script creamos necesarias. En general, hacer menos proceso en los scriptles y más en los componentes como servlets o Beans haremos el código de nuestra aplicación más reutilizable y portable. No obstante, podemos escribir nuestra aplicación JSP como queramos, y la implementación de referencia de JSP 1.0 de Sun no especifica límite a la longitud del scriptlet.

Mezclar Sentencias Scripting con Etiquetas

Cuando mezclamos elementos scripting con etiquetas HTML y JSP, siempre debemos terminar un elemento de scripting antes de empezar a usar etiquetas y luego reabrir el elemento de scripting, de esta forma:
<% } else { %>   
 <!-- Cerrar el escript antes de empezar las etiquetas-->

... siguen las etiquetas...

<% } %> 
<!-- reabrimos el scriptlet para cerrar el bloque de lenguaje-->
Al principio, esto podría parecer un poco extraño, pero así se asegura de que los elementos de scripting son transformados correctamente cuando se compila el fichero fuente JSP.

¿Cuando se ejecutan los elementos de Scripting?

Un fichero fuente JSP se procesa en dos estado - tradución HTTP y procesamiento de solicitud.

Durante la tradución HTTP, que ocurre cuando el usuario carga por primera vez una página JSP, el fichero fuente JSP es compilado a una clase Java, normalmente un Servlet Java. Las etiquetas HTML así como muchas etiquetas JSP son procesadas en este estado, antes de que el usuario haga una petición.

El procesamiento de solicitud ocurre cuando el usuario pulsa en la página JSP para hacer un solicitud. La solicitud es envíada desde el cliente al servidor mediante el objeto request. Entonces el motor JSP ejecuta el fichero JSP compilado, o servlet, usando los valores del request enviado por el usuario.

Cuando usamos elementos de scripting en un fichero JSP, deberíamos saber cuando son evaluadas. Las declaraciones son procesadas durante la traducción HTTP y están disponibles para otras declaraciones, expresiones y scriptlets en el fichero compilador JSP. La expresiones también se evalúan durante la traducción a HTTP. El valor de cada expresión se convierte a un String y es insertado en su lugar del fichero compilador JSP. Sin embargo, los scriptlets son evaluados durante el proceso de la solicitud, usando las declaraciones y expresiones que se han puesto a su disposición.

¿Cómo ejecutar el Ejemplo?

Las instrucciones dadas aquí usan path al estilo Unix, si utilizamos Windows, usaremos el mismo path pero con el separador apropiado.
  1. El ejemplo Number Guess ya está instalado en la implementación de referencia JSP.
  2. Los ficheros .jsp y .html están en el directorio ../jswdk-1.0/examples/jsp/num .
  3. Los ficheros .java y .class están en el directorio ../jswdk-1.0/examples/WEB-INF/jsp/beans/num .
  4. Abrimos un navegador web y vamos a: http://host/examples/jsp/num/numguess.jsp

Ozito