I have a JSF application containing two JSP pages that both display some of the same data from a session-scoped container object. Each page displays the data differently, each in a data table that varies between pages. This all works properly so far.
My problem is that I have been cheating a bit with how I figure out what page was requested from inside my backing bean action methods. On each page, I have used a binding for my data table.
draftReport.jsp:
<t:dataTable
border="1"
id="reportDraftDataTable"
binding="#{controller.reportDraftDataTable}"
value="#{sessionData.reportDraftAdapterList}"
var="currentRow"
rowClasses="dataTableOddRow, dataTableEvenRow">
report.jsp:
<t:dataTable
border="1"
id="reportDataTable"
binding="#{controller.reportDataTable}"
value="#{sessionData.reportAdapterList}"
var="currentRow"
rowClasses="dataTableOddRow, dataTableEvenRow">
I have a request-scoped backing bean (named Controller
) with some of the action methods for these pages. Rather than duplicate code on the backing bean (one similar method for each similar JSP page), I wanted to figure out what page was being rendered and use that as a parameter to a generic handler method (that can handle actions from both pages) on the backing bean. So I cheated and did this:
public class Controller {
...
private HtmlDataTable preArrivalReportDataTable;
private HtmlDataTable preArrivalReportDraftDataTable;
private static enum ReportType {
NON_DRAFT,
DRAFT
}
...
private ReportType determineReportTypeFromControlBindings() {
Validate.isTrue(this.preArrivalReportDataTable != null ^
this.preArrivalReportDraftDataTable != null,
"Either preArrivalReportDataTable XOR " +
"preArrivalReportDraftDataTable must be null in " +
"determineReportTypeFromControlBindings()");
if (this.preArrivalReportDataTable != null) {
return ReportType.NON_DRAFT;
} else {
return ReportType.DRAFT;
}
}
...
public String actionOnReport() {
ReportType reportType = null;
reportType = determineReportTypeFromControlBindings();
handleReportAction(reportType);
return "REFRESH";
}
...
}
This worked OK inside action methods in my Controller class, but then I needed to add another method that finally broke my hacky code:
public String getStyleClass() {
ReportType reportType = determineReportTypeFromControlBindings();
switch (reportType) {
case NON_DRAFT:
return "styleA";
case DRAFT:
return "styleB";
default:
return null;
}
}
In my JSP, the JSF-EL expression is located above the control binding for the data table that I'm using in the backing bean to determine what page I'm on. At that point the determineReportTypeFromControlBindings()
throws an exception at the Validate check, presumably because the control binding has not occurred yet.
I'm not surprised that this is happening. It always felt like the wrong way. But my question is:
What is the correct way to determine the currently requested JSP page from a request-scoped backing bean action method?
In case it is relevant, I'm using the MyFaces 1.2 Tomahawk tag library.