JBoss Seam: Contextual

seedjaggedInternet and Web Development

Nov 12, 2013 (3 years and 11 months ago)

89 views

JBoss Seam: Contextual
Components

Jason Bechtel

bechtel2@cse.buffalo.edu

Overview


What is Seam?


How does it work?


Example Code and what it does


Demo


How it works


Questions

What is JBoss Seam?


An application framework for Java EE 5


A unifier for EJB 3.0 and JSF


Integrates the server layer with the
presentation layer


Declarative State Management


What is JBoss Seam?



Seam works in any application server that supports EJB 3.0



Use Seam as a framework for applications using



JSF (Presentation)



Hibernate (or plain JDBC) (Persistence)



JavaBeans (Business Logic)



Etc.

How does it work?



2 JSP pages



An Entity Bean




A Stateless Session Bean



EJB Entity management




Uses EJB Session Beans as
JSF Action Listeners (no
“glue code”)



No JNDI context lookup



Seam does it all!

@Entity (1)

@Name("user") (2)

@Scope(SESSION) (3)

@Table(name="users") (4)

public class User implements Serializable {


private static final long serialVersionUID = 1881413500711441951L;



private String username; (5)


private String password;


private String name;



public User(String name, String password, String username) {



this.name = name;



this.password = password;



this.username = username;


}




User.java (Entity Bean)

(1)The EJB3 standard @Entity annotation indicates that the User
class is an entity bean.

(2)A Seam component needs a
component name

specified by the
@Name

annotation. This name must be unique within the
Seam application. When JSF asks Seam to resolve a context
variable with a name that is the same as a Seam component
name, and the context variable is currently undefined (null),
Seam will instantiate that component, and bind the new
instance to the context variable. In this case, Seam will
instantiate a User the first time JSF encounters a variable
named user.

(3)Whenever Seam instantiates a component, it binds the new
instance to a context variable in the component's
default
context
. The default context is specified using the
@Scope

annotation. The User bean is a session scoped component.


(4)The EJB standard @Table annotation indicates that the User class
is mapped to the users table.

(5)name, password and username are the persistent attributes of the
entity bean. All of our persistent attributes define accessor
methods. These are needed when this component is used by JSF
in the render response and update model values phases.



public User() {} (6)




@NotNull


@Length(min=5, max=15)





(7)


public String getPassword() { return password; }



public void setPassword(String password) { this.password = password; }



@NotNull


public String getName() { return name; }




public void setName(String name) { this.name = name;}



@Id


@NotNull


@Length(min=5, max=15) (8)


public String getUsername() { return username; }



public void setUsername(String username) { this.username = username; }

}

User.java Con’t

(6)An empty constructor is both required by both the EJB specification
and by Seam.

(7)The @NotNull and @Length annotations are part of the
Hibernate Validator framework. Seam integrates Hibernate
Validator and lets you use it for data validation (even if you
are not using Hibernate for persistence).


(8)The EJB standard @Id annotation indicates the primary key
attribute of the entity bean.


@Stateless







(1)

@Name("register")

@Interceptors(SeamInterceptor.class)




(2)


public class RegisterAction implements Register {


@In









(3)


@Valid







(4)


private User user;



@PersistenceContext






(5)


private EntityManager em;



@In private


FacesContext facesContext;





(6)




@IfInvalid(outcome=Outcome.REDISPLAY)



(7)


public String register() {






(8)



List existing = em.createQuery("select username …..

RegistrationAction.java (Session Bean)

(1)The EJB standard @Stateless annotation.

(2)The SeamInterceptor EJB interceptor must be enabled for all
session beans which are Seam components.

(3)The
@In

annotation marks an attribute of the bean as injected
by Seam. In this case, the attribute is injected from a context
variable named user (the instance variable name).


(4)The @Valid annotation is provided by Hibernate Validator.

(5)The EJB standard @PersistenceContext annotation.

(6)Seam also allows various JSF, Seam and jBPM context objects
to be injected. To get the current FacesContext instance
injected to a Seam component, just mark an instance variable
named facesContext with the @In annotation.

(7)The
@IfInvalid

annotation tells Seam to validate the component
state using Hibernate Validator before invoking the action
listener method, and return a different JSF outcome if the state
is invalid. In this example, the user is validated when the
register() method is invoked, and the form is redisplayed with
messages if a validation failure occurs.

(8)The action listener method uses the standard EJB3 EntityManager
API to interact with the database, and returns the JSF outcome.
Note that, since this is a sesson bean, a transaction is automatically
begun when the register() method is called, and committed when it
completes.


faces
-
config.xml

<?xml version="1.0" encoding="UTF
-
8"?>

<!DOCTYPE faces
-
config

PUBLIC "
-
//Sun Microsystems, Inc.//DTD JavaServer Faces Config
1.0//EN" "http://java.sun.com/dtd/web
-
facesconfig_1_0.dtd">

<faces
-
config>


<navigation
-
rule>



<navigation
-
case>




<from
-
outcome>success</from
-
outcome>




<to
-
view
-
id>/registered.jsp</to
-
view
-
id>


</navigation
-
case>


</navigation
-
rule>


<!
--

A phase listener is needed by all Seam applications
--
>


<lifecycle>



<phase
-
listener>org.jboss.seam.jsf.SeamPhaseListener



</phase
-
listener>


</lifecycle>


</faces
-
config>

View pages using JSP with JSF

<%@ taglib uri="http://java.sun.com/jsf/html"

prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core"

prefix="f" %>

<html>


<head>


<title>


Register New User


</title>


</head>


<body>


<f:view>


<h:form>


<table border="0">


<tr>


<td>Username</td>


<td><h:inputText value="#{user.username}"/></td>


</tr>


<tr>


<td>Real Name</td>


<td><h:inputText value="#{user.name}"/></td>


</tr>


<tr>


<td>Password</td>


<td><h:inputSecret value="#{user.password}"/></td>


</tr>


</table>


<h:messages/>


<h:commandButton type="submit" value="Register"

action="#{register.register}"/>


</h:form>


</f:view>


</body>

</html>


<%@ taglib uri="http://java.sun.com/jsf/html"


prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core"


prefix="f" %>

<html>


<head>


<title>


Successfully Registered New User


</title>


</head>


<body>


<f:view>


Welcome,


<h:outputText value="#{user.name}"/>


, you are successfully registered as



<h:outputText value="#{user.username}"/>


</f:view>


</body>

</html>


<application>


<display
-
name>Seam</display
-
name>


<module>


<web>


<web
-
uri>jboss
-
seam
-
registration.war</web
-
uri>


<context
-
root>/seam
-
registration</context
-
root>


</web>


</module>


<module>


<ejb>jboss
-
seam
-
registration.jar</ejb>


</module>


</application>



This deployment descriptor links modules in the
enterprise archive and binds the web application
to the context root /seam
-
registration.


We've now seen
most

of the files in the
application!

application.xml

Demo

How it works


When the form is submitted, JSF asks Seam to resolve the
variable named user. Since there is no value already bound to
that name (in any Seam context), Seam instantiates the user
component, and returns the resulting User entity bean instance to
JSF after storing it in the Seam session context. JSF binds the
form input values to properties of the User entity bean.


Next, JSF asks Seam to resolve the variable named register.
Seam finds the RegisterAction stateless session bean in the
stateless context and returns it. JSF invokes the register() action
listener method.


Seam intercepts the method call, injects the User entity from the
session context, and the current FacesContext instance, before
asking Hibernate Validator to validate the session bean instance
(and, recursively, the User entity bean instance). If the state is
valid, the invocation proceeds and the register() method is called.
If not, Seam returns a null outcome and JSF redisplays the page.


When JSF comes to render the next JSP page, it asks Seam to
resolve the variable named user and uses property values of the
returned User entity from Seam's session scope.

References


http://labs.jboss.com/portal/index.html?ctrl:id=page.default.
info&project=jbossseam


http://labs.jboss.com/portal/jbossseam/gettingstarted


http://docs.jboss.com/seam/reference/en/html/index.html


Questions?