|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 5
The AjaxCommand strategy uses a phase listener, which seems to be the most common approach to handling Ajax requests in JSF.
AjaxCommand is the key interface.
Figure 1 shows the classes involved.

All of this is pretty straightforward. What you can't see in the diagram is that the PhaseListener gains its reference to the AjaxCommand instance by pulling a class name out of the request. Setting up the PhaseListener is easy, I'll walk through it in just a moment. In the meantime, Listing 1 shows the phase-listener method that does the
work:
public void beforePhase (PhaseEvent event){
...
if (AjaxRequestUtil.isAjaxCommand(context)){ // 1)
if (log.isTraceEnabled()) { log.trace("Got ajax command..."); }
String ajaxCommandBean = AjaxRequestUtil.getAjaxCommandBeanName(context); // 2)
if (ajaxCommandBean == null){
throw new NullPointerException(
"This was an ajaxCommand request but no ajaxCommandBean name was found under key: " + AjaxCommand.AJAX_COMMAND_BEAN_KEY);
}
ValueBinding vb = context.getApplication().createValueBinding(
"#{"+ajaxCommandBean+"}"); // 3)
AjaxCommand command = (AjaxCommand)vb.getValue(context);
command.handleAjaxRequest(context); // 4)
// Call response complete, we are going to handle the response ourselves
context.responseComplete();
}
The PhaseListener does the following in Listing 1 (note the numbered references in the above code sample):
AjaxCommand request.
AjaxCommand bean name from the request (throwing an exception if not found).
AjaxCommand bean from a value binding.
handleAjaxRequest method (you might check for null first).
I'll break each of these steps out into some detail in the next sections.
The AjaxRequestUtil.isAjaxCommand() is called by the phase listener in Listing 2.
public class AjaxRequestUtil {
...
public static boolean isAjaxCommand(FacesContext context){
HttpServletRequest request =
(HttpServletRequest)context.getExternalContext().getRequest();
Map requestMap = request.getParameterMap();
boolean ajaxKeyIsTrue = false;
if (requestMap.containsKey(AjaxCommand.AJAX_COMMAND_KEY)){
ajaxKeyIsTrue = "true".equals(request
.getParameter(AjaxCommand.AJAX_COMMAND_KEY));
}
return ajaxKeyIsTrue;
}
In Listing 2 you check the request for a parameter under a given key (a constant AjaxCommand.AJAX_COMMAND_KEY that should be something unique, like: public static final String AjaxCommand.AJAX_COMMAND_KEY = "com.companyname.jsf.AJAX_COMMAND";). If that key is present and has the value you want, you return true.
Next, you use AjaxRequestUtil.getAjaxCommandBeanName() to pull the AjaxCommand bean name out of the request. Note that AjaxRequestUtil also uses a straightforward parameter in the request, as shown in Listing 3.
public class AjaxRequestUtil {
...
public static String getAjaxCommandBeanName(FacesContext context){
HttpServletRequest request =
(HttpServletRequest)context.getExternalContext().getRequest();
Map requestMap = request.getParameterMap();
String ajaxCommandId = request.getParameter(AjaxCommand.AJAX_COMMAND_BEAN_KEY);
if (ajaxCommandId == null){
if (log.isWarnEnabled()) {
log.warn("There was NO AjaxCommand bean name found under key: " +
AjaxCommand.AJAX_COMMAND_BEAN_KEY); }
}
return ajaxCommandId;
}
}
In Step 3 you leverage JSF's managed bean facility. With the bean name in hand you do a programmatic lookup, which basically says, "Give me the bean bound under this name."
Here's the declaration of the bean in faces-config.jsf:
<faces-config>
...
<managed-bean>
<description>Command to delete item from Ajax Request</description>
<managed-bean-name>DeleteItemCommand</managed-bean-name>
<managed-bean-class>
ajaxcommand.jsf.ajax.DeleteWithId
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>businessObjectUtil</property-name>
<value>#{idUtil}</value>
</managed-property>
<managed-property>
<property-name>deleter</property-name>
<value>#{DeleteVoAction}</value>
</managed-property>
</managed-bean>
...
<faces-config>
In Listing 4 you find the class under the logical name DeleteItemCommand. The class DeleteWithId implements the AjaxCommand interface. The "WithId" part of the name signifies that what you are deleting will be designated by an "Id", regardless of where the delete is called from. Note that if you needed to use more information than just an ID to identify
the objects, it would be trivial to do that.
Note that you also parameterize DeleteWithId with a couple classes. The first, businessObjectUtil, is a utility class that allows you to look up the object based on Id.
Archived Discussions (Read only)