简体   繁体   中英

Java servlet and JSP accessing the same session bean

Let's say I have a simple Login servlet that checks the passed name and creates User object and stores it in a session.

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

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

In the index.jsp page I access the user object through jsp:useBean

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

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

It works so far.

From the jsp beans documentation

To locate or instantiate the Bean, takes the following steps, in this order:

  1. Attempts to locate a Bean with the scope and name you specify.
  2. Defines an object reference variable with the name you specify.
  3. If it finds the Bean, stores a reference to it in the variable. If you specified type, gives the Bean that type.
  4. If it does not find the Bean, instantiates it from the class you specify, storing a reference to it in the new variable. If the class name represents a serialized template, the Bean is instantiated by java.beans.Beans.instantiate.
  5. If has instantiated (rather than located) the Bean, and if it has body tags or elements (between and ), executes the body tags.

The questions:

Attempts to locate a Bean with the scope and name you specify

It does not specify the "locate" process. Does it mean it will check HttpServletRequest.getSession() or just check whether other pages already created this bean or not?

If it does not find the Bean, instantiates it from the class you specify, storing a > reference to it in the new variable.

This actually means that Jsp can associate a newly created bean with session using jsp_internal_name_user . There is no word about how Jsp stores and finds beans in the session.

There is an option to access session objects by using ${sessionScope.user} and that will guarantee that "user" from the Java session object will be get. The same one I put into by myself.

Java EE 5 example "Book Store" access session objects using ${sessionScope.name} approach.

Using just ${user} works. And this is what worries me. I would like to see a specific sentence in the specification about the locate process and whether ${user} must work or whether it is up to the JSP and/or JSTL reference implementation.

In case of a controller (servlet) which takes care about the model, the jsp:useBean is only useful if the default instance (constructed with the no-arg constructor) exposes different behavior/state than a non-existing instance. Eg if you would like to have a default user name "Unknown User", you would do:

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

Else the enduser may face a "Welcome" instead of "Welcome Unknown User" display. In your particular case, you can safely remove it. It's superfluous.

However, I've also seen the argument that it's useful for pure documentation. You could declare "useless" jsp:useBean instances in top of JSP page so that you have an overview which models exactly are been used in the particular JSP page. Although I find it pretty smart, I myself have never had the need for this way of documenting the model in JSP. As per the comments, another argument is indeed that this way IDE's like IDEA and Eclipse are able to autocomplete bean properties in EL.

Update : as to the locating, it uses PageContext#findAttribute() for that and then uses reflection/javabean introspection to invoke getter methods on it. Eg

${user.name}

roughly resolves to

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

Also see the JSP specification and the JSP EL specification .

Update 2 : the <jsp:useBean> certainly doesn't use an internal name or so as session attribute prefix. Loop over all session attributes yourself to see the actual keys and values:

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

or in a servlet

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

Quoting the JSP spec JSP.5.1

The basic semantic tries to find an existing object using id and scope. If the object is not found it will attempt to create the object using the other attributes.

In other words,

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

would translate roughly into java as:

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

From the documentation:

The <jsp:useBean> element locates or instantiates a JavaBeans component. <jsp:useBean> first attempts to locate an instance of the Bean. If the Bean does not exist, <jsp:useBean> instantiates it from a class or serialized template.

Since "locating" the bean is perfectly allright then we can assume that the bean may be made available by means other than instantiation via <jsp:useBean> . For instance, by creating it in a servlet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM