- 04. Java EE 6: DI (JSR 330) and CDI (JSR 299)
- BOOK Study/J2EE
- 2010/01/14 10:40
- Posted by 들기름왕자
Lab Exercises
For the sake of the simplicity of the lab, most exercises are provided in the form of "ready-to-open-and-run" NetBeans projects. (Many of them are borrowed from "glassfish-samples" and "Java EE 6 tutorial".) Please feel free to create them from scratch if you want to.
It is strongly encouraged, leveraging what is provided in this lab, you do your own experimentation meaning creating/adding your own code as much as you can.
If you have written some code that might help everyone else, please feel free to share them on this codecamp email alias or directly send them to the instructors. Your name will be recognized in this lab if your sample code is chosen to be included. For the tasks that need to be done, please see the "Things to be done" section above.)
- Exercise 1: @Inject simple usages (20 minutes)
- Exercise 2: @Inject with @Qualifier (20 minutes)
- Exercise 3: Scope (20 minutes)
- Exercise 4: Producer method (20 minutes)
- Exercise 5: ManagedBean with lifecycle methods (20 minutes)
- Exercise 6: Build and run "weld-servlet" sample application (20 minutes)
- Exercise 7: Build and run "weld-guess" sample application (20 minutes)
- Exercise 8: Event (20 minutes)
- Homework Exercise
Before you start this lab, you have to get sample applications from "glassfish-samples" and "Java EE tutorial" as described in LAB-4530: Java EE 6 - Examples.Exercise 1: @Inject simple usages
더보기
The container injects references to contextual instances to the following kinds of injection point:
- Any injected field of a bean class
- Any parameter of a bean constructor, initializer method, producer method or disposer method
- Any parameter of an observer method, except for the event parameter
- Inject a bean to a field: "inject_bean_to_field" sample application
- Study the code
- Inject a bean via constructor method: "inject_bean_via_constructor" sample application
- Study the code
- Inject a bean via init method: "inject_bean_via_init" sample application
- Study the code
- Inject a bean to a field: "inject_bean_to_field_using_interface" sample application
- Study the code
- Inject an EJB to a field: "inject_ejb_to_field" sample application
- Study the code
(1.1) Inject a bean to a field: "inject_bean_to_field" sample application
1. Open inject_bean_to_field NetBeans project (from "Lab samples")
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Windows: If you unzipped the 4531_javaee6_injection.zip file under C:\ directory, the directory to which you want to browse down should be C:\javaee6_injection\samples.
- Solaris/Linux/Mac: If you unzipped the 4531_javaee6_injection.zip file under $HOME directory, the directory to which you want to browse down should be $HOME/javaee6_injection/samples.
- Select inject_bean_to_field.
- Click Open Project.
- Observe that the inject_bean_to_field project node appears under Projects tab window.
2. Build and run inject_bean_to_field project.
- Right-click inject_bean_to_field project and select Run.
- Observe that the browser gets displayed.

Figure-1.11
(1.2) Study the code of the project
| package mypackage; import java.io.IOException; import java.io.PrintWriter; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet"}) public class HelloServlet extends HttpServlet { // You need an empty beans.xml in the WEB-INF directory to enable Weld // Inject Greeting object @Inject Greeting greeting; /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // out.println("<html>"); out.println("<head>"); out.println("<title>Servlet HelloServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Calling a method of an injected class: " + greeting.greet("Codecamper!") + "</h1>"); out.println("</body>"); out.println("</html>"); // } finally { out.close(); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> } |
- Display context senstive Javadoc on @Inject.

Figure-1.21

Figure-1.22
2. Study Greeting.java.
| package mypackage; public class Greeting { public String greet(String name){ return "Hello " + name; } } |
3. Study beans.xml.
An application that uses CDI must have a file named beans.xml. The file can be completely empty (it has content only in certain limited situations), but it must be present. For a web application, the beans.xml file can be in either the WEB-INF directory or the WEB-INF/classes/META-INF directory. For EJB modules or JAR files, the beans.xml file must be in the META-INF directory.
| <?xml version="1.0" encoding="UTF-8"?> <beans/> |

Figure-1.21
(1.3) Inject a bean via constructor method: "inject_bean_via_constructor" sample application
1. Open inject_bean_via_constructor NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_bean_via_constructor.
- Click Open Project.
- Observe that the inject_bean_via_constructor project node appears under Projects tab window.
2. Build and run inject_bean_via_constructor project.
- Right-click inject_bean_via_constructor project and select Run.
- Observe that the browser gets displayed.

Figure-1.31
(1.4) Study code
1. HelloServlet.java
| package mypackage; import java.io.IOException; import java.io.PrintWriter; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet"}) public class HelloServlet extends HttpServlet { private Greeting greeting; // Use constructor method injection @Inject void HelloServlet(Greeting greeting){ this.greeting = greeting; } /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // out.println("<html>"); out.println("<head>"); out.println("<title>Servlet HelloServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Calling a method of an injected class: " + greeting.greet("Codecamper!") + "</h1>"); out.println("</body>"); out.println("</html>"); // } finally { out.close(); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> } |
(1.5) Inject a bean via init method: "inject_bean_via_init" sample application
1. Open inject_bean_via_init NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_bean_via_init.
- Click Open Project.
- Observe that the inject_bean_via_init project node appears under Projects tab window.
2. Build and run inject_bean_via_init project.
- Right-click inject_bean_via_init project and select Run.
- Observe that the browser gets displayed.

Figure-1.51
(1.6) Study code
1. Study the code - HelloServlet.java.
| package mypackage; import java.io.IOException; import java.io.PrintWriter; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet"}) public class HelloServlet extends HttpServlet { private Greeting greeting; // Use initializer method injection @Inject void init(Greeting greeting){ this.greeting = greeting; } /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // out.println("<html>"); out.println("<head>"); out.println("<title>Servlet HelloServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Calling a method of an injected class: " + greeting.greet("Codecamper!") + "</h1>"); out.println("</body>"); out.println("</html>"); // } finally { out.close(); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> } |
(1.7) Inject a bean to a field: "inject_bean_to_field_using_interface" sample application
In this exercise, you are going to inject a bean whose type is a Java interface.
1. Open inject_bean_to_field_using_interface NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_bean_to_field_using_interface.
- Click Open Project.
- Observe that the inject_bean_to_field_using_interface project node appears under Projects tab window.
2. Build and run inject_bean_to_field_using_interface project.
- Right-click inject_bean_to_field_using_interface project and select Run.
- Observe that the browser gets displayed.

Figure-1.71
(1.8) Study code
1. GreetingInterface.java
| package mypackage; public interface GreetingInterface { public String greet(String name); } |
2. FormalGreeting.java
| package mypackage; public class FormalGreeting implements GreetingInterface { public String greet(String name){ return "Formal Hello " + name; } } |
3. HelloServlet.java
| package mypackage; import java.io.IOException; import java.io.PrintWriter; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet"}) public class HelloServlet extends HttpServlet { // You need an empty beans.xml in the WEB-INF directory to enable Weld // Inject GreetingInterface object @Inject GreetingInterface greeting; /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // out.println("<html>"); out.println("<head>"); out.println("<title>Servlet HelloServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Calling a method of an injected class: " + greeting.greet("Codecamper!") + "</h1>"); out.println("</body>"); out.println("</html>"); // } finally { out.close(); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> } |
(1.9) Inject an EJB to a field: "inject_ejb_to_field" sample application
In this exercise, you are going to inject EJB object (instead of regular bean) into a field. Given that you can inject an EJB through @Inject, you might have a question - "Is there any reason to use @Inject or @EJB when injecting EJB?" The answer from Ken Saks (EJB 3.1 spec lead) is as following:
"Yes, @EJB provides a static mapping to the target EJB component based on Java type and any specific linking metadata like beanName() or lookup(). The result of the injection is the actual EJB reference. (Note that this is still distinct from a
target bean *instance*)
@Inject adds an additional level of indirection by way of CDI, where the target EJB component is resolved via CDI's type-safe resolution algorithm. The result of injection is a CDI object that has an internal run-time mapping to a particular EJB reference. This allows whatever CDI scope is in context at the time of invocation to determine the target EJB reference.
Basically, if you want the additional CDI semantics to apply, use @Inject. Otherwise, use @EJB."
1. Open inject_ejb_to_field NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_ejb_to_field.
- Click Open Project.
- Observe that the inject_ejb_to_field project node appears under Projects tab window.
2. Build and run inject_ejb_to_field project.
- Right-click inject_ejb_to_field project and select Run.
- Observe that the browser gets displayed.

Figure-1.91
(1.10) Study code
1. Greeting.java. Greeting is a stateless EJB.
| package mypackage; import javax.ejb.Stateless; @Stateless public class Greeting { public String greet(String name){ return "Hello " + name; } } |
Summary
In this exercise, you have learned how to inject a bean to a field, through constructor and init methods through @Inject annotation. You also learned how to inject EJB through @EJB annotation.
Exercise 2: @Inject usage with @Qualifier
더보기
For a given bean type, there may be multiple beans which implement the type. You can use qualifiers to provide different implementations of a particular bean type. A qualifier is an annotation that you apply to a bean. A qualifier type is a Java annotation defined as @Target({METHOD, FIELD, PARAMETER, TYPE}) and @Retention(RUNTIME).
(2.1) Experience "ambiguity" error condition
In this step, you are going to add InformalGreeting class which implements GreetingInterface to the inject_bean_to_field_using_interface project. In other words, there are two classes, FormalGreeting and InformalGreeting classes which implement GreetingInterface interface. This will cause ambiguity error condition.
1. Add InformalGreeting.java. InformalGreeting class is added as the second class that implements GreetingInterface interface.

Figure-2.11

Figure-2.12
3. Modify the IDE generated InformalGreeting.java with the code below. Note that InformalGreeting implements GreetingInterface.
| package mypackage; public class InformalGreeting implements GreetingInterface { public String greet(String name){ return "Informal Hello " + name; } } |
4. Build and run and observe error condition.
- Right click the project and select Run.
- Observe the AmbiguousResolutionException occurred as expected.

Figure-2.13
Note: The completed version of this step is available as inject_qualifier_ambiguitycase project under <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory. You can just build and run it to see the above result.
(2.2) User qualifier
In this step, you are going to define @Formal and @Informal qualifier types and apply them to FormalGreeting and InformalGreeting classes, which are the implementations of the GreetingInterface interface.
If you define a bean with no qualifier, it automatically has the qualifier @Default.
1. Add @Formal qualifier definition. This is a marker interface that does not require a processor action. If you are not sure how to define an annotation, please study Java Annotaiton.
| package mypackage; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({ TYPE, METHOD, FIELD, PARAMETER }) public @interface Formal { } |
2. Add @Informal qualifier definition.
| package mypackage; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({ TYPE, METHOD, FIELD, PARAMETER }) public @interface Informal { } |
3. Modify FormalGreeting class to get annotated with @Formal qualifier.
| package mypackage; @Formal public class FormalGreeting implements GreetingInterface { public String greet(String name){ return "Formal Hello " + name; } } |
4. Modify InformalGreeting class to get annotated with @Informal qualifier.
| package mypackage; @Informal public class InformalGreeting implements GreetingInterface { public String greet(String name){ return "Informal Hello " + name; } } |
5. Modify HelloServlet class to inject the Formal qualified type of the GreetingInterface
| package mypackage; import java.io.IOException; import java.io.PrintWriter; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet"}) public class HelloServlet extends HttpServlet { // You need an empty beans.xml in the WEB-INF directory to enable Weld // Inject GreetingInterface object using qualifier @Inject @Formal GreetingInterface greeting; /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // out.println("<html>"); out.println("<head>"); out.println("<title>Servlet HelloServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Calling a method of an injected class: " + greeting.greet("Codecamper!") + "</h1>"); out.println("</body>"); out.println("</html>"); // } finally { out.close(); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> } |
6. Run the project.

Figure-2.21
Solution: The completed version is available as inject_qualifier project under <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory. You can just build and run it to see the above result.
Summary
In this exercise, you have learned how to use qualifier when there are multiple implementations of a particular bean type.
Exercise 3: Scope
더보기
- @RequestScoped
- A user's interaction with a web application in a single HTTP request
- @SessionScoped
- A user's interaction with a web application across multiple HTTP requests
- @ApplicationScoped
- Shared state across all users' interactions with a web application
- @Dependent
- The default scope if none is specified; it means that an object exists to serve exactly one client (bean), and has the same lifecycle as that client (bean)
- @ConversationScoped
- A user's interaction with a JavaServer Faces application, within explicit boundaries controlled by the developer that extend the scope across multiple invocations of the JavaServer Faces life cycle. All long-running conversations are scoped to a particular HTTP servlet session and may not cross session boundaries.
(3.1) Use @RequestScoped
In this exercise, you are going to see a bean - Printer bean - whose scope is defined with @RequestScoped annotation.
1. Open inject_scope_request NetBeans project (from "Lab samples")
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_scope_request.
- Click Open Project.
- Observe that the inject_scope_request project node appears under Projects tab window.
2. Build and run inject_scope_request project.
- Right-click inject_scope_request project and select Run.
- Observe that the browser gets displayed.
- For the Enter your name field, enter <your name>.
- Click Say Hello button.

Figure-3.11

Figure-3.12
(3.2) Study the code
| <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <ui:composition template="/template.xhtml"> <ui:define name="title">Simple Greeting</ui:define> <ui:define name="head">Simple Greeting</ui:define> <ui:define name="content"> <h:form id="greetme"> <p><h:outputLabel value="Enter your name: " for="name"/> <h:inputText id="name" value="#{printer.name}"/></p> <p><h:commandButton value="Say Hello" action="#{printer.createSalutation}"/></p> <p><h:outputText value="printer.salutation = #{printer.salutation}"/> </p> </h:form> </ui:define> </ui:composition> </html> |
2. Printer.java.
| import javax.inject.Inject; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @Named @RequestScoped public class Printer { @Inject @Informal Greeting greeting; private String name; private String salutation = "nothing yet!"; public void createSalutation() { this.salutation = greeting.greet(name); } public String getSalutation() { return salutation; } public void setName(String name) { this.name = name; } public String getName() { return name; } } |
(3.3) Use @ConversationScoped
1. Open inject_scope_conversation NetBeans project (from "Lab samples")
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_scope_conversation.
- Click Open Project.
- Observe that the inject_scope_conversation project node appears under Projects tab window.
2. Build and run inject_scope_conversation project.
- Right-click inject_scope_conversation project and select Run.
- Observe that the browser gets displayed.

Figure-3.31

Figure-3.32

Figure-3.33

Figure-3.34
4. Run the application in Conversation scope.
- Click Start Conversation button. This will start the conversation scope.

Figure-3.35
- Observe that the conversation scope is on.

Figure-3.36
- For the Enter your name field, enter a name.
- Click Say Hello button.

Figure-3.37

Figure-3.38

Figure-3.39

Figure-3.40
5. Turn off the conversation.

Figure-3.41

Figure-3.42

Figure-3.43

Figure-3.44
(3.4) Study code
1. index.html
| <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <ui:composition template="/template.xhtml"> <ui:define name="title">Simple Greeting</ui:define> <ui:define name="head">Simple Greeting</ui:define> <ui:define name="content"> <h:form id="greetme"> <p><h:outputLabel value="Enter your name: " for="name"/> <h:inputText id="name" value="#{printer.name}"/></p> <p><h:commandButton value="Say Hello" action="#{printer.createSalutation}"/></p> <p><h:commandButton value="Start conversation" action="#{printer.startConversation}"/></p> <p><h:commandButton value="End conversation" action="#{printer.endConversation}"/></p> <p><h:outputText value="printer.salutation = #{printer.salutation}"/> </p> <p><h:outputText value="printer.old_salutation = #{printer.old_salutation}"/> </p> <p><h:outputText value="myConversationStatus.conversationSattus = #{myConversationStatus.conversationSattus}"/> </p> </h:form> </ui:define> </ui:composition> </html> |
2. Printer.java
| package greetings; import java.io.Serializable; import javax.enterprise.context.Conversation; import javax.enterprise.context.ConversationScoped; import javax.inject.Inject; import javax.inject.Named; @Named @ConversationScoped public class Printer implements Serializable { @Inject @Informal Greeting greeting; @Inject Conversation conversation; @Inject MyConversationStatus cstatus; private String name; private String salutation = "nothing yet!"; private String old_salutation = "nothing yet!"; public void startConversation() { cstatus.setConversationSattus("on"); conversation.begin(); } public void endConversation() { cstatus.setConversationSattus("off"); conversation.end(); } public void createSalutation() { this.old_salutation = salutation; this.salutation = greeting.greet(name); } public String getSalutation() { return salutation; } public void setName(String name) { this.name = name; } public String getName() { return name; } /** * @return the old_salutation */ public String getOld_salutation() { return old_salutation; } /** * @param old_salutation the old_salutation to set */ public void setOld_salutation(String old_salutation) { this.old_salutation = old_salutation; } } |
Summary
In this exercise, you have learned, for a web application to use a bean that injects another bean class, how to use scope for holding state over the duration of the user's interaction with the application.
Exercise 4: Producer Methods
더보기
Producer methods provide a way to inject objects that are not beans, objects whose values may vary at run time, and objects that require custom initialization.
(4.1) Open, build, and run "inject_producer_businesslogic" sample application
1. Open inject_producer_businesslogic NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select inject_producer_businesslogic.
- Click Open Project.
- Observe that the inject_producer_businesslogic project node appears under Projects tab window.
2. Build and run inject_producer_businesslogic project.
- Right-click inject_producer_businesslogic project and select Run.
- Observe that the browser gets displayed.

Figure-4.11
(4.2) Study code
1. HelloServlet.java
| package mypackage; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "HelloServlet", urlPatterns = {"/HelloServlet"}) public class HelloServlet extends HttpServlet { @Inject @Formal String greetingMessage; /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { // out.println("<html>"); out.println("<head>"); out.println("<title>Servlet HelloServlet</title>"); out.println("</head>"); out.println("<body>"); //out.println("<h1>Calling a method of an injected class: " + greeting.greet("Codecamper!") + "</h1>"); out.println("<h1>" + new Date() + ": " + greetingMessage + "</h1>"); out.println("</body>"); out.println("</html>"); // } finally { out.close(); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> } |
2. FormalGreeting.java. Note that the @Formal annotation is used not with the FormalGreeting class but with the getFormalGreeting() method, in which you can produce and return an object of @Formal type.
| package mypackage; import java.util.Calendar; import java.util.GregorianCalendar; import javax.enterprise.inject.Produces; public class FormalGreeting { String formalGreeting; // Produces greeting message based on business logic. @Produces @Formal public String getFormalGreeting() { GregorianCalendar todaysDate = new GregorianCalendar(); int hour_of_day = todaysDate.get(Calendar.HOUR_OF_DAY); if (hour_of_day < 12) { formalGreeting = "Good morning!"; } if (hour_of_day > 11 && hour_of_day < 17) { formalGreeting = "Good afternoon!"; } if (hour_of_day >= 17 && hour_of_day < 22) { formalGreeting = "Good evening!"; } if (hour_of_day >= 22) { formalGreeting = "Good night!"; } return formalGreeting; } } |
Summary
In this exercise, you have learned how to provide a way to inject objects whose values may vary at run time based on business logic through @Produces annotation.
Exercise 5: Managed Bean with Lifecycle methods
더보기
The ManagedBean annotation marks a POJO (Plain Old Java Object) as a ManagedBean. A ManagedBean supports a small set of basic services such as resource injection, lifecycle callbacks and interceptors.
- Open, build, and run "managedbean_lifecycle_defaultscope" sample application
- Study the code
- Open, build, and run "managedbean_lifecycle_requestscope" sample application
- Study the code
- Open, build, and run "managedbean_interceptor" sample application
- Study the code
(5.1) Open, build, and run "managedbean_lifecycle_defaultscope" sample application (from "Lab samples")
1. Open managedbean_lifecycle_defaultscope NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select managedbean_lifecycle_defaultscope.
- Click Open Project.
- Observe that the managedbean_lifecycle_defaultscope project node appears under Projects tab window.
2. Build and run managedbean_lifecycle_defaultscope project.
- Right-click managedbean_lifecycle_defaultscope project and select Run.
- Observe that the browser gets displayed.

Figure-5.11

Figure-5.12

Figure-5.13

Figure-5.14
(5.2) Study code
1. Greeting.java
| package mypackage; import javax.annotation.ManagedBean; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @ManagedBean public class Greeting { public String greet(String name) { return "Hello " + name; } @PostConstruct private void init() { System.out.println("\n=======> init() method is called as PostConstruct"); } @PreDestroy private void release() { System.out.println("=======> release() method is called as PreDestroy"); } } |
(5.3) Open, build, and run "managedbean_lifecycle_requestscope" sample application
1. Open managedbean_lifecycle_requestscope NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select managedbean_lifecycle_requestscope.
- Click Open Project.
- Observe that the managedbean_lifecycle_requestscope project node appears under Projects tab window.
2. Build and run managedbean_lifecycle_requestscope project.
- Right-click managedbean_lifecycle_requestscope project and select Run.
- Observe that the browser gets displayed.

Figure-5.31
(5.4) Study code
| package mypackage; import javax.annotation.ManagedBean; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.RequestScoped; @ManagedBean @RequestScoped public class Greeting { public String greet(String name) { return "Hello " + name; } @PostConstruct private void init() { System.out.println("\n=======> init() method is called as PostConstruct"); } @PreDestroy private void release() { System.out.println("=======> release() method is called as PreDestroy"); } } |
(5.5) Open, build, and run "managedbean_interceptor" sample application
1. Open managedbean_interceptor NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select managedbean_interceptor.
- Click Open Project.
- Observe that the managedbean_interceptor project node appears under Projects tab window.
2. Build and run managedbean_interceptor project.
- Right-click managedbean_interceptor project and select Run.
- Observe that the browser gets displayed.

Figure-5.51
(5.6) Study code
1. Greeting.java
| package mypackage; import javax.annotation.ManagedBean; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.RequestScoped; import javax.interceptor.Interceptors; @ManagedBean @RequestScoped @Interceptors(LoggingInterceptor.class) public class Greeting { public String greet(String name) { return "Hello " + name; } @PostConstruct private void init() { System.out.println("\n=======> init() method is called as PostConstruct"); } @PreDestroy private void release() { System.out.println("=======> release() method is called as PreDestroy"); } } |
2. LoggingInterceptor.java
| package mypackage; import java.util.logging.Logger; import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; // This class will be used as an interceptor. public class LoggingInterceptor { private Logger logger = Logger.getLogger("mypackage"); @AroundInvoke public Object logMethod(InvocationContext ic) throws Exception { logger.info("------> " + ic.getTarget().getClass() + ", method name: " + ic.getMethod().getName()); try { return ic.proceed(); } finally { logger.info("<------ " + ic.getTarget().getClass() + ", method name: " + ic.getMethod().getName()); } } } |
Summary
In this exercise, you have learned how to use managed bean with lifecycle methods. You also leraned how to use interceptor with a managed bean.
Exercise 6: Build and run "weld-servlet" sample application
더보기
The "weld-servlet" sample application is provided as a sample application from "glassfish-samples". The description of this sample application is available from "Context and Dependency Injection And Servlets" blog by Roger Kitain.
(6.1) Open, build, and run "weld-servlet" sample application (from "glassfish-samples")
1. Open weld-servlet NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/weld directory.
- Select weld-servlet.
- Click Open Project.

Figure-6.11
- Observe that the weld-servlet project node appears under Projects tab window.
2. Build and run weld-servlet project.
- Right-click weld-servlet project and select Run.
- Observe that the browser gets displayed.
- For the User Name field, enter <your name>.
- For the Password field, enter whatever password of your choice.
- Click Submit button.

Figure-6.12
- Observe that "Successfully Logged In As: <your name>" message gets displayed at the bottom.

Figure-6.13
(6.2) Study the code
1. web.xml
| <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
2. index.jsp
| <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Weld Servlet Injection</title> <script type="text/javascript" src="resources/ajax.js"> </script> <link type="text/css" rel="stylesheet" href="/weld-servlet/resources/stylesheet.css" /> </head> <body> <form name="myForm" method="POST" action="LoginServlet"> <table class="title-panel"> <tbody> <tr> <td><span class="title-panel-text">Login Servlet</span></td> </tr> <tr> <td><span class="title-panel-subtext">Powered By Servlet 3.0 and Weld</span></td> </tr> </tbody> </table> <table height="30" style="font-size: 16px"> <tr> <td>Enter any value for user name and password.</td> </tr> </table> <table style="font-size: 16px"> <tr> <td style="color:red">*</td> <td>Denotes required entry.</td> </tr> </table> <table height="30"> <table border="1" style="font-size: 18px"> <tr> <td>User Name:</td> <td><input type="text" name="username" id="username" /></td> <td style="color:red">*</td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password" id="password" /></td> <td style="color:red">*</td> </tr> </table> <table border="1"> <tr> <td colspan="2"><input type="button" value="Submit" onclick="ajaxFunction();" /></td> <td colspan="2"><input type="button" value="Reset" onclick="resetFunction();" /></td> </tr> </table> </table> <table height="20"> <tr> <td><div id="message" style="color:red;font-size: 14px"></td> </tr> </table> </form> </body> </html> |
3. LoginServlet.java
| package weldservlet; import java.io.IOException; import java.io.PrintWriter; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * This Servlet class demonstrates Weld injection. */ @WebServlet(name="LoginServlet", urlPatterns={"/LoginServlet"}) public class LoginServlet extends HttpServlet { // BeanManager interface allows a portable extension to interact directly with // the container. Provides operations for obtaining contextual references for // beans, along with many other operations of use to portable extensions. // It is not used in this application. // Inject Weld Bean Manager. @Inject BeanManager m; // Inject The Credentials Weld bean. @Inject Credentials credentials; // Inject the Login Weld bean. @Inject Login login; /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // Because credentials variable is injected with Credentials object by the container, // you can use it here without yourself assigning it. credentials.setUsername(request.getParameter("username")); credentials.setPassword(request.getParameter("password")); // Because login variable is injected with Login object by the container, // you can use it here without yourself assigning it. login.login(); try { if (login.isLoggedIn()) { out.println("Successfully Logged In As: " + credentials.getUsername()); } else { out.println("Login Failed: Check username and/or password."); } } finally { out.close(); } } /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; } } |
4. Credentials.java.
| package weldservlet; import java.io.Serializable; import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Default; import javax.inject.Named; /** * This is just a simple container class Weld bean for the username * and password entry values. */ @Named @RequestScoped @Default public class Credentials implements Serializable { private String username = null; private String password = null; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } |
5. Login.java.
| package weldservlet; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Default; import javax.inject.Inject; import javax.inject.Named; /** * A simple Weld Bean that performs a login operation with user's * credentials. */ @Named @SessionScoped @Default public class Login implements Serializable { // Credential object is already initialized with // username and password input parameters // is placed in the request scope object. @Inject Credentials credentials; private boolean loggedIn = false; /** * This is where you could potentially access a database. */ public void login() { if ((credentials.getUsername() != null && credentials.getUsername().trim().length() > 0) && (credentials.getPassword() != null && credentials.getPassword().trim().length() > 0)) { loggedIn = true; } } public boolean isLoggedIn() { return loggedIn; } } |
Summary
In this exercise, you have played with a sample application that uses dependency injection.
Exercise 7: Build and run "weld-guess" sample application
더보기
The description of of this example is provided as part of Java EE 6 tutorial.
(7.1) Open, build, and run "weld-guess" sample application (from "glassfish-samples")
1. Open weld-guess NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/weld directory.
- Select weld-guess.
- Click Open Project.
- Observe that the weld-guess project node appears under Projects tab window.
2. Build and run weld-guess project.
- Right-click weld-guess project and select Run.
- Browser gets displayed.

Figure-7.11

Figure-7.12

Figure-7.13
(7.2) Study the code
| <html> <head> <meta http-equiv="Refresh" content="0; URL=home.jsf"> </head> </html> |
2. home.xhtml
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>JSF 2.0 Weld Example</title> </h:head> <h:body> <h:form id="NumberGuessMain"> <h:panelGrid styleClass="title-panel"> <h:outputText value="Guess Number" styleClass="title-panel-text"/> <h:outputText value="Powered By JavaServer Faces 2.0 and Weld" styleClass="title-panel-subtext"/> </h:panelGrid> <div style="color: black; font-size: 24px;"> I'm thinking of a number between <span style="color: blue">#{game.smallest}</span> and <span style="color: blue">#{game.biggest}</span>. You have <span style="color: blue">#{game.remainingGuesses}</span> guesses. </div> <h:panelGrid border="1" columns="5" style="font-size: 18px;"> Number: <h:inputText id="inputGuess" value="#{game.guess}" required="true" size="3" disabled="#{game.number eq game.guess}" validator="#{game.validateNumberRange}"> </h:inputText> <h:commandButton id="GuessButton" value="Guess" action="#{game.check}" disabled="#{game.number eq game.guess}"/> <h:commandButton id="RestartButton" value="Reset" action="#{game.reset}" immediate="true" /> <h:outputText id="Higher" value="Higher!" rendered="#{game.number gt game.guess and game.guess ne 0}" style="color: red"/> <h:outputText id="Lower" value="Lower!" rendered="#{game.number lt game.guess and game.guess ne 0}" style="color: red"/> </h:panelGrid> <div style="color: red; font-size: 14px;"> <h:messages id="messages" globalOnly="false"/> </div> <h:outputStylesheet name="stylesheet.css" /> </h:form> </h:body> </html> |
3. Game.java.
| package weldguess; import java.io.Serializable; import javax.annotation.PostConstruct; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.inject.Named; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; @Named @SessionScoped public class Game implements Serializable { private static final long serialVersionUID = 1L; private int number; private int guess; private int smallest; // Inject an object which is qualified with // @MaxNumber qualifier. @MaxNumber @Inject private int maxNumber; private int biggest; private int remainingGuesses; // Inject an object which is qualified with // @Random qualifier. @Random @Inject Instance<Integer> randomNumber; public Game() { } public int getNumber() { return number; } public int getGuess() { return guess; } public void setGuess(int guess) { this.guess = guess; } public int getSmallest() { return smallest; } public int getBiggest() { return biggest; } public int getRemainingGuesses() { return remainingGuesses; } public String check() throws InterruptedException { if (guess>number) { biggest = guess - 1; } if (guess<number) { smallest = guess + 1; } if (guess == number) { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!")); } remainingGuesses--; return null; } @PostConstruct public void reset() { this.smallest = 0; this.guess = 0; this.remainingGuesses = 10; this.biggest = maxNumber; this.number = randomNumber.get(); } public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) { if (remainingGuesses <= 0) { FacesMessage message = new FacesMessage("No guesses left!"); context.addMessage(toValidate.getClientId(context), message); ((UIInput)toValidate).setValid(false); return; } int input = (Integer) value; if (input < smallest || input > biggest) { ((UIInput)toValidate).setValid(false); FacesMessage message = new FacesMessage("Invalid guess"); context.addMessage(toValidate.getClientId(context), message); } } } |
4. Generator.java.
| package weldguess; import java.io.Serializable; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; @ApplicationScoped public class Generator implements Serializable { private static final long serialVersionUID = -7213673465118041882L; private java.util.Random random = new java.util.Random( System.currentTimeMillis() ); private int maxNumber = 100; java.util.Random getRandom() { return random; } @Produces @Random int next() { return getRandom().nextInt(maxNumber); } @Produces @MaxNumber int getMaxNumber() { return maxNumber; } } |
5. MaxNumber.java.
| package weldguess; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; // Define @MaxNumber qualifier annotation @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented @Qualifier public @interface MaxNumber { } |
6. Random.java.
| package weldguess; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; // Define @Random qualifier annotation @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented @Qualifier public @interface Random { } |
Summary
In this exercise, you have played with a sample application that uses dependency injection.
Exercise 8: Event
더보기
Beans may produce and consume events. This facility allows beans to interact in a completely decoupled fashion, with no
compile-time dependency between the interacting beans. Most importantly, it allows stateful beans in one architectural tier
of the application to synchronize their internal state with state changes that occur in a different tier.
An event comprises:
- A Java object—the event object
- A (possibly empty) set of instances of qualifier types—the event qualifiers
The event object acts as a payload, to propagate state from producer to consumer. The event qualifiers act as topic selectors,
allowing the consumer to narrow the set of events it observes.
An observer method acts as event consumer, observing events of a specific type—the observed event type—with a specific
set of qualifiers—the observed event qualifiers. An observer method will be notified of an event if the event object is assignable
to the observed event type, and if all the observed event qualifiers are event qualifiers of the event.
- Open, build, and run "weld-servlet-event" sample application
- Study the code
- Add more event handlers
- Fire @Admin qualified event
(8.1) Open, build, and run "weld-servlet-event" sample application
1. Open weld-servlet-event NetBeans project (from "Lab samples").
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/samples directory.
- Select weld-servlet-event.
- Click Open Project.
- Observe that the weld-servlet-event project node appears under Projects tab window.
2. Build and run weld-servlet-event project.
- Right-click weld-servlet-event project and select Run.
- Browser gets displayed.
- For the User Name field, enter sangshin (or whatever user name of your choce).
- For the Password field, enter whatever password of your choice.
- Click Submit button.

Figure-8.11
- Observe that "Successfully Logged In As: <your user name>" message gets displayed at the bottom.

Figure-8.12
3. Observe that the event handler is invoked.
- Click GlassFish v3 Domain tab under Outout window.
- Observe that "INFO: ----afterLogin() method is called, .." message is displayed.

Figure-8.13
(8.2) Study code
| package weldservlet; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.enterprise.inject.Any; import javax.enterprise.inject.Default; import javax.inject.Inject; import javax.inject.Named; /** * A simple Weld Bean that performs a login operation with user's * credentials. */ @Named @SessionScoped @Default public class Login implements Serializable { @Inject Credentials credentials; // Inject LoggedEvent @Inject @Any Event<LoggedInEvent> loggedInEvent; private boolean loggedIn = false; /** * This is where you could potentially access a database. */ public void login() { if ((credentials.getUsername() != null && credentials.getUsername().trim().length() > 0) && (credentials.getPassword() != null && credentials.getPassword().trim().length() > 0)) { loggedIn = true; // Fire an event when successful login loggedInEvent.fire(new LoggedInEvent(credentials.getUsername())); } } public boolean isLoggedIn() { return loggedIn; } // This methog gets invoked when LoggedInEvent is fired public void afterLogin(@Observes LoggedInEvent event) { System.out.println("----afterLogin() method is called, event = " + event); } } |
2. LoggedInEvent.java
| package weldservlet; public class LoggedInEvent { private String user; public LoggedInEvent(String user) { this.user = user; } } |
(8.3) Add more event handlers
1. Add Admin.java. This is to define @Admin qualifier marker annotation.
| package weldservlet; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented @Qualifier public @interface Admin { } |

Figure-8.31
2. Modify Login.java as shown below. The modification is to add two extra event handlers. The code fragments that need to be added are highlighted in bold and red-colored font.
| package weldservlet; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.enterprise.inject.Any; import javax.enterprise.inject.Default; import javax.inject.Inject; import javax.inject.Named; /** * A simple Weld Bean that performs a login operation with user's * credentials. */ @Named @SessionScoped @Default public class Login implements Serializable { @Inject Credentials credentials; // Inject LoggedEvent @Inject @Any Event<LoggedInEvent> loggedInEvent; private boolean loggedIn = false; /** * This is where you could potentially access a database. */ public void login() { if ((credentials.getUsername() != null && credentials.getUsername().trim().length() > 0) && (credentials.getPassword() != null && credentials.getPassword().trim().length() > 0)) { loggedIn = true; // Fire an event when successful login loggedInEvent.fire(new LoggedInEvent(credentials.getUsername())); } } public boolean isLoggedIn() { return loggedIn; } // This methog gets invoked when LoggedInEvent is fired public void afterLogin(@Observes LoggedInEvent event) { System.out.println("----afterLogin() method is called, event = " + event); } // Capture any event (same as above) public void afterAnyLogin(@Observes @Any LoggedInEvent event) { System.out.println("----afterAnyLogin() method is called, event = " + event); } // Capture only @Admin qualified event public void afterAdminLogin(@Observes @Admin LoggedInEvent event) { System.out.println("----afterAdminLogin() method is called, event = " + event); } } |

Figure-8.32
3. Build and run the application.
- Right-click weld-servlet-event-qualifier project and select Run.
- Browser gets displayed.
- For the User Name field, enter sangshin (or whatever user name of your choce).
- For the Password field, enter whatever password of your choice.
- Click Submit button.
- Observe that "Successfully Logged In As: <your user name>" message gets displayed at the bottom.
- Click GlassFish v3 Domain tab under Outout window.
- Observe that "INFO: ----afterLogin() method is called, .." message is displayed.
- Observe that "INFO: ----afterAnyLogin() method is called, .." message is displayed.

Figure-8.33
(8.4) Fire qualified event
1. Modify Login.java as shown below. The modification is to fire @Admin qualified event.
| package weldservlet; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.enterprise.inject.Any; import javax.enterprise.inject.Default; import javax.inject.Inject; import javax.inject.Named; /** * A simple Weld Bean that performs a login operation with user's * credentials. */ @Named @SessionScoped @Default public class Login implements Serializable { @Inject Credentials credentials; // Inject LoggedEvent @Inject @Admin Event<LoggedInEvent> loggedInEvent; private boolean loggedIn = false; /** * This is where you could potentially access a database. */ public void login() { if ((credentials.getUsername() != null && credentials.getUsername().trim().length() > 0) && (credentials.getPassword() != null && credentials.getPassword().trim().length() > 0)) { loggedIn = true; // Fire an event when successful login loggedInEvent.fire(new LoggedInEvent(credentials.getUsername())); } } public boolean isLoggedIn() { return loggedIn; } // This methog gets invoked when LoggedInEvent is fired public void afterLogin(@Observes LoggedInEvent event) { System.out.println("----afterLogin() method is called, event = " + event); } // Capture any event (same as above) public void afterAnyLogin(@Observes @Any LoggedInEvent event) { System.out.println("----afterAnyLogin() method is called, event = " + event); } // Capture only @Admin qualified event public void afterAdminLogin(@Observes @Admin LoggedInEvent event) { System.out.println("----afterAdminLogin() method is called, event = " + event); } } |
- Right-click weld-servlet-event-qualifier project and select Run.
- Browser gets displayed.
- For the User Name field, enter sangshin (or whatever user name of your choce).
- For the Password field, enter whatever password of your choice.
- Click Submit button.
- Observe that "Successfully Logged In As: <your user name>" message gets displayed at the bottom.
- Click GlassFish v3 Domain tab under Outout window.
- Observe that "INFO: ----afterAdminLogin() method is called, .." message is also displayed along with the other two. This shows that afterAdminLogin(@Observes @Admin LoggedInEvent event) event handler gets called only when @Admin qualified event is fired.

Figure-8.41
Solution: The solution up to this step is captured as "ready to open and build" NetBeans project as weld-servlet-event-qualifer project under <LAB_UNZIPPED_DIRECTORY>/javaee6_injection/solutions directory.
Summary
In this exercise, you have learned how beans may produce and consume events. You also learned how to use qualifer.
Homework Exercise
- Goal: Exercising qualifier
- Define another qualifier called @SemiFormal.
- Define SemiFormalGreeting class with @SemiFormal annotation
- Modify HelloServlet class to inject @SemiFormal greeting object.
- Goal: Exercising scope
- Create a bean called my_application_scope_bean with application scope, which has a field called my_application_scope_counter. Use the my_application_scope_counter to keep track of how many times the Say Hello button was clicked.
- Display the value of my_application_scope_counter.
- Create another bean called my_conversation_scope_bean with conversation scope, which has a field called my_conversation_scope_counter. Now every time my_application_scope_counter hits multiple of 5, for example, 5, 10, 15, ..., start a conversation. Every time my_application_scope_counter hits multiple of 5 plus 4, for example, 9, 14, 19, ..., stop the conversation.
- The my_conversation_scope_counter gets incremented each time the Say Hello button is clicked but starting from a new random number whenever a new coversation scope gets started.
- Display the value of my_conversation_scope_counter.
- Create a bean called my_application_scope_bean with application scope, which has a field called my_application_scope_counter. Use the my_application_scope_counter to keep track of how many times the Say Hello button was clicked.
- Goal: Exercising event handling
- Every time my_application_scope_bean hits the prime numbers up to 20, fire a event. The event handler should display a message "Prime number x is hit!". This message can be displayed either HTML response message or system log.
| <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <ui:composition template="/template.xhtml"> <ui:define name="title">Simple Greeting</ui:define> <ui:define name="head">Simple Greeting</ui:define> <ui:define name="content"> <h:form id="greetme"> <p><h:outputLabel value="Enter your name: " for="name"/> <h:inputText id="name" value="#{printer.name}"/></p> <p><h:commandButton value="Say Hello" action="#{printer.createSalutation}"/></p> <p><h:commandButton value="Start conversation" action="#{printer.startConversation}"/></p> <p><h:commandButton value="End conversation" action="#{printer.endConversation}"/></p> <p><h:outputText value="printer.salutation = #{printer.salutation}"/> </p> <p><h:outputText value="printer.old_salutation = #{printer.old_salutation}"/> </p> <p><h:outputText value="myConversationStatus.conversationSattus = #{myConversationStatus.conversationSattus}"/> </p> <p><h:outputText value="my_application_scope_bean.my_application_scope_counter = #{my_application_scope_bean.my_application_scope_counter}"/> </p> <p><h:outputText value="my_conversation_scope_bean.my_conversation_scope_counter = #{my_conversation_scope_bean.my_conversation_scope_counter}"/> </p> </h:form> </ui:define> </ui:composition> </html> |
- Zip files of the the my_inject_qualifier and my_inject_scope_conversation NetBeans projects. (Someone else should be able to open and run them as NetBeans projects.) You can use your favorite zip utility or you can use "jar" utility that comes with JDK as following.
- cd <parent directory that contains my_inject_qualifier directory> (assuming you named your project as my_inject_qualifier)
- jar cvf my_inject_qualifier.zip my_inject_qualifier (my_inject_qualifier should contain nbproject directory)
- cd <parent directory that contains my_inject_qualifier directory> (assuming you named your project as my_inject_qualifier)
- Captured output screens - name it as homework_javaee6_injection1.gif orhomework_javaee6_injection1.jpg (or homework_javaee6_injection1.<whatver graphics format>) for the first part and homework_javaee6_injection2.gif orhomework_javaee6_injection2.jpg (or homework_javaee6_injection2.<whatver graphics format>)
- Any screen capture that shows that your program is working is good enough.
'BOOK Study > J2EE' 카테고리의 다른 글
| 06. Java EE 6 - EJB 3.1 (0) | 2010/01/17 |
|---|---|
| 05. Java EE 6 - JPA 2.0 (0) | 2010/01/16 |
| 04. Java EE 6: DI (JSR 330) and CDI (JSR 299) (0) | 2010/01/14 |
| 02. Servlet 3.0 (0) | 2010/01/12 |
| 01. Java EE 6 Overrview & Getting Java EE 6 sample codes (0) | 2010/01/11 |
| [java ee programming] Java EE 6 "1-day" Online Codecamp (on Jan. 12th, 2010) (0) | 2010/01/04 |


homework_javaee6_injection1.zip
Session10-ContextDependencyAndInjection.pdf



Recent comment