JS JSF is great for building pages by associating components and events, but, like all existing technologies, it requires a controller to isolate navigation decisions between pages and provide links to the business layer. It has a basic navigation handler that can be replaced with a full-featured handler. Page flow provides the basis for creating reusable encapsulated page flows and works in parallel with the view layer. It is a full-featured navigation handler that takes the JSF page as the top priority. This article will discuss how to integrate the two technologies to take advantage of both.
Building BEEHIVE/JSF Applications
To build an BEEHIVE/JSF application, start page flow first, and then add support for JSF. The starting point is the project that starts with the basic support Netui (the component that contains page flow in beehive). Build basic support for Netui Web applications based on guidance. In this article, we call it "jsf-beehive", which can be obtained on http://localhost:8080/jsf-beehive.
Next, install and configure JSF. Page flow can use any implementation that is compatible with JavaServer Faces 1.1 and is tested for two major implementations: Apache Myfaces and JSF Reference implementation. Follow the instructions below to install Jsf:myfaces v1.0.9 and later in a new Web application, JSF Reference implementation v1.1_01, or other implementations. After that, you can use a simple entry in Web-inf/faces-config.xml to start page flow integration, with the entry below the <application> label,<navigation-rule> label:
<factory> <application-factory> Org.apache.beehive.netui.pageflow.faces.PageFlowApplicationFactory </application-factory></factory>
Adding these provides an opportunity for page flow to provide its own version of the JSF framework object to customize its behavior. Typically, the JSF behavior is modified only when the page flow feature is used, and the basic behavior of JSF does not change.
Basic integration
The most basic use of page flow in JSF is to raise (invoke) an action from a JSF page. JSF pages can handle events within a page, and page flow is the way to navigate from one page to another. First, create a directory named "Example" in your Web application, where you create a page flow controller class:
Package Example;import Org.apache.beehive.netui.pageflow.forward;import Org.apache.beehive.netui.pageflow.pageflowcontroller;import org.apache.beehive.netui.pageflow.annotations.jpf;@ Jpf.controller ( simpleactions={ @Jpf. Simpleaction (name= "Begin", path= "Page1.faces") }) public class Examplecontroller extends pageflowcontroller{ @Jpf. Action ( forwards={ @Jpf. Forward (name= "Success", Path= "Page2.faces") } ) public Forward GoPage2 () { Forward fwd = new Forward ("Success"); return FWD }}
There are two actions in this page stream: Jump to Page1.faces's begin action and jump to Page2.faces's goPage2 action. The reason for GoPage2 as a method action (rather than a simple action) is that it will be expanded later.
When you construct a page, you should create a Page1 and PAGE2;JSF servlet for the extension with a. JSP to process each. faces request and eventually jump to the relevant JSP. So, jump to Page1.faces will eventually show page1.jsp, as follows:
<%@ taglib prefix= "F" uri= "Http://java.sun.com/jsf/core"%><%@ taglib prefix= "h" uri= "http://java.sun.com/" Jsf/html "%>
Raising an action from a JSF page is simple: Use the action name in the action attribute of the command component. In the example above, the CommandLink points to the GoPage2 action. Use page flow integration, which means that the GoPage2 action will run in Example.examplecontroller.
That's it. To experiment, build the application and click Http://localhost:8080/jsf-beehive/example/ExampleController.jpf, which will jump to page1.faces through the begin action. Clicking the link "go to page 2" triggers the GoPage2 action and jumps to page2.faces.
Background bean
The page flow framework can manage the background bean (backing bean) associated with the JSF page. This class is a convenient place to place the event handlers and states associated with the page. Think of it as a single place to centralize all the code that runs when interacting with a page. When you click on a JSF page, page flow determines whether there are classes with the same name and package, such as the Page/example/page1.faces Example.page1 class. If there is such a class, and it is annotated with @jpf.facesbacking and extends Facesbackingbean, it creates an instance of the class. When you leave the JSF page and go to an action or any other page, the background bean is destroyed. The background bean survives the JSF page.
Properties bound to the background bean
The following is a very simple background bean for page1.faces, as well as a property someproperty. File name is Page1.java:
Package Example;import Org.apache.beehive.netui.pageflow.facesbackingbean;import ORG.APACHE.BEEHIVE.NETUI.PAGEFLOW.ANNOTATIONS.JPF @Jpf. Facesbackingpublic class Page1 extends facesbackingbean{ private String _someproperty = "This is a property value from" + getclass (). GetName () + "."; Public String Getsomeproperty () {return _someproperty; } public void Setsomeproperty (String someproperty) { _someproperty = Someproperty; }}
In the JSF page (page1.jsp), you can bind to this property by using the backing binding context:
The above example shows the value of Someproperty (eventually the background bean is raised with Getsomeproperty ()). Similarly, set this value:
Note that in this example, the event handler or component reference does not appear in the background bean. This shortens the code; the background bean is a good place to place all of the handler and component references for the page.
To raise a page flow from a background bean
In the "Basic integration" section above, we directly raise page flow from JSF components. Usually, this is all you need to do, and when you click a button or link, you run an action and jump to another page. If you want to run some page-related code before calling the controller, or if you want the page to dynamically select between several actions, you can raise an action in the command handler (a Java method that the JSF page runs). The following is an example of a command handler that can be placed in the background bean Page2.java (or any other publicly accessible bean):
Public Stringchoosenextpage () {return "GoPage3";}
This is a very simple command handler, which selects the GoPage3 action. You can bind to this command handler from a JSF command component in standard JSF mode:
When you click the link, the choosenextpage command handler is run, and it chooses to raise the GoPage3 action. You can also use a special page flow comment on the command handler method-@Jpf. CommandHandler:
@Jpf. CommandHandler (raiseactions={ @Jpf. Raiseaction (action= "GoPage3")}) public String choosenextpage () {return "GoPage3";}
This annotation enables tools that support beehive to know which action the command handler raised in the background bean and to allow the ability to extend JSF action processing (see the "Send data from JSF page to page Flow" section below).
Accessing the current page stream or shared stream from the background bean
In some cases, you may want to access the current page stream or an active shared stream directly from the background bean. To do this, simply create a field of the appropriate type and annotate it appropriately with @jpf.pageflowfield or @jpf.sharedflowfield:
@Jpf. CommandHandler (raiseactions={ @Jpf. Raiseaction (action= "GoPage3")}) public String choosenextpage () {return "GoPage3";}
These fields will be initialized when the background bean is created. It does not need to be initialized manually. The following example uses the Examplecontroller field that is initialized automatically. In this example, the "Show Hints" radio buttons event handler sets a normal priority in the page flow.
@Jpf. pageflowfieldprivate examplecontroller mycontroller @Jpf. Sharedflowfield (name= "SharedFlow2")//"SharedFlow2" is a //name defined in the //page flow controllerprivate examplesharedflow Mysharedflow;
In many cases, pages do not need to interact directly with page or shared streams, and it is sufficient to use other methods to pass data from a page to a JSF page, and vice versa. I'll give you some examples below.
Accessing the background bean from the page flow controller
You cannot access the background bean! from the page flow controller At least, it's not easy, it's intentional. Background beans are closely related to JSF pages, and when you leave the page, the background bean is destroyed. Just as the page flow controller should not understand page details, it should not understand background beans. Of course, you can pass the data to the controller from the background bean (which will be introduced later), and you can even pass the background bean instance itself, but in most cases the contents of the background bean should not be leaked to the controller.
Life cycle Approach
Typically, when something happens in a background bean, such as when it is created or destroyed, we want to be able to run the code. In the life cycle of the page flow framework, it calls some methods on the background bean:
- onCreate (): When creating a bean
- OnDestroy (): When the bean is destroyed (removed from the user session)
- Onrestore (): This needs to be explained in detail. As I said, when you leave the page, the background bean is destroyed. This is true in most cases, but if the page stream uses the NavigateTo attribute (which allows you to access the previously displayed page again), the page flow framework retains the background bean for a short period of time after you leave it, in case it needs to be restored. When using Navigateto=jpf.navigateto.currentpage or navigateto= via @jpf.forward or @jpf.simpleaction When Jpf.NavigateTo.previousPage restores a JSF page, the page's component tree and its background bean are restored by the page flow framework. When this happens, Onrestore () is invoked.
Regardless of the period of time you want to run your code, simply rewrite the appropriate method:
protected void OnCreate () {/*some create-time logic * *}
When you override these methods, you do not need to invoke the empty super version.
Passing data between JSF pages and page flows
Now we should see how to pass data between the JSF page and the page stream.
Send data from a page to a JSF page
Typically, you want to use the data from the page stream to initialize a page. To do this, you can add "action outputs" to the page2.faces forward:
@Jpf. Action (forwards={ @Jpf. Forward ( name= "Success", path= "Page2.faces", actionoutputs={ @ Jpf.actionoutput (name= "message", Type=string.class,required=true) }) -public Forward goPage2 () { Forward fwd = new Forward ("Success"); Fwd.addactionoutput ("message", "Got"); return FWD;}
Once you have done this, you can access the value directly from the JSF page or from the background bean as a page entry. (If you don't like to type verbose annotations, you can omit italic.) They are primarily used to check again for the correct type of object being added, and to determine the type is not missing. )
You can bind to this value in the page by using the page Flow pageinput binding context in the JSF presentation language:
Note that you can use the Pageflow and sharedflow binding contexts to bind to the page flow controller itself or to any of the available shared stream properties:
Finally, to access page input from a background bean, you simply invoke Getpageinput in any place in the Bean Class Code:
String message = (string) getpageinput (' message ');
Send data to a page stream from a JSF page
You can also send data as the page stream triggers the action. Many actions will require the form bean as input; Typically, the form bean is used to get data from the page to the controller. First, let's build an action to receive the form bean and jump to the page:
@Jpf. Action ( forwards={ @Jpf. Forward (name= "Success", path= "Page3.faces") }) public Forward GoPage3 ( Namebean Namebean) { _username = namebean.getfirstname () + ' + namebean.getlastname (); return new Forward ("Success");}
The action contains a namebean, which is a form bean class that will getters/setters as its FirstName and LastName properties. It sets a member variable to save the full name, and then jumps to page3.faces. We know that you can raise an action directly from the JSF page or its background bean. In either case, the form bean can be sent to the action. Let's look at each of these in turn.
To send a form bean from a background bean
To send form beans from a command handler in a background bean, you need to use a specific comment. The following is given in Page2.java:
Private Examplecontroller.namebean _namebean;protected void OnCreate () { _namebean = new Examplecontroller.namebean ();} Public Examplecontroller.namebean GetName () {return _namebean;} @Jpf. CommandHandler ( raiseactions={ @Jpf. Raiseaction (action= "GoPage3", outputformbean= "_namebean") }) Public String Choosenextpage () {return "GoPage3";}
In this example, the JSF page can populate _namebean values in any way it chooses (for example, by binding h:inputtext values to #{backing.name.firstname} and #{backing.name.lastname}). It then uses the Outputformbean attribute on the @jpf.raiseaction to mark that _namebean should be passed to the action GoPage3.
Send form bean from JSF page
Sending a form bean directly from a JSF page is easy, as long as you can get the bean value through a data-binding expression. This is accomplished by adding a H:attribute component named Submitformbean within the CommandButton component:
Here, in order for the form bean to be sent to the action GoPage3, the button is bound to the background Bean's "name" Property (GetName).
Conclusion
This article shows you how to combine JSF's rich features in building pages with the Beehive page flow's powerful ability to navigate between pages of control. The integration of the two is very easy, but it can have a profound impact on the application: it separates the JSF page from the application-level logic and brings the page into the functional area provided by page flow. The JSF page has a clear task: to participate in the flow of the application as a single (if sufficient) view element. The article does not show the full application of the JSF page with event-handling capabilities and complex navigation logic in the controller. But as the complexity of the application increases, it will require a division of responsibilities and the advanced streaming capabilities that page flow adds to JSF. You can take a few minutes to try--and soon you'll be aware of the benefits of doing so.