Skip to main content

Context And Dependency Injection (JSR 299) And Servlets

Posted by rogerk on September 9, 2009 at 7:34 AM PDT

I've had questions about how to inject Web Beans into servlets and whether that is supported.  In this entry I'll outline a method of accomplishing just that.
This is a simple login application that communicates to a servlet using Ajax calls from a JSP view.  I'm not going to focus on the view or the protocol (Ajax) that  is used to communicate with the servlet.  If you are interested in that, you can check out the source (instructions at the end of this post).  I'm going to focus on the servlet code and the supporting classes for the application.  The application just prompts for a user name / pasword, and pressing the submit button sends those values to a servlet.  First, let's take a look at some of the supporting code for the application:

Listing 1: Login Credentials

  1. package webbeansservlet;
  2.  
  3. import javax.enterprise.context.RequestScoped;
  4. import javax.enterprise.inject.Default;
  5. import javax.inject.Named;
  6.  
  7. /**
  8.  * This is just a simple container class Web Bean for the username
  9.  *  and password entry values.
  10.  */
  11. @Named
  12. @RequestScoped
  13. @Default
  14. public class Credentials {
  15.     private String username = null;
  16.     private String password = null;
  17.     public String getUsername() {
  18.         return username;
  19.     }
  20.     public void setUsername(String username) {
  21.         this.username = username;
  22.     }
  23.     public String getPassword() {
  24.         return password;
  25.     }
  26.     public void setPassword(String password) {
  27.         this.password = password;
  28.     }
  29. }

 

  • Line 11: The name of this Web Bean will be credentials since we don't supply an argument to the Named annotation.
  • Line 12: For the purposes of this simple application this Web Bean scope will be for the current request.
  • Line 13: Specifies the default qualifier type for this Web Bean.  Note that you should not have to specify this if it's the only qualifier type being used.  In future implementations of Web Beans this should be fixed.

Listing 2: Login

  1. package webbeansservlet;
  2.  
  3. import java.io.Serializable;
  4. import javax.enterprise.context.SessionScoped;
  5. import javax.enterprise.inject.Default;
  6. import javax.inject.Inject;
  7. import javax.inject.Named;
  8.  
  9. /**
  10.  * A simple Web Bean that performs a login operation with user's
  11.  * credentials.
  12.  */
  13. @Named
  14. @SessionScoped
  15. @Default
  16. public class Login implements Serializable {
  17.  
  18.     @Inject Credentials credentials;
  19.  
  20.     private boolean loggedIn = false;
  21.  
  22.     /**
  23.      * This is where you could potentially access a database.
  24.      */
  25.     public void login() {
  26.         if ((credentials.getUsername() != null &&
  27.             credentials.getUsername().trim().length() > 0) &&
  28.             (credentials.getPassword() != null &&
  29.             credentials.getPassword().trim().length() > 0)) {
  30.             loggedIn = true;
  31.         }
  32.     }
  33.  
  34.     public boolean isLoggedIn() {
  35.         return loggedIn;
  36.     }
  37.  
  38. }
  • Line 13: The name of this Web Bean will be login
  • Line 14: This Web Bean will exist for the session
  • Line 15: Specifies the default qualifier type for this Web Bean.
  • Line 18: We're injecting an instance of Credentials so we can check the validity of the user name and password entries

Listing 3: Login Servlet

  1. package webbeansservlet;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import javax.enterprise.inject.spi.BeanManager;
  5. import javax.inject.Inject;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.annotation.WebServlet;
  8. import javax.servlet.http.HttpServlet;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11.  
  12. /**
  13.  * This Servlet class demonstrates Web Beans injection.
  14.  */
  15. @WebServlet(name="LoginServlet", urlPatterns={"/LoginServlet"})
  16. public class LoginServlet extends HttpServlet {
  17.  
  18.     // Inject Web Beans Bean Manager.
  19.     @Inject BeanManager m;
  20.  
  21.     // Inject The Credentials Web Bean.
  22.     @Inject Credentials credentials;
  23.  
  24.     // Inject the Login Web Bean.
  25.     @Inject Login login;
  26.  
  27.     /**
  28.      * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
  29.      * @param request servlet request
  30.      * @param response servlet response
  31.      * @throws ServletException if a servlet-specific error occurs
  32.      * @throws IOException if an I/O error occurs
  33.      */
  34.     protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  35.         throws ServletException, IOException {
  36.         response.setContentType("text/html;charset=UTF-8");
  37.         PrintWriter out = response.getWriter();
  38.         credentials.setUsername(request.getParameter("username"));
  39.         credentials.setPassword(request.getParameter("password"));
  40.         login.login();
  41.         try {
  42.             if (login.isLoggedIn()) {
  43.                 out.println("Successfully Logged In As: " + credentials.getUsername());
  44.             } else {
  45.                 out.println("Login Failed: Check username and/or password.");
  46.             }
  47.         } finally {
  48.             out.close();
  49.         }
  50.     }
  51.    .......
  52. }
  • Line 15: New for Servlet 3.0 - eliminates servlet entry in web.xml! Not relevant to this example, but worth mentioning.
  • Line 19: The Web Beans Bean Manager can also be injected.  The Bean Manager api provides some useful methods for interrogating portions of a Web Beans application.
  • Line 22: The Credentials Web Bean is injected making it available to the servlet.
  • Line 38: Now we can access the Credentials Web Bean.
  • Line 40: We can also use the injected Login Web Bean instance.

This is just one example of Web Bean injection into a servlet.  There are more areas in the JavaEE6 platform that can be used as Web Bean injection points - topics that will certainly be covered in future posts.  The sample for this blog can be found under the glassfish-samples project.  You can check out the code following these instructions.  Once the workspace is checked out, you can find this sample under glassfish-samples/ws/javaee6/webbeans/webbeans-servlet.  You can find documentation for the sample under glassfish-samples/ws/javaee6/webbeans/webbeans-servlet/docs.  As with all the Web Beans samples now, you should run with GlassFish V3 - any build after September 2 2009.

Comments

Just trying to understand

Just trying to understand CDI. are my following assumptions correct?. 1)'credentials' object is requestscoped and this object is formed during request and as soon as request is served and response is sent back,'credentials' object is garbage collected by CDI runtime.. 2) login object is session scoped , that means this object stays in memory and accessible(from CDI runtime) during entire user session. 'credentials' object is injected into login , so a copy of 'credentials' object stays inside login object during entire user session.