/ WEB, ATTRIBUTE, REQUEST, SESSION

Easier attribute management in Java EE

Last year, I’ve been tasked to design a course and teach it to students of the 3rd year of a higher-education school in Geneva. Though I’m a Spring fan, foundations of Spring’s Web MVC take their root in Java EE e.g. servlets and filters. For this reason, I created the course on Java EE.

I started my career with Java and J2EE 1.3. By reading the documentation again, I learned a few things regarding the changes since that time. This post is dedicated to one of my findings: how to manage request/session attributes. The first part is dedicated to how things were done before, the second one to how it can be done nowadays.

The legacy way

If one has previously developed applications in Java EE, one is probably already familiar with the way to pass request attributes from a servlet to another servlet - or to a JSP. Let’s see how it’s done.

Here’s an object, that is instantiated in the controller i.e. a servlet, and passed to the view i.e. a JSP, for display.

public class Thing {

  private final UUID uid;

  Thing() {
    uid = UUID.randomUUID();
  }

  public UUID getUid() {
    return uid;
  }
}

The following servlet will create a Thing instance, and store it in the request scope.

@WebServlet("/")
public class AttributeManagementServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                                              throws ServletException, IOException {
    Thing thing = new Thing();
    req.setAttribute("old", thing);                                    (1)
    req.getRequestDispatcher("/WEB-INF/page.jsp").forward(req, resp);
  }
}
1 Add the Thing instance in the request scope, under the key "old"

This is available since old versions of Java EE. I remember writing similar code with J2EE 1.3.

On the JSP side, it’s very straightforward to access said object, using the Servlet API:

<% Thing thing = (Thing) request.getAttribute("old"); %>
<%= thing.getUid() %>

This part changed quite a bit along the Java EE versions. With JSTL, the above code could be rewritten as:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out value="${requestScope.old.uid}" />

Even better, with Java EE 6, the core JSTL library is not necessary anymore, and an Expression Language expression can be used directly:

${requestScope.old.uid}

The "new" way

Java EE 6 also brought CDI to the platform. As its name implies, CDI is an implementation of the Dependency Injection principle for Java EE - among other things.

To create a new bean that will be associated with each request, the only requirement is to annotate the class with the relevant annotations:

@RequestScoped                           (1)
@Named                                   (2)
public class NewThing extends Thing {    (3)
}
1 @RequestScoped is the magic annotion for the automatic instantiation and injection
2 @Named allows the bean to be accessible under a defined key in the JSP. The key is the simple name of the class, with its first character lower-cased i.e. newThing
3 I’m lazy, and I didn’t want to retype the UUID stuff, so using inheritance is acceptable here

At startup time, the application server will scan the classpath for relevant annotations. The one above will be found, and for every new request, it will create a NewThing instance.

To get access to the bean in the JSP is the matter of just writing the following EL:

${newThing.uid}

Notice there’s no usage of the request scope. That’s because the bean is not stored in the request, but bound to the CDI context! The way to access it is to use the above EL expression, which retrieves from there.

This works with TomEE 7.x. I admit that I don’t know whether this is an implementation detail or part of the specification.

Conclusion

Features of Java EE have changed a lot along its many versions. If you started your journey a long time ago, it’s a good idea to check alternatives on how to achieve a task every now and then. While they might not be overall "better", they might be a better fit in some contexts.

The complete source code for this post can be found on Github in Maven format.
Nicolas Fränkel

Nicolas Fränkel

Nicolas Fränkel is a Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Currently working for Hazelcast. Also double as a teacher in universities and higher education schools, a trainer and triples as a book author.

Read More