Comunicación entre elementos en páginas JSP
Creación de JSPs
Los JSP, ya sabemos que son plantillas donde podemos utilizar distintos tipos
de componentes (JavaBeans y TagsLibs) o insertar porciones de Java utilizando
Scriplets ….
Aquí es donde debemos aportar nuestro conocimiento y sentido común,
definiendo que elementos se deben utilizar en cada caso.
Os vamos a mostrar como, utilizar cada uno de los componentes y como
interactúan entre sí y en función de la situación, proporcionaremos
distintas directivas.
Vamos a partir de un JSPs que pone datos a la sesión y en la petición y que
delega sobre otro, nuestro JSP objeto de estudio.
(Tanto las pantallas como el código están generados desde NetBeans 3.5 y no
se han capturado más pasos porque ya existen otros tutoriales en este Web que
muestran paso a paso cada una de las tareas realizadas)
Mostramos el código de nuestro BeanBasico
/* * rcbean.java * * Created on July 15, 2003, 12:21 AM */ package roberto; import java.beans.*; /** * * @author Administrator */ public class rcbean extends Object implements java.io.Serializable { private static final String PROP_SAMPLE_PROPERTY = "PropiedadBasica"; private String propiedadBasica = "Esta es la propiedad básica"; private PropertyChangeSupport propertySupport; /** Creates new rcbean */ public rcbean() { propertySupport = new PropertyChangeSupport( this ); } public String getPropiedadBasica() { return propiedadBasica; } public void setPropiedadBasica(String value) { String oldValue = propiedadBasica; propiedadBasica = value; propertySupport.firePropertyChange(PROP_SAMPLE_PROPERTY, oldValue, propiedadBasica); } public void addPropertyChangeListener(PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(listener); } } |
Y creamos un JSP que use este Bean
<%@page contentType=»text/html»%> <html> <head><title>JSP Page</title></head> <body> <jsp:useBean id=»beansimple» scope=»page» class=»roberto.rcbean» /> </body> |
Y vemos que se muestra el valor de la propiedad
Acceder a un Bean desde un Scriptles
Desde cualquier parte de la página podemos acceder al Bean, a traves del id
que le hemos asignado.
<%@page contentType=»text/html»%> <html> <head><title>JSP Page</title></head> <body> <jsp:useBean id=»beansimple» scope=»page» class=»roberto.rcbean» /> <% String sCadena = beansimple.getPropiedadBasica(); </body> |
Vemos el resultado
Todo tiene su explicación, si vemos el código que genera el JSP
Lectura de parámetros desde un Bean
Un Bean, deber ser un componente generico que deberiámos poder
reutilizar en muchos tipos de aplicaciones distintas.
Si alguien nos pasa un parámetro (desde un CGI), podemos de un
modo sencillo pasárselo a nuestro Bean a través de la propia etiqueta.
<%@page contentType=»text/html»%> <html> <head><title>JSP Page</title></head> <body> <jsp:useBean id=»beansimple» scope=»page» class=»roberto.rcbean» /> <% String sCadena = beansimple.getPropiedadBasica(); </body> |
Si pasamos el parámetro, aparecerá
Paso de un parámetro de petición a un Bean
El parámetro los enviamos desde el primer JSP
<%@page contentType=»text/html»%> <html> <head><title>JSP Page</title></head> <body> Este JSP los usaremos como punto de entrada <% <jsp:forward page=»/jspobjetivo.jsp» /> </body> |
Y lo leemos desde el segundobJSP
<%@page contentType=»text/html»%> <html> <head><title>JSP Page</title></head> <body> <jsp:useBean id=»beansimple» scope=»page» class=»roberto.rcbean» /> value=‘<%= request.getAttribute(«valorpasado») %>’ /> <% String sCadena = beansimple.getPropiedadBasica(); </body> |
TagLibs simples y procesamiento de parámetros
Para simplificar la complejidad de las páginas JSPs, se crean
nuevas etiquetas, de tal modo que los diseñadores gráficos no tienen necesidad
de conocer Java para interactuar con los objetos que deben formatear.
Vamos a crear una etiqueta que muestre un mensaje en pantalla,
concatenando un valor recogido como parámetro. Es decir, esta etiqueta hace
transparente al diseñador como se adquiere, valida o transforma.
package roberto; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTag; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.servlet.jsp.tagext.IterationTag; import javax.servlet.jsp.tagext.Tag; import javax.servlet.jsp.tagext.TagSupport; public class RctagsimpleTag extends BodyTagSupport { private String parametro; public RctagsimpleTag() { super(); } public void otherDoStartTagOperations() { try { JspWriter out = pageContext.getOut(); String sParametro = pageContext.getRequest().getParameter(parametro); out.println("El parámetro en la tag es: " + sParametro); } catch (java.io.IOException ex) { // do something } } public boolean theBodyShouldBeEvaluated() { return true; } public void otherDoEndTagOperations() { } public boolean shouldEvaluateRestOfPageAfterEndTag() { return true; } public int doStartTag() throws JspException, JspException { otherDoStartTagOperations(); if (theBodyShouldBeEvaluated()) { return EVAL_BODY_BUFFERED; } else { return SKIP_BODY; } } public int doEndTag() throws JspException, JspException { otherDoEndTagOperations(); if (shouldEvaluateRestOfPageAfterEndTag()) { return EVAL_PAGE; } else { return SKIP_PAGE; } } public String getParametro() { return parametro; } public void setParametro(String value) { parametro = value; } public void writeTagBodyContent(JspWriter out, BodyContent bodyContent) throws IOException { bodyContent.writeOut(out); bodyContent.clearBody(); } public void handleBodyContentException(Exception ex) throws JspException { // Since the doAfterBody method is guarded, place exception handing code here. throw new JspException("error in RctagsimpleTag: " + ex); } public int doAfterBody() throws JspException { try { JspWriter out = getPreviousOut(); BodyContent bodyContent = getBodyContent(); writeTagBodyContent(out, bodyContent); } catch (Exception ex) { handleBodyContentException(ex); } if (theBodyShouldBeEvaluatedAgain()) { return EVAL_BODY_AGAIN; } else { return SKIP_BODY; } } public boolean theBodyShouldBeEvaluatedAgain() { return false; } } |
Creamos el JSP. Como podemos observar, no hay Scriptlet por
ningún lado.
<%@page contentType=»text/html»%> <%@taglib uri=»rctags.tld» prefix=»rc»%> <html> Vamos a recoger un parametro y pasárselo al Tag <b> </body> |
Y la página resultante:
No olvidar que hace falta el descriptor para que funcione el tag
…..
rctags.tld
<?xml version=»1.0″ encoding=»UTF-8″ ?>
<!DOCTYPE taglib
<taglib> <!– Validators are new in JSP1.2. You may have zero or one validator <!– listeners are new in JSP1.2. You may have as many listeners as you like |
Y tambien hay que incluir un par de lineas en el web.xml
<?xml version=»1.0″ encoding=»UTF-8″?>
<!DOCTYPE web-app <web-app> |
Como sabemos…. todo tiene un porqué … así que … si vemos el código
del servlet que se genera
// begin [file="/jspcontagsimple.jsp";from=(11,0);to=(11,46)] /* ---- rc:rctagsimple ---- */ roberto.RctagsimpleTag _jspx_th_rc_rctagsimple_0 = new roberto.RctagsimpleTag(); _jspx_th_rc_rctagsimple_0.setPageContext(pageContext); _jspx_th_rc_rctagsimple_0.setParent(null); _jspx_th_rc_rctagsimple_0.setParametro("parametropasado"); try { int _jspx_eval_rc_rctagsimple_0 = _jspx_th_rc_rctagsimple_0.doStartTag(); if (_jspx_eval_rc_rctagsimple_0 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) { try { if (_jspx_eval_rc_rctagsimple_0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) { out = pageContext.pushBody(); _jspx_th_rc_rctagsimple_0.setBodyContent((javax.servlet.jsp.tagext.BodyContent) out); _jspx_th_rc_rctagsimple_0.doInitBody(); } do { // end // begin [file="/jspcontagsimple.jsp";from=(11,0);to=(11,46)] } while (_jspx_th_rc_rctagsimple_0.doAfterBody() == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN); } finally { if (_jspx_eval_rc_rctagsimple_0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) out = pageContext.popBody(); } } if (_jspx_th_rc_rctagsimple_0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) return; } finally { _jspx_th_rc_rctagsimple_0.release(); } // end // HTML // begin [file="/jspcontagsimple.jsp";from=(11,46);to=(16,0)] |
Para descargarnos los ficheros que hemos manejado hasta ahora pulsaraquí.
Comunicación entre un TAG y un JavaBean
Podemos crear variables dentro de nuestros tags y luego hacerlos
accesibles desde nuestro código JSP.
El procedimiento es bastante simple ….
Creamos nuestro JSP, donde podemos ver que hemos creado un cadena de
caracteres como un bean … y mostramos en pantalla el valor
<%@page contentType=»text/html»%> <%@taglib uri=»rctags.tld» prefix=»rc»%> <html> <rc:rctagsimple parametro=»parametropasado» /> </b> </body> |
En nuestro TAG, podemos introducir un nuevo valor con el mismo ID y
ámbito
… y ya hemos resuelto el problema
public void otherDoStartTagOperations() { try { JspWriter out = pageContext.getOut(); String sParametro = pageContext.getRequest().getParameter(parametro); String sParametroMayusculas = sParametro.toUpperCase(); pageContext.setAttribute("valorsimple",sParametroMayusculas); out.println("El parámetro en la tag es: " + sParametro); } catch (java.io.IOException ex) { // do something } } |
Si vemos el código que se genera a partir del servlet .. entenderemos el
porqué
// begin [file="/jspcontagybean.jsp";from=(10,0);to=(10,70)] java.lang.String valorsimple = null; boolean _jspx_specialvalorsimple = false; synchronized (pageContext) { valorsimple= (java.lang.String)pageContext.getAttribute("valorsimple",PageContext.PAGE_SCOPE); if ( valorsimple == null ) { _jspx_specialvalorsimple = true; try { valorsimple = (java.lang.String) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "java.lang.String"); } catch (ClassNotFoundException exc) { throw new InstantiationException(exc.getMessage()); } catch (Exception exc) { throw new ServletException (" Cannot create bean of class "+"java.lang.String", exc); } pageContext.setAttribute("valorsimple", valorsimple, PageContext.PAGE_SCOPE); } } |
Y podemos ver que obtenemos el resultado deseado
¿para que podríamos necesitar esto por ahora? pues supongo que
realmente para poco…. si no queremos ser un poco chapuzas…. aunque esta
técnica podría sernos útil para otras cosas … aunque ya veremos que
todo puede ser útil.
Variables de Scripting
Hemos visto en el ejemplo anterior que creamos una variable en nuestro TAG y
la hacemos pública (indirectamente a través de un Bean) a nuestro JSP.
Esto se puede mejorar, haciendo directamente pública la variables utilizando
una técnica que se llama variables de Scripting.
Si vamos a NetBeans.. podemos hacerlo de un modo automático … ya que hay
que realizar varios pasos.
Le damos un nombre
Y decimos al sistema que regenere el código
Vemos que se ha creado una nueva clase …. RCtagsimpleTagTEI ..
necesaria para hacer pública esta variable.
Y en nuestra clase principal han aparecido nuevos métodos
Ahora cambiaremos el código de nuestra tag para establecer el
valor …
Y modificamos la página JSP
<%@page contentType=»text/html»%> <%@taglib uri=»rctags.tld» prefix=»rc»%> <html> <rc:rctagsimple parametro=»parametropasado»> </body> |
y vemos que somos capaces de recuperar el valor sin necesidad de usar la
declaración del bean …..
Podemos recuperar todo el código aquí
Conclusiones
Posibilidades de interacción entre elementos hay muchas.
Lo único que tenemos que tener en cuenta es que debemos proporcionar un
juego de componentes, fundamentalmente de TAG, muy básicos y simples y que no
requieran que los maquetadores deban saber demasiados tecnicismos.
Excelente tutorial, estab buscando algo similar en Internet