The JavaEE team at Oracle has been busy processing the feedback from the JavaEE 8 Community Survey
Question 6 in part one of the survey reads: "Is there any one de-facto standard technology in this space [Server side web MVC framework, aside from JSF] to which we should look for inspiration". For those respondents that answered yes to that question, fully half of them cited Spring MVC. By way of background, it's possible to classify server side web frameworks as "action based" or "component based". For some background on these terms, please see http://javaserverfaces.java.net/presentations/demystifyingjsf.odp.
To explore the possibilities for adding "action based" to the UI standard for JavaEE, we have committed some experimental prototype work to snapshot builds of Mojarra on January 9th, 2014. The current prototype allows you to use a simple annotation which would result in a call to a method on your managed bean and then dispatch the response to a regular view.
To try out the code in this blog entry, grab the latest 2.2.6-SNAPSHOT build of Mojarra from the maven.java.net snapshot repository and drop it into the GlassFish 4.0 modules directory.
You will also need to add the following dependency in the POM of your web application.
<dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.2.6-SNAPSHOT</version> <scope>provided </dependency>
import com.sun.faces.action.RequestMapping; import javax.enterprise.context.RequestScoped; import java.io.Serializable; import javax.faces.context.FacesContext; import javax.inject.Named; @Named("myBean") @RequestScoped public class MyBean implements Serializable { private String value; @RequestMapping(value = "/form1b.xhtml") public String form1() { String inputText1 = (String) FacesContext.getCurrentInstance(). getExternalContext().getRequestParameterMap().get("inputText1"); setValue("We set inputText1 manually to - " + inputText1); return "/form1b.xhtml"; } public void setValue(String value) { this.value = value; } public String getValue() { return this.value; } }
Note the request mapping here is an exact mapping, but you can also do an extension mapping (using *.xx) or a prefix mapping do (using prefix/*).
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Facelet HTML page</title> <head> <body> <form action="#{request.contextPath}/action/form1b.xhtml"> <input id="inputText1" value="#{myBean.value}"/> <input id="submit" type="submit" value="Submit"/> </form> </body> </html>
<?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:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <form action="#{request.contextPath}/action/form1b.xhtml"> <h:inputText id="inputText1" value="#{myBean.value}"/> <input id="submit" type="submit" value="Submit"/> </form> </h:body> </html>
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Result page</title> </head> <body> We did a POST to an action based URL and the result is: #{myBean.value} </body> </html>
<?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:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Result page</title> </h:head> <h:body> We did a POST to an action based URL and the result is: <h:outputText value="#{myBean.value}"/> </h:body> </html>
<servlet> <servlet-name>Faces Action Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <init-param> <param-name>javax.faces.LIFECYCLE_ID</param-name> <param-value>com.sun.faces.action.ActionLifecycle</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Action Servlet</servlet-name> <url-pattern>/action/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping>
While not necessary we opted to include the regular mapping to the FacesServlet to demonstrate that the "action based" approach can coexist in a JSF web application.
Note as this code is in SNAPSHOT mode it means we might need to do some code adjustments, so consider these code samples as examples of what we might or might not be working towards.
Posted January 13, 2014