A user must submit report parameters to the server. The server redirects the user to a URL. That URL runs Oracle Reports to produce a PDF (or web page).
The system uses a relatively slow authentication mechanism. But I'm not looking to restart the web flow, so the authentication should not otherwise interfere with the redirect.
The "Run Report" button is coded as follows:
<button type="submit" id="run" name="_eventId_run">
<fmt:message key="form.button.report.run" />
</button>
The rest of the page binds the parameters to a map in the DAO, such as:
<form:radiobutton path="parameters['service']" class="service" value="..." />
Submitting the form shows that the bind variables are set in the DAO map correctly. Further, the report is able to generate the URL used for redirection.
The form itself resembles:
<form:form modelAttribute="report" action="${flowExecutionUrl}"
method="post">
<fieldset>
<%-- secret tokens --%>
<tiles:insertAttribute name="hidden" />
<%-- includes the requested report form parameters --%>
<jsp:include page="${reportKey}.jsp" />
<%-- includes the aforementioned submit button %-->
<tiles:insertAttribute name="reportButtons" />
</fieldset>
</form:form>
The flow has three view states: list reports, enter parameters, and run report. The last two are pertinent:
<view-state id="parameters" model="report" view="flow/reports/parameters">
<transition on="run" to="redirect">
<evaluate expression="reportService.run(report)" result="flowScope.url" />
</transition>
</view-state>
<view-state id="redirect" view="externalRedirect:#{flowScope.url}"/>
The reportService.run(report)
method is being called. The report parameters are being bound. The return result is, indeed, the correct URL.
The report service itself is reasonably trivial:
public String run(Report report) {
Map<String, String> parameters = report.getParameters();
String url = getConfigurationValue("ReportUrl");
for (String key : parameters.keySet()) {
info("Report Parameter: {} = {}", key, parameters.get(key));
}
return url;
}
Again, the correct url is being returned. There is no controller class. The Report DAO could hardly be simpler:
public class Report extends DAOBase implements Serializable {
/** Values to pass into the report. */
private Map<String, String> parameters;
public Report() {
setParameters(createParameters());
}
// standard accessors and serial version not shown
}
It appears that the application is performing a POST-Redirect-GET (PRG). The GET does not direct the browser to the URL set by flowScope.url
. (I have not verified that flowScope.url
contains valid data.) When the POST operation completes, the application is redirected to the parameter flow, rather than the run button redirecting to the redirect
flow.
From the schema definition, everything seems correct.
Using Spring 4.1.2, what needs to change so that the externalRedirect sends the browser to the URL returned by reportService.run(...)
?
Does the form need to supply a different value for flowExecutionUrl
?
Here are some of the various changes that have been made to no avail:
$
in the EL, instead of #
(i.e., externalRedirect:${flowScope.url}
)<end-state id="redirect" view="externalRedirect:#{flowScope.url}"/>
<view-state id="redirect" view="externalRedirect:http://google.com"/>
form:button
instead of button
Changing the redirect view-state and removing the expression evaluation causes the redirect to fire. For example:
<transition on="run" to="redirect">
<!-- <evaluate expression="reportService.run(report)" result="flowScope.url" /> -->
</transition>
...
<view-state id="redirect" view="externalRedirect:http://google.com"/>
This, of course, means that the report parameters are never used, which won't work.
Remove the evaluation from the transition:
<transition on="run" to="redirect"/>
Call the run method within an EL statement to generate the URL:
<view-state id="redirect" view="externalRedirect:#{reportService.run(report)}"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With