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
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; @WebServlet(name=”HelloServlet”, urlPatterns={“/HelloServlet”}) // You need an empty beans.xml in the WEB-INF directory to enable Weld // Inject Greeting object /** // <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”> /** /** } |
HelloServlet.java
- Display context senstive Javadoc on @Inject.
Figure-1.21
Figure-1.22
2. Study Greeting.java.
package mypackage;
public class Greeting { |
Greeting.java
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/> |
beans.xml
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
package mypackage;
import java.io.IOException; @WebServlet(name=”HelloServlet”, urlPatterns={“/HelloServlet”}) private Greeting greeting; // Use constructor method injection /** // <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”> /** /** } |
(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
package mypackage;
import java.io.IOException; @WebServlet(name=”HelloServlet”, urlPatterns={“/HelloServlet”}) private Greeting greeting; // Use initializer method injection /** // <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”> /** /** } |
(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
package mypackage;
public interface GreetingInterface { |
2. FormalGreeting.java
package mypackage;
public class FormalGreeting implements GreetingInterface { |
3. HelloServlet.java
package mypackage;
import java.io.IOException; @WebServlet(name=”HelloServlet”, urlPatterns={“/HelloServlet”}) // You need an empty beans.xml in the WEB-INF directory to enable Weld // Inject GreetingInterface object /** // <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”> /** /** } |
(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
package mypackage;
import javax.ejb.Stateless; @Stateless } |
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 { |
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 java.lang.annotation.Retention; @Qualifier |
2. Add @Informal qualifier definition.
package mypackage;
import static java.lang.annotation.ElementType.FIELD; import java.lang.annotation.Retention; @Qualifier |
3. Modify FormalGreeting class to get annotated with @Formal qualifier.
package mypackage;
@Formal |
4. Modify InformalGreeting class to get annotated with @Informal qualifier.
package mypackage;
@Informal |
5. Modify HelloServlet class to inject the Formal qualified type of the GreetingInterface
package mypackage;
import java.io.IOException; @WebServlet(name=”HelloServlet”, urlPatterns={“/HelloServlet”}) // You need an empty beans.xml in the WEB-INF directory to enable Weld // Inject GreetingInterface object using qualifier /** // <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”> /** /** } |
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:composition> |
index.xhtml
2. Printer.java.
import javax.inject.Inject; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @Named public void createSalutation() { public String getSalutation() { public void setName(String name) { public String getName() { |
Printer.java
(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
<?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:composition> |
2. Printer.java
package greetings;
import java.io.Serializable; @Named @Inject public void startConversation() { public void endConversation() { public void createSalutation() { public String getSalutation() { public void setName(String name) { public String getName() { /** /** |
Printer.java
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
package mypackage;
import java.io.IOException; @WebServlet(name = “HelloServlet”, urlPatterns = {“/HelloServlet”}) @Inject @Formal /** // <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”> /** /** |
HelloServlet.java
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; public class FormalGreeting { String formalGreeting; // Produces greeting message based on business logic. |
FormalGreeting.java
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
package mypackage;
import javax.annotation.ManagedBean; @ManagedBean public String greet(String name) { @PostConstruct @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; @ManagedBean public String greet(String name) { @PostConstruct @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
package mypackage;
import javax.annotation.ManagedBean; @ManagedBean public String greet(String name) { @PostConstruct @PreDestroy |
Greeting.java
2. LoggingInterceptor.java
package mypackage;
import java.util.logging.Logger; // This class will be used as an interceptor. private Logger logger = Logger.getLogger(“mypackage”); @AroundInvoke |
LoggingInterceptor.java
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
<?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> <welcome-file-list> |
web.xml
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> </form> |
index.jsp
3. LoginServlet.java
package weldservlet;
import java.io.IOException; /** // BeanManager interface allows a portable extension to interact directly with // Inject The Credentials Weld bean. // Inject the Login Weld bean. /** // Because credentials variable is injected with Credentials object by the container, // Because login variable is injected with Login object by the container, try { /** /** /** } |
LoginServlet.java
4. Credentials.java.
package weldservlet;
import java.io.Serializable; import javax.enterprise.context.RequestScoped; /** private String username = null; private String password = null; public String getUsername() { public void setUsername(String username) { public String getPassword() { public void setPassword(String password) { } |
Credentials.java
5. Login.java.
package weldservlet;
import java.io.Serializable; import javax.enterprise.context.SessionScoped; /** // Credential object is already initialized with private boolean loggedIn = false; /** public boolean isLoggedIn() { } |
Login.java
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> |
index.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> <h:body> <div style=”color: black; font-size: 24px;”> <h:panelGrid border=”1″ columns=”5″ style=”font-size: 18px;”> <div style=”color: red; font-size: 14px;”> <h:outputStylesheet name=”stylesheet.css” /> </html> |
3. Game.java.
package weldguess;
import java.io.Serializable; import javax.annotation.PostConstruct; @Named private int number; private int guess; // Inject an object which is qualified with private int biggest; // Inject an object which is qualified with public Game() public int getNumber() public int getGuess() public void setGuess(int guess) public int getSmallest() public int getBiggest() public int getRemainingGuesses() public String check() throws InterruptedException @PostConstruct public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) if (input < smallest || input > biggest) FacesMessage message = new FacesMessage(“Invalid guess”); |
Game.java
4. Generator.java.
package weldguess;
import java.io.Serializable; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped 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() @Produces @Random @Produces @MaxNumber int getMaxNumber() } |
Generator.java
5. MaxNumber.java.
package weldguess;
import static java.lang.annotation.ElementType.FIELD; import java.lang.annotation.Documented; import javax.inject.Qualifier; // Define @MaxNumber qualifier annotation } |
MaxNumber.java
6. Random.java.
package weldguess;
import static java.lang.annotation.ElementType.FIELD; import java.lang.annotation.Documented; import javax.inject.Qualifier; // Define @Random qualifier annotation } |
Random.java
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; /** @Inject // Inject LoggedEvent private boolean loggedIn = false; /** // Fire an event when successful login public boolean isLoggedIn() { // This methog gets invoked when LoggedInEvent is fired |
Login.java
2. LoggedInEvent.java
package weldservlet;
public class LoggedInEvent { public LoggedInEvent(String user) { |
LoggedInEvent.java
(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 java.lang.annotation.Documented; import javax.inject.Qualifier; @Target( { TYPE, METHOD, PARAMETER, FIELD }) } |
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; /** @Inject // Inject LoggedEvent /** // Fire an event when successful login public boolean isLoggedIn() { // This methog gets invoked when LoggedInEvent is fired // Capture any event (same as above) // Capture only @Admin qualified event |
Login.java
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.
4. Observe that the two event handlers are invoked.
- 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; /** @Inject // Inject LoggedEvent private boolean loggedIn = false; /** // Fire an event when successful login public boolean isLoggedIn() { // This methog gets invoked when LoggedInEvent is fired // Capture any event (same as above) // Capture only @Admin qualified event |
Login.java
- 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.
3. Observe that the two event handlers are invoked.
- 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.
2. The second part of homework is to modify inject_scope_conversation project you worked on in Exercise 3 above as following. (You might want to create a new project by copying inject_scope_conversation project. You can name the newly copied project in any way you want. Here it is referred to as my_inject_scope_conversation.) – If you already submitted homework or would use to use a single project as a base as in the original homework, that is perfectly fine as well.
- 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.
- 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.
Hint: Given that we have not covered how to use JSF/Facelets yet, the following hint shows how to display things in the index.xhtml file – make sure you copy resources directory and template.xhtml as well as seen in inject_scope_conversation project. The “Prime number x is hit!” can be printed out on system log through sysem.out.println(…);
<?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:composition> |
- 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)
- 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.