2017-01-16 4 views
1

J'essaie de comprendre comment exactement scope attribut dans jsp:useBean JSP action tag. Dans ma compréhension scope est utilisé pour indiquer où le bean est situé (demande, session, application, etc.), mais après quelques tests je suis tombé sur une situation intéressante où ce n'est pas le cas, veuillez considérer le code JSP suivant (j'utilise scriplets ici juste pour des raisons de simplicité):Comment fonctionne l'attribut de portée jsp: useBean?

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
    pageEncoding="ISO-8859-1" import="package2JSP.User" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<title>Title</title> 
</head> 

<body> 
    <% 
     User user1 = new User("id1","name1"); 
     User user2 = new User("id2","name2"); 
     request.setAttribute("user", user1); 
     session.setAttribute("user", user2); 
    %> 
    <%-- Here I expect to create user bean that represents user2 from session scope--%> 
    <jsp:useBean id="user" class="package2JSP.User" scope="session"/> 

    <%-- Here I expect user name to be name2 but it is name1 instead--%> 
    <jsp:getProperty property="name" name="user"/> 
</body> 
</html> 

donc, fondamentalement ici j'ai créé 2 objets utilisateurs et les définir comme « utilisateur » attributs dans les étendues de demande et de session, quand j'ai essayé de récupérer « utilisateur » de « session » portée en utilisant jsp:useBean il semble que "utilisateur" de "demande" portée a été récupérée.

Pouvez-vous m'expliquer pourquoi c'est arrivé? Et quelle était la raison de développement de faire jsp:useBean de cette façon au lieu de sélectionner normalement l'attribut de la portée spécifiée, y at-il des avantages de celui-ci?

Maintenant, je sais que je pourrais utiliser JSTL/EL pour récupérer la valeur nécessaire, c'est-à-dire <c:out value="${sessionScope.user.name}" /> mais je veux juste savoir comment fonctionne jsp:useBean.

Répondre

0

Dans cette situation sont 2 balises impliquées:

  • jsp: useBean
  • jsp: getProperty

Le jsp: useBean

Selon Specification - CHAPTER JSP.5 - JSP.5.1 <jsp:useBean>:

A jsp: associés d'action useBean une instance d'une programmation Java objet langage défini dans un champ donné et disponible avec un ID donné avec une variable de script nouvellement déclarée du même identifiant. Lorsqu'une action est utilisée dans une page sans script ou dans un contexte sans script (comme dans le corps d'une action indiquée), ne crée aucune variable de script Java mais une variable EL créée.

Le code Java compilé est:

 package2JSP.User user = null; 
     synchronized (session) { 
     user = (package2JSP.User) _jspx_page_context.getAttribute("user", PageContext.SESSION_SCOPE); 
     if (user == null){ 
      try { 
      user = (package2JSP.User) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "package2JSP.User"); 
      } catch (ClassNotFoundException exc) { 
      throw new InstantiationException(exc.getMessage()); 
      } catch (Exception exc) { 
      throw new ServletException("Cannot create bean of class " + "package2JSP.User", exc); 
      } 
      _jspx_page_context.setAttribute("user", user, PageContext.SESSION_SCOPE); 
     } 
     } 

Si vous souhaitez accéder à cet objet utilisateur, vous pouvez utiliser un scriptlet (expression) <%=user.getName()%>

Le jsp: getProperty

Selon Specification - CHAPTER JSP.5 - JSP.5.3 <jsp:getProperty> dire:

La valeur de l'attribut de nom dans jsp: setProperty et jsp: getProperty fera référence à un objet qui est obtenu à partir de l'objet pageContext par sa méthode findAttribute .

Le JSP compilateur faire de la balise jsp:getProperty un appel à la findAttribute():

out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString(
    (((package2JSP.User)_jspx_page_context.findAttribute("user")).getName()))); 

findAttribute()
recherches pour l'attribut nommé à la page, demande, session (si elle est valide), et champ (s) d'application dans l'ordre et renvoie la valeur associée ou null.

Fondamentalement: la première correspondance est renvoyée.

L'utilisation de useBean et getProperty est considérée comme une mauvaise pratique.
L'utilisation de JSTL/EL est la meilleure façon de travailler avec des attributs.

+0

Merci pour la clarification. Cela me semble plus comme une faille de conception/développement, si 'jsp: getProperty' utilise' findAttribute' pour obtenir sa valeur alors logiquement je pourrais me débarrasser de ' 'line dans mon fichier jsp et je devrais toujours obtenir" name1 "pour' 'parce que' user' est toujours dans la requête et étendues de session. –

+0

Lorsque j'ai essayé de faire cela, j'ai une exception qui signifie probablement que lorsque vous utilisez 'getProperty', le bean doit être défini par' jsp: useBean'. Eh bien de toute façon j'ai essayé d'obtenir la valeur correcte en utilisant '<% ​​= user.getName()%>' comme vous l'avez suggéré et cela a fonctionné donc le coupable ici est définitivement 'jsp: getProperty' pas' jsp: useBean'. –