Spring 使用表达式的 Web 流外部重定向

Spring Web Flow ExternalRedirect using Expression

背景

用户必须向服务器提交报表参数。服务器将用户重定向到 URL。 URL 运行s Oracle Reports 生成 PDF(或网页)。

系统使用了相对较慢的身份验证机制。但我不打算重新启动网络流程,因此身份验证不应 otherwise interfere 与重定向。

JSP

"Run Report"按钮编码如下:

<button type="submit" id="run" name="_eventId_run">
    <fmt:message key="form.button.report.run" />
</button>

页面的其余部分将参数绑定到DAO中的一个映射,例如:

<form:radiobutton path="parameters['service']" class="service" value="..." />

提交表单表明在 DAO 映射中正确设置了绑定变量。此外,该报告能够生成用于重定向的 URL。

表格本身类似于:

<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>

流量

流程具有三种视图状态:列出报告、输入参数和运行报告。最后两个是相关的:

<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}"/>

正在调用 reportService.run(report) 方法。正在绑定报表参数。 return 结果确实是正确的 URL.

Java

报告服务本身相当简单:

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;
}

同样,正在 return 编辑正确的 url。没有控制器 class。 Report DAO 简直再简单不过了:

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
}

问题

应用程序似乎正在执行 POST-Redirect-GET (PRG)。 GET 不会将浏览器定向到 flowScope.url 设置的 URL。 (我还没有验证 flowScope.url 包含有效数据。)当 POST 操作完成时,应用程序被重定向到参数流,而不是 运行 按钮重定向到 redirect流.

schema definition 看来,一切似乎都是正确的。

问题

使用 Spring 4.1.2,需要更改什么才能使 externalRedirect 将浏览器发送到由 reportService.run(...) 编辑的 URL return?

表单是否需要为 flowExecutionUrl 提供不同的值?

尝试次数

以下是一些无效的更改:

更改重定向视图状态并删除表达式计算会导致触发重定向。例如:

<transition on="run" to="redirect">
    <!-- <evaluate expression="reportService.run(report)" result="flowScope.url" />  -->
</transition>
...
<view-state id="redirect" view="externalRedirect:http://google.com"/>

当然,这意味着报告参数从未被使用过,这是行不通的。

从转换中删除评估:

<transition on="run" to="redirect"/>

在EL语句中调用运行方法生成URL:

<view-state id="redirect" view="externalRedirect:#{reportService.run(report)}"/>