2010-04-18 18 views
9

Digamos que tengo un servlet de inicio de sesión simple que comprueba el name pasado y crea el objeto User y lo almacena en una sesión.Java servlet y JSP accediendo al mismo bean de sesión

User user = new User(); 
user.setId(name); 

request.getSession().setAttribute("user", user); 
response.sendRedirect("index.jsp"); 

En la página index.jsp accedo al objeto de usuario a través jsp:useBean

<jsp:useBean id="user" scope="session" 
      class="package.name.User"/> 

<div class="panel"> 
    Welcome ${user.id} 
</div> 

Funciona hasta ahora.

De la documentación granos JSP

Para localizar o crear una instancia del Bean, toma los siguientes pasos, en este orden:

  1. intenta localizar un Bean con el alcance y nombre especificar.
  2. Define una variable de referencia de objeto con el nombre que especifique.
  3. Si encuentra el Bean, almacena una referencia en la variable. Si ha especificado el tipo, le da a Bean ese tipo.
  4. Si no encuentra el Bean, crea una instancia de la clase que especifica, guardando una referencia en la nueva variable. Si el nombre de la clase representa una plantilla serializada, Bean se instancia por java.beans.Beans.instantiate.
  5. Si ha instanciado (más que encuentra) el Bean, y si tiene etiquetas del cuerpo o elementos (entre y), ejecuta las etiquetas del cuerpo.

Las preguntas:

intenta localizar un Bean con el alcance y el nombre que especifique

No especifica el proceso de "localizar". ¿Significa que comprobará HttpServletRequest.getSession() o simplemente comprobará si otras páginas ya han creado este bean o no?

Si no encuentra el Bean, crea una instancia de la clase que especifique, almacenando una> referencia a ella en la nueva variable.

En realidad, esto significa que JSP puede asociar un grano recién creada con la sesión utilizando jsp_internal_name_user. No hay ninguna palabra sobre cómo almacena JSP y encuentra los granos en la sesión.

Hay una opción para acceder a los objetos de sesión usando ${sessionScope.user} y eso garantizará que se obtenga el "usuario" del objeto de sesión de Java. El mismo que puse yo mismo.

Java EE 5 ejemplo "Book Store" objetos de sesión de acceso utilizando ${sessionScope.name} enfoque.

El uso de ${user} funciona. Y esto es lo que me preocupa. Me gustaría ver una oración específica en la especificación sobre el proceso locate y si debe funcionar ${user} o si corresponde a la implementación de referencia JSP y/o JSTL.

Respuesta

6

En el caso de un controlador (servlet) que se ocupa del modelo, jsp:useBean solo es útil si la instancia predeterminada (construida con el constructor no-arg) expone un comportamiento/estado diferente al de una instancia no existente. P.ej. si le gustaría tener un nombre de usuario por defecto "Usuario desconocido", que haría:

public User { 
    this.id = "Unknown User"; 
} 

lo contrario el usuario final puede hacer frente a un "Bienvenido" en lugar de la pantalla "Usuario desconocido Bienvenido". En su caso particular, puede eliminarlo de manera segura. Es superfluo

Sin embargo, también he visto el argumento de que es útil para la documentación pura. Podría declarar instancias "inútiles" jsp:useBean en la parte superior de la página JSP para que tenga una visión general de qué modelos se han utilizado exactamente en la página JSP en particular. Aunque me parece bastante inteligente, nunca tuve la necesidad de documentar el modelo en JSP. Según los comentarios, otro argumento es que de esta manera los IDE como IDEA y Eclipse son capaces de autocompletar propiedades de bean en EL.

actualización: en cuanto a la localización, utiliza PageContext#findAttribute() para eso y luego utiliza la reflexión/introspección JavaBean para invocar métodos getter en él. P.ej.

${user.name} 

resuelve más o menos a

out.print(pageContext.findAttribute("user").getName()) 

también ver la JSP specification y la JSP EL specification.

Actualización 2: la <jsp:useBean>duda no utiliza un nombre interno más o menos como prefijo de atributo de sesión. Lazo sobre todos los atributos de sesión ti mismo para ver las claves y los valores reales:

<c:forEach items="${sessionScope}" var="entry"> 
    ${entry.key} = ${entry.value}<br> 
</c:forEach> 

o en un servlet

for (String name : Collections.list(session.getAttributeNames())) { 
    System.out.println(name + " = " + session.getAttribute(name)); 
} 
+0

¿Hay algún tipo de documentación que describen explícitamente el proceso de resolución de las variables en una página JSP? –

+0

Intellij IDEA completa campos variables solo en el caso de la declaración explícita. –

+1

1) ¿Estás hablando de EL? Verifique la [especificación JSP EL] (https://jsp.dev.java.net/spec/jsp-2_1-fr-spec-el.pdf). En pocas palabras, hace 'PageContext # findAttribute()' para localizar atributos en cualquier ámbito. 2) Ese también es otro argumento que he visto antes. – BalusC

2

De la documentación:

El elemento <jsp:useBean> localiza o una instancia de un componente JavaBeans. <jsp:useBean> primero intenta ubicar una instancia del Bean. Si el Bean no existe, <jsp:useBean> lo crea desde una clase o una plantilla serializada de .

Desde "localización" el grano es perfectamente allright entonces podemos asumir que el grano puede ponerse a disposición por medios distintos de instanciación vía <jsp:useBean>. Por ejemplo, al crearlo en un servlet.

4

Citando al JSP.5 especificación JSP.1

La semántica básica trata de encontrar un objeto existente usando ID y alcance. Si no se encuentra el objeto, intentará crear el objeto utilizando los otros atributos .

En otras palabras,

<jsp:useBean id="user" scope="session" class="package.name.User"/> 

se traduciría aproximadamente en Java como:

package.name.User user = (package.name.User)session.getAttribute("user"); 
if (user == null){ 
    user = new package.name.User(); 
    session.setAttribute("user", user); 
} 
+0

Hola, me alegro de verte aquí :) Tu respuesta es correcta para la línea 'jsp: usebean' en particular, solo olvidaste' session.setAttribute ("user", user); 'en el bloque' if';) – BalusC

+0

Me gustaría ver la descripción del proceso "encontrar un existente". De hecho, jsp puede almacenar objetos usando el nombre "user_jsp_internal". –

+0

No, no es así. El objeto se almacena con la clave de atributo como se especifica en 'id'. ¿De qué otro modo podría acceder a él en EL simple por '$ {user}' y así sucesivamente? – BalusC

Cuestiones relacionadas