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:
- Attempts to locate a Bean with the scope and name you specify.
- Defines an object reference variable with the name you specify.
- If it finds the Bean, stores a reference to it in the variable. If you specified type, gives the Bean that type.
- 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.
- 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.
They cannot be stored in a JSP scope object (for page , request , session , or application scope), because only objects can be stored in a scope object.
The Model 2 architecture, as shown in Figure 3, integrates the use of both servlets and JSP pages. In this mode, JSP pages are used for the presentation layer, and servlets for processing tasks. The servlet acts as a controller responsible for processing requests and creating any beans needed by the JSP page.
The JSP engine compiles the servlet into an executable class and forwards the original request to a servlet engine. A part of the web server called the servlet engine loads the Servlet class and executes it. During execution, the servlet produces an output in HTML format.
Create Session BeanIn the New File window, select a category of Enterprise JavaBeans and a file type of Session Bean. Click Next. Select Local as the option for Create Interface. Click Finish.
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. E.g. 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. E.g.
${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));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With