Read also:
Now that you
are familiar with the template method design pattern, let's try to identify a
use case of it in the JSF implementation. In order to accomplish this, we have
to focus on the JSF phases.
As you
probably know, JSF lifecycle contains six phases (Restore View, Apply Request
Values, Process Validation, Update Model Values, Invoke Application and Render
Response). Basically, these phases are executed in a preset order even if not
all six are always executed. For example, at initial request (GET), JSF executes
only the Restore View and Render Response phase, while at postbacks (POST), JSF
executed all six phases in the same order as they are listed above. Beside the
preset order, each phase (step) contains a predefined behavior. With other
words, at each phase, JSF will accomplish a set of tasks that are fix and are
specific to that phase. We can easily intuit that the JSF phases looks like the
invariant steps from the template method design pattern. But, JSF provides PhaseListeners
that are conceptually similar to variant steps of the template method design pattern.
Between each JSF phase (before and after it), a developer can implement PhaseListeners
to provide hooks similar to the template method hooks. For example, if the PhaseId
is ANY_PHASE,
the JSF implementation calls the PhaseListener before and after every phase.
The JSF implementation is slightly different because PhaseListeners are not
required, while the template method pattern assumes that subclasses generally
redefine variant steps that are defined abstract in the parent class.
A JSF phase
listener can be written by implementing the PhaseListener interface, as
below:
public class
MyPhaseListener implements PhaseListener {
private static final Logger LOG =
Logger.getLogger(MyPhaseListener.class.getName());
@Override
public void afterPhase(PhaseEvent event)
{
LOG.info("After phase: " +
event.getPhaseId());
}
@Override
public void afterPhase(PhaseEvent event)
{
LOG.log(Level.INFO, "After phase:
{0}", event.getPhaseId());
}
@Override
public void beforePhase(PhaseEvent event) {
LOG.log(Level.INFO, "Before phase:
{0}", event.getPhaseId());
}
}
The phase
listener should be configured in faces-config.xml:
<lifecycle>
<phase-listener>phaselistener.MyPhaseListener</phase-listener>
</lifecycle>
For an
initial request (GET) this will output:
Before
phase: RESTORE_VIEW 1
After phase:
RESTORE_VIEW 1
Before
phase: RENDER_RESPONSE 6
After phase:
RENDER_RESPONSE 6
For a
postback (POST) request this will output:
Before
phase: RESTORE_VIEW 1
After phase:
RESTORE_VIEW 1
Before
phase: APPLY_REQUEST_VALUES 2
After phase:
APPLY_REQUEST_VALUES 2
Before
phase: PROCESS_VALIDATIONS 3
After phase:
PROCESS_VALIDATIONS 3
Before
phase: UPDATE_MODEL_VALUES 4
After phase:
UPDATE_MODEL_VALUES 4
Before
phase: INVOKE_APPLICATION 5
After phase:
INVOKE_APPLICATION 5
Before
phase: RENDER_RESPONSE 6
After phase:
RENDER_RESPONSE 6
Complete
application is available here.
Read also:
Niciun comentariu :
Trimiteți un comentariu