title: Spring Web Flow ExternalRedirect using Expression
body: <h1>Background</h1>
  
  <p>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).</p>
  
  <p>The system uses a relatively slow authentication mechanism. But I'm not looking to restart the web flow, so the authentication should not <a href="https://stackoverflow.com/a/28256489/59087">otherwise interfere</a> with the redirect.</p>
  
  <h2>JSP</h2>
  
  <p>The "Run Report" button is coded as follows:</p>
  
  <pre><code>&lt;button type="submit" id="run" name="_eventId_run"&gt;
      &lt;fmt:message key="form.button.report.run" /&gt;
  &lt;/button&gt;
  </code></pre>
  
  <p>The rest of the page binds the parameters to a map in the DAO, such as:</p>
  
  <pre><code>&lt;form:radiobutton path="parameters['service']" class="service" value="..." /&gt;
  </code></pre>
  
  <p>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.</p>
  
  <p>The form itself resembles:</p>
  
  <pre><code>&lt;form:form modelAttribute="report" action="${flowExecutionUrl}"
      method="post"&gt;
      &lt;fieldset&gt;
          &lt;%-- secret tokens --%&gt;
          &lt;tiles:insertAttribute name="hidden" /&gt;
  
          &lt;%-- includes the requested report form parameters --%&gt;
          &lt;jsp:include page="${reportKey}.jsp" /&gt;
  
          &lt;%-- includes the aforementioned submit button %--&gt;
          &lt;tiles:insertAttribute name="reportButtons" /&gt;
      &lt;/fieldset&gt;
  &lt;/form:form&gt;
  </code></pre>
  
  <h2>Flow</h2>
  
  <p>The flow has three view states: list reports, enter parameters, and run report. The last two are pertinent:</p>
  
  <pre><code>&lt;view-state id="parameters" model="report" view="flow/reports/parameters"&gt;
      &lt;transition on="run" to="redirect"&gt;
          &lt;evaluate expression="reportService.run(report)" result="flowScope.url" /&gt;
      &lt;/transition&gt;
  &lt;/view-state&gt;
  
  &lt;view-state id="redirect" view="externalRedirect:#{flowScope.url}"/&gt;
  </code></pre>
  
  <p>The <code>reportService.run(report)</code> method is being called. The report parameters are being bound. The return result is, indeed, the correct URL.</p>
  
  <h2>Java</h2>
  
  <p>The report service itself is reasonably trivial:</p>
  
  <pre><code>public String run(Report report) {
      Map&lt;String, String&gt; parameters = report.getParameters();
  
      String url = getConfigurationValue("ReportUrl");
  
      for (String key : parameters.keySet()) {
          info("Report Parameter: {} = {}", key, parameters.get(key));
      }
  
      return url;
  }
  </code></pre>
  
  <p>Again, the correct url is being returned. There is no controller class. The Report DAO could hardly be simpler:</p>
  
  <pre><code>public class Report extends DAOBase implements Serializable {
      /** Values to pass into the report. */
      private Map&lt;String, String&gt; parameters;
  
      public Report() {
          setParameters(createParameters());
      }
  
      // standard accessors and serial version not shown
  }
  </code></pre>
  
  <h1>Problem</h1>
  
  <p>It appears that the application is performing a <a href="http://en.wikipedia.org/wiki/Post/Redirect/Get" rel="nofollow noreferrer">POST-Redirect-GET</a> (PRG). The GET does not direct the browser to the URL set by <code>flowScope.url</code>. (I have not verified that <code>flowScope.url</code> contains valid data.) When the POST operation completes, the application is redirected to the parameter flow, rather than the run button redirecting to the <code>redirect</code> flow.</p>
  
  <p>From the <a href="http://schema.spring.io/webflow/spring-webflow-2.0.xsd" rel="nofollow noreferrer">schema definition</a>, everything seems correct.</p>
  
  <h1>Questions</h1>
  
  <p>Using Spring 4.1.2, what needs to change so that the externalRedirect sends the browser to the URL returned by <code>reportService.run(...)</code>?</p>
  
  <p>Does the form need to supply a different value for <code>flowExecutionUrl</code>?</p>
  
  <h1>Attempts</h1>
  
  <p>Here are some of the various changes that have been made to no avail:</p>
  
  <ul>
  <li>Use <code>$</code> in the EL, instead of <code>#</code> (i.e., <code>externalRedirect:${flowScope.url}</code>)</li>
  <li>Use <code>&lt;end-state id="redirect" view="externalRedirect:#{flowScope.url}"/&gt;</code></li>
  <li>Use <code>&lt;view-state id="redirect" view="externalRedirect:http://google.com"/&gt;</code></li>
  <li>Use <code>form:button</code> instead of <code>button</code></li>
  </ul>
  
  <p>Changing the redirect view-state and removing the expression evaluation causes the redirect to fire. For example:</p>
  
  <pre><code>&lt;transition on="run" to="redirect"&gt;
      &lt;!-- &lt;evaluate expression="reportService.run(report)" result="flowScope.url" /&gt;  --&gt;
  &lt;/transition&gt;
  ...
  &lt;view-state id="redirect" view="externalRedirect:http://google.com"/&gt;
  </code></pre>
  
  <p>This, of course, means that the report parameters are never used, which won't work.</p>