You could manually create and build the view when the restored view returns null
during postback. You can do this in a custom ViewHandler
. Here's a kickoff example:
public class RestorableViewHandler extends ViewHandlerWrapper {
private ViewHandler wrapped;
public RestorableViewHandler(ViewHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public UIViewRoot restoreView(FacesContext context, String viewId) {
UIViewRoot restoredView = wrapped.restoreView(context, viewId);
if (!(restoredView == null && context.isPostback())) {
return restoredView;
}
UIViewRoot createdView = createView(context, viewId);
context.setViewRoot(createdView);
try {
getViewDeclarationLanguage(context, viewId).buildView(context, createdView);
} catch (IOException e) {
throw new FacesException(e);
}
return createdView;
}
@Override
public ViewHandler getWrapped() {
return wrapped;
}
}
You may want to extend the if
check with a check if the viewId
represents the login page.
To get it to run, register it as follows in faces-config.xml
:
<application>
<view-handler>com.example.RestorableViewHandler</view-handler>
</application>
There are however technical limitations: the recreated view is exactly the same as it was during the initial request, so any modifications to the JSF component tree which are made thereafter, either by taghandlers or conditionally rendered components based on some view or even session scoped variables, are completely lost. In order to recreate exactly the desired view, you would need to make sure that those modifications are made based on request scoped variables (read: request parameters) instead of view or session scoped variables.
In other words, the state of the view should not depend on view or session scoped managed beans, but purely on request scoped managed beans.
Update: the OmniFaces JSF utility library has in the current 1.3 snapshot a reuseable solution in flavor of <o:enableRestorableView>
which can be embedded in <f:metadata>
. See also the <o:enableRestorableView>
showcase page on snapshot site for a demo.