使用Expression的Spring Web Flow ExternalRedirect

Dav*_*vis 4 java redirect spring jsp spring-webflow

背景

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

系统使用相对较慢的身份验证机制.但我不打算重新启动Web流,因此身份验证不应该干扰重定向.

JSP

"运行报告"按钮编码如下:

<button type="submit" id="run" name="_eventId_run">
    <fmt:message key="form.button.report.run" />
</button>
Run Code Online (Sandbox Code Playgroud)

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

<form:radiobutton path="parameters['service']" class="service" value="..." />
Run Code Online (Sandbox Code Playgroud)

提交表单显示绑定变量在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>
Run Code Online (Sandbox Code Playgroud)

该流有三种视图状态:列表报告,输入参数和运行报告.最后两个是相关的:

<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}"/>
Run Code Online (Sandbox Code Playgroud)

reportService.run(report)正在调用该方法.报告参数受到约束.返回的结果确实是正确的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;
}
Run Code Online (Sandbox Code Playgroud)

同样,正在返回正确的URL.没有控制器类.报告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
}
Run Code Online (Sandbox Code Playgroud)

问题

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

架构定义来看,一切似乎都是正确的.

问题

使用Spring 4.1.2,需要更改什么,以便externalRedirect将浏览器发送到返回的URL reportService.run(...)

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

尝试

以下是一些无效的变化:

  • $在EL中使用,而不是#(即externalRedirect:${flowScope.url})
  • 使用 <end-state id="redirect" view="externalRedirect:#{flowScope.url}"/>
  • 使用 <view-state id="redirect" view="externalRedirect:http://google.com"/>
  • form:button而不是button

更改重定向视图状态并删除表达式评估会导致重定向触发.例如:

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

当然,这意味着从不使用报告参数,这将不起作用.

Dav*_*vis 6

从过渡中删除评估:

<transition on="run" to="redirect"/>
Run Code Online (Sandbox Code Playgroud)

在EL语句中调用run方法以生成URL:

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