Who knows if these stats mean anything, but it does make a pretty graph. Current mailing list traffic leaders in the web framework space: Rails, Flex and GWT. For those frameworks with dev and users lists, these stats are from the users lists. If you find these numbers to be inaccurate, please let me know.
Here's the numbers in case you want to create your own graphs:
- Rails: 4056
- Flex: 3558
- GWT: 2305
- Django: 1951
- Wicket: 1718
- Struts: 1689
- Grails: 1307
- MyFaces: 1283
- Tapestry: 1268
- TurbyGears: 797
- Stripes: 206
- OpenLaszlo: 189
What if you didn't have to choose between a request-based framework and a component-based framework? What if you could use them together and use request-based for some pages and component-based for others? This is the functionality that the Struts 2 JSF Plugin provides.
To be fair, the JSF-Spring project says it does the same thing for Spring MVC + JSF, but there doesn't appear to be any documentation.
I did some prototyping of Struts 2 + JSF and discovered that it does indeed work. I also discovered that there's no documentation on integrating it with Facelets. Luckily, it's pretty easy to do - hence my reason for writing this entry. You might ask why I want to use Facelets when JSF 1.2 supports JSP fairly well? My reason is because JSP 2.1 hijacks #{}, which Struts 2's OGNL uses for some expressions. Because of this, I want to be able to run on a JSP 2.0 container until a workaround comes along. Sun's JSF 1.2 RI can run on a JSP 2.0 container, while MyFaces 2.1 cannot (at least in my experience).
There's two ways to get Struts 2 + JSF + Facelets working:
- Create a WEB-INF/faces-config.xml file and override the default view-handler:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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-facesconfig_1_2.xsd"
version="1.2">
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>
- The 2nd way is to use Ajax4JSF and declare the view-handler in your web.xml (allowing you to get rid of faces-config.xml):
<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>com.sun.facelets.FaceletViewHandler</param-value>
</context-param>
NOTE: You have to use 2nd method if you want to use Ajax4JSF. It won't read the view-handler from faces-config.xml.
If you're using SiteMesh, you may have to add another <parser> element to your sitemesh.xml to get Facelets pages decorated:
<parser content-type="application/xhtml+xml"
class="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>
Thanks to Laurie Harper for his assistance figuring this stuff out.
Now you might ask - why would you want to do this? For one, Struts 2 has a better navigation model (IMO) than JSF. Also, if developers want to use JSF and think it's a better way for a certain module - let them go to it!