Choosing between action and actionListener
Every request done by the user can be understood as an action. This action may have several behaviors in the system: update a database record, save a file to the hard disc, page navigation, display some information, etc.
JSF classify these actions in two ways: “action with navigation” and “action without navigation”. Actions with navigation are those user requests that will finish in other page, like create a city in the database or system login/logout. The actions without navigation usually are the Ajax request or to configure any object in memory before some other event.
A developer must have in mind that an action that creates navigation will not always display other page to the user; if the user is in a page to create new items in the database and a required field is empty, the action can be fired but the user will stay in the same page and an error message will be displayed.
Inside the components “h:commandLink” and “h:commandButton”, the most used components to create an action, it is possible to see the parameters “action” and “actionListener”. We can say that the “action” parameter will result in actions that result in page navigations and the actionListener is used for Ajax request or actions that will modify/prepare any object in memory.
The correct utilization of the “action” parameter is to use it with a ManagedBean method that returns a String. The signature “public String create()” is a valid signature of an “action”. The returned String indicates to the JSF the end destination of the user request. After returning the String the JSF will take the following steps:
- If the returned value is null, the user will stay in the same page
- If the returned value has an invalid extension, the current view extension will be used. E.g. if the user is in the create.xhtml and the invoked method returns “indexPage” the JSF will handle it as “indexPage.xhtml”
- If the returned value does not start with “/” the JSF will handle it as “/indexPage.xhtml”
- The JSF will also check the faces-config.xml file for some navigation rules.
- Any non-null returned value will erase the current view and its values. Imagine that the user is in the page “create.xhtml”, if the action method returns null the user will stay in the same page with all the current values without starting a new navigation; if the return is “create.xhtml” a new navigation to the page will be started.
The actionListener requires a different signature. A valid actionListener signature would be: “public void checkUser(javax.faces.event.ActionEventevent)”.
It is possible to have both methods in the same button: “<h:commandButton action= “userMB.createUser” actionListener= “userMB.checkUser” />”. The button click will fire a method to check the User object in memory and later the action to create the user.
An “actionListener” action is heavily used by view components. In a pagination component it would be used an actionListener method to change the displayed pages without firing a navigation. Unfortunately some developers do not use this resource as it should be used and they will find problems that should not happen. To do navigation from an “actionListener” method it would be required to use the method sendRedirect of the HttpServletResponse; a developer must use an “action” method to do navigation without a problem.
It is a good practice to use the “action” behavior in the JSF codes if the request is not coming from a component or from an Ajax request.