jsf with webbeans
WebBeans (JSR-299) gives JSF a solid foundation for
its component model, based on WebBeans' typesafe IoC capabilities
and annotation-based discovery. Demo
WebBeans works together with JSF to provide a solid component-basis
for the data model of a JSF application.
With WebBeans, data components can be created by marking them with
a @Component annotation, reducing the amount of configuration XML to
a minimum. In this example, we only need XML to define the FacesServlet,
and a marker web-beans.xml to direct WebBeans to search for
component classes.
The data components automatically populate the JSF EL (expression language),
so they are automatically available to the JSF application.
This example creates a simple calculator which adds two numbers together.
The Calculator model receives the user data and
produces the results. A trivial JSP page creates the JSF UI
component tree.
The data model is the heart of the JSF application. In this case,
a trivial calculator.
The @Component marks example.Calculator as
a WebBeans component. When WebBeans scans the classes, it will discover
Calculator , introspect it, and automatically register the
calculator in the WebBeans directory. Once it's registered, any other
WebBeans component, or JSP/JSF EL, or PHP file or servlet or EJB can
use the component.
The Calculator component has no XML configuration at all,
since there's nothing to configure. For other applications, some of the
component beans will want configuration to set properties, which will
occur in something like the resin-web.xml file.
Calculator.java
package example;
import javax.webbeans.*;
@Component
@RequestScoped
@Named("calc")
public class Calculator {
private int _a;
private int _b;
public int getA() { return _a; }
public void setA(int a) { _a = a; }
public int getB() { return _b; }
public void setB(int b) { _b = b; }
public int getSum()
{
return _a + _b;
}
}
The @RequestScoped annotation tells WebBeans to store
the bean in the servlet request scope. Each request will use its own
instance of the calculator. If the scope was @SessionScoped ,
the same Calculator would be used for the entire session.
If it was @ConversationScoped it would be used for the
JSF page.
The optional @Named annotation gives an alternate name
for the calculator. If there is no @Named , WebBeans will
use the class name, e.g. "calculator" in this case.
WebBeans components can also be injected with other WebBeans, or
DataSources, JPA EntityManager or EntityManagerFactory
or JMS Queues, and they can also use the @PostConstruct
and @PreDestroy lifecycle annotations. Method interception
and event listening are also possible.
JSF/JSP: Building the Component Tree
JSF is designed around a UI component tree model. The JSP code
builds the JSF component tree, hands it back to JSF, and then JSF will
display the component tree based on its current rendering configuration.
- <f:view> is a wrapper tag around all the JSF component tree.
- <h:messages> displays any error messages, like typing a string to
the number fields.
- <h:form> creates a HTML <form>
- <h:inputText> creates a HTML <input> tag, using the
Calculator methods getA() and setA()
to receive the form values.
- <h:outputText> creates a HTML <span> tag, with the text
value generated by the
Calculator getSum() method.
- <h:commandButton> creates a HTML <input type="submit"> tag.
test.jsp
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<f:view>
<h:messages/>
<h:form>
<h:inputText value="#{calc.a}" size="4"/>
+ <h:inputText value="#{calc.b}" size="4"/>
= <h:outputText value="#{calc.sum}" style="color:red"/>
<br>
<h:commandButton value="Add"/>
</h:form>
</f:view>
The JSF expression language expressions #{calc.a} and
#{calc.b} are used in two phases of JSF. When displaying,
JSF will lookup the Calculator with "calc", and call
its getA() method. When processing the form, JSF will
lookup the Calculator and call the setA()
method to assign the new value.
Housekeeping: the resin-web.xml and web-beans.xml
The housekeeping overhead is a minimum when using WebBeans. In this
example we just need two pieces of XML configuration:
- Configuring the JSF servlet in the web.xml
- Marking a classpath root with a web-beans.xml
WebBeans will scan classes directories and jars if they contain
a META-INF/web-beans.xml file, so many applications will
just use web-beans.xml as a marker file with no content.
Others applications will want to configure the WebBeans components using
the web-beans.xml or may put that configuration in the
resin-web.xml .
WEB-INF/resin-web.xml
<web-app xmlns="http://caucho.com/ns/resin">
<servlet-mapping url-pattern="*.jsf"
servlet-class="javax.faces.webapp.FacesServlet"/>
</web-app>
META-INF/web-beans.xml
<web-beans xmlns="http://caucho.com/ns/resin">
<!--
- The web-beans.xml marks a class root for WebBeans to search for
- @Component beans. Since the example doesn't need to override any
- defaults, there's no additional configuration necessary.
-->
</web-beans>
Completing the Application
A more complete application would likely the IoC injection capabilities
of WebBeans. For example:
- Use Java Persistence by injecting a
@In EntityManager
to a model field.
- Injecting a WebBeans singleton service with
@In , defined
by a <bean> configuration in the resin.conf (assuming it needs configuration.
- Using JDBC directly with
@In DataSource or @Named("jdbc/test") DataSource. .
- Using EJB stateless or stateful session beans as services.
Demo
Copyright © 1998-2008 Caucho Technology, Inc. All rights reserved. Resin ® is a registered trademark, and Quercustm, Ambertm, and Hessiantm are trademarks of Caucho Technology. |
|