Java Enterprise Edition 5 is here. It’s new, it’s sparkling and it contains many new features. The two main ones are EJB 3.0 and JSF. In itself these are very nice aspects of JEE5, but it may be hard to glue these two technologies together. This is where Seam jumps in. Instead of letting developers work on integration and implementing common problems, it enables them to focus on the important areas: the actual business issues.
Previous EJB specifications are infamous for the complexity and the intrusive nature. EJB 3.0 evolved this into being a fine-grained component model. Basically, an EJB nowadays is nothing more than a plain old java object (POJO) with annotations. This makes it possible to create lightweight components containing session and entity beans. Seam even encourages the use of session beans as action listeners and entity as backing beans for JSF components. At first I was worried that this was the only way to make things work with Seam, but luckily Seam does not enforce this. It is easily possible to create extra architectural layers to abstract your domain layer from the presentation layer. It is you who makes the decision, not Seam.
Conversations and workspaces
Seam introduces the concept of conversations, not present in JEE. A conversation surpasses the request-response model a conversation may span several requests.
For example, one of Seam’s example applications is a hotel booking system. Within this context, everything from selecting a hotel to confirming the actual booking is wrapped in a so-called conversation. A conversation can be started via a simple @Begin annotation in the action listener method and is ended by marking an action with @End. An alternative in plain JEE would be to store items on the HttpSession. This could work, but it is hard to limit the amount of data stored on the session.
Seam also makes it possible to run several conversations at a time, because of the notion of workspace management. Data associated with different conversations will be isolated.
Login example
Seam makes it possible to make use of an annotation, @LoggedIn, to make sure users can only enter an action listener if the person has actually successfully logged in to the application. The small example code below is taken from the Hotel example and shows how easy it is to register a user being logged in. The code contains a number of annotations:
• @Stateless
Denotes this class is a stateless session bean.
• @Name
The LoginAction is called a Seam component. This annotation marks the name of this component. This name must be unique within the application and is used to bind JSF and this Seam component.
• @In and @Out
Seam supports the notion of bijection. Seam injects the attribute via the @In annotation. This field is being outjected, that is, being stored in the Seam context after successful login.
• @PersistenceContext
Part of EJB 3.0 and used to inject the entity manager.
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.FacesMessages;
@Stateless
@Name("login")
public class LoginAction implements Login
{
@In @Out
private User user;
@PersistenceContext
private EntityManager em;
public String login()
{
List<User> results = em.createQuery("select u from User u where u.username=:username and u.password=:password")
.setParameter("username", user.getUsername())
.setParameter("password", user.getPassword())
.getResultList();
if ( results.size()==0 )
{
FacesMessages.instance().add("Invalid login");
return "login";
}
else
{
user = results.get(0);
Contexts.getSessionContext().set("loggedIn", true);
FacesMessages.instance().add("Welcome, #{user.name}");
return "main";
}
}
}
After the user is authenticated, the user is outjected to the Seam context. Marking other Seam components with the @LoggedIn annotation makes it only possible to enter the component after a successful login. The user object can be used after injection by the @In annotation.
Seam wrap-up
JBoss understands not everyone is yet ready to make use of EJB 3.0. Therefore it is also possible to use Seam in combination with a servlet container like Tomcat and the JBoss Embeddable EJB3 container. If you cannot make the switch to EJB 3.0 it is also possible to use Seam in combination with JSF and Hibernate or straight JDBC.
Conclusion
Seam makes it easy to integrate EJB 3.0 and JSF. It helps you to focus on the key points of your application. This saves development time and prevents having to create proprietary in-house solutions for common things.
This article only discussed a tip of the Seam iceberg. Seam covers a lot more, like integration with jBPM (workflow and task management), support for unit and integration testing of Seam components and interceptor classes. Furthermore, Gavin King (JBoss, creator of Hibernate and Seam) is the spec lead for JSR 299: Web Beans. The goal of this specification is to standardize functionality offered by Seam. The final draft is to be expected in early 2008. Below are excellent resources for further reading.
Sander Nieuwenhuizen
J2EE consultant
e-mail:
This email address is being protected from spam bots, you need Javascript enabled to view it
References
http://labs.jboss.com/portal/jbossseam/?prjlist=false
http://www.onjava.com/pub/a/onjava/2006/03/15/jboss-seam.html
http://jcp.org/en/jsr/detail?id=299
|