diff --git a/spring-faces/ivy.xml b/spring-faces/ivy.xml
index b02cb07f..5db6ac0e 100644
--- a/spring-faces/ivy.xml
+++ b/spring-faces/ivy.xml
@@ -21,6 +21,7 @@
+
diff --git a/spring-faces/src/main/java/META-INF/faces-config.xml b/spring-faces/src/main/java/META-INF/faces-config.xml
index 99d5dfb7..e279da38 100644
--- a/spring-faces/src/main/java/META-INF/faces-config.xml
+++ b/spring-faces/src/main/java/META-INF/faces-config.xml
@@ -10,7 +10,6 @@
org.springframework.faces.model.SelectionTrackingActionListener
org.springframework.faces.webflow.FlowVariableResolver
org.springframework.faces.webflow.FlowPropertyResolver
- org.springframework.faces.webflow.FlowViewStateManager
org.springframework.faces.webflow.FlowViewHandler
diff --git a/spring-faces/src/main/java/org/springframework/faces/mvc/JsfController.java b/spring-faces/src/main/java/org/springframework/faces/mvc/JsfController.java
new file mode 100644
index 00000000..914d3b17
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/mvc/JsfController.java
@@ -0,0 +1,16 @@
+package org.springframework.faces.mvc;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+public class JsfController extends AbstractController {
+
+ protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException("Auto-generated method stub");
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java b/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java
index c6db6e25..ec2b84ba 100644
--- a/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java
+++ b/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java
@@ -85,7 +85,7 @@ public class JsfView extends AbstractUrlBasedView {
private void populateRequestMap(FacesContext facesContext, Map model) {
Iterator i = model.keySet().iterator();
while (i.hasNext()) {
- Object key = i.next();
+ String key = i.next().toString();
facesContext.getExternalContext().getRequestMap().put(key, model.get(key));
}
}
diff --git a/spring-faces/src/main/java/org/springframework/faces/mvc/richfaces/RichFacesAjaxHandler.java b/spring-faces/src/main/java/org/springframework/faces/mvc/richfaces/RichFacesAjaxHandler.java
new file mode 100644
index 00000000..9c6f5a51
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/mvc/richfaces/RichFacesAjaxHandler.java
@@ -0,0 +1,67 @@
+package org.springframework.faces.mvc.richfaces;
+
+import java.io.IOException;
+
+import javax.faces.FactoryFinder;
+import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ajax4jsf.context.AjaxContext;
+import org.springframework.faces.webflow.FlowLifecycle;
+import org.springframework.webflow.mvc.SpringJavascriptAjaxHandler;
+
+public class RichFacesAjaxHandler extends SpringJavascriptAjaxHandler {
+
+ public boolean isAjaxRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response) {
+ FacesContextHelper helper = new FacesContextHelper();
+ if (AjaxContext.getCurrentInstance(helper.getFacesContext(context, request, response)).isAjaxRequest(
+ helper.getFacesContext(context, request, response))) {
+ helper.cleanup();
+ return true;
+ } else {
+ helper.cleanup();
+ return super.isAjaxRequest(context, request, response);
+ }
+ }
+
+ public void sendAjaxRedirect(ServletContext context, HttpServletRequest request, HttpServletResponse response,
+ String targetUrl, boolean popup) throws IOException {
+ FacesContextHelper helper = new FacesContextHelper();
+ if (AjaxContext.getCurrentInstance(helper.getFacesContext(context, request, response)).isAjaxRequest(
+ helper.getFacesContext(context, request, response))) {
+ helper.cleanup();
+ response.sendRedirect(response.encodeRedirectURL(targetUrl));
+ } else {
+ helper.cleanup();
+ super.sendAjaxRedirect(context, request, response, targetUrl, popup);
+ }
+ }
+
+ private static class FacesContextHelper {
+
+ private boolean created = false;
+
+ protected FacesContext getFacesContext(ServletContext context, HttpServletRequest request,
+ HttpServletResponse response) {
+ if (FacesContext.getCurrentInstance() != null) {
+ return FacesContext.getCurrentInstance();
+ } else {
+ created = true;
+ FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
+ .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+ FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context, request, response,
+ FlowLifecycle.newInstance());
+ return defaultFacesContext;
+ }
+ }
+
+ protected void cleanup() {
+ if (created) {
+ FacesContext.getCurrentInstance().release();
+ }
+ }
+ }
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java
index a3f783ab..1f53967f 100644
--- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java
@@ -19,13 +19,16 @@ import java.lang.reflect.Method;
import java.util.Iterator;
import javax.el.ELContext;
+import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
import javax.faces.context.ResponseStream;
import javax.faces.context.ResponseWriter;
+import javax.faces.lifecycle.Lifecycle;
import javax.faces.render.RenderKit;
import org.springframework.binding.message.Message;
@@ -47,12 +50,12 @@ public class FlowFacesContext extends FacesContext {
/**
* The key for storing the responseComplete flag
*/
- static final String RESPONSE_COMPLETE_KEY = "responseComplete";
+ static final String RESPONSE_COMPLETE_KEY = "webFlowResponseComplete";
/**
* The key for storing the renderResponse flag
*/
- static final String RENDER_RESPONSE_KEY = "renderResponse";
+ static final String RENDER_RESPONSE_KEY = "webFlowRenderResponse";
/**
* The key for storing the renderResponse flag
@@ -64,6 +67,21 @@ public class FlowFacesContext extends FacesContext {
*/
private FacesContext delegate;
+ public static FlowFacesContext newInstance(RequestContext context, Lifecycle lifecycle) {
+ FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
+ .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+ FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
+ .getNativeContext(), context.getExternalContext().getNativeRequest(), context.getExternalContext()
+ .getNativeResponse(), lifecycle);
+ FlowFacesContext instance = new FlowFacesContext(context, defaultFacesContext);
+
+ // Ensure that FlowViewStateManager is first in the chain
+ FlowViewStateManager sm = new FlowViewStateManager(instance.getApplication().getStateManager());
+ instance.getApplication().setStateManager(sm);
+
+ return instance;
+ }
+
public FlowFacesContext(RequestContext context, FacesContext delegate) {
this.context = context;
this.delegate = delegate;
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java
index b4868cf4..420c1c7e 100644
--- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java
@@ -16,10 +16,12 @@
package org.springframework.faces.webflow;
import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,13 +35,21 @@ import org.apache.commons.logging.LogFactory;
*
* @author Jeremy Grelle
*/
-class FlowLifecycle extends Lifecycle {
+public class FlowLifecycle extends Lifecycle {
private static final Log logger = LogFactory.getLog(FlowLifecycle.class);
private final Lifecycle delegate;
- public FlowLifecycle(Lifecycle delegate) {
+ public static Lifecycle newInstance() {
+ LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
+ .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+ Lifecycle defaultLifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
+ return new FlowLifecycle(defaultLifecycle);
+
+ }
+
+ FlowLifecycle(Lifecycle delegate) {
this.delegate = delegate;
}
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java
index ebe6c3a2..255ac393 100644
--- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java
@@ -18,10 +18,8 @@ package org.springframework.faces.webflow;
import java.io.IOException;
import javax.faces.FacesException;
-import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
-import javax.faces.context.FacesContextFactory;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
@@ -51,8 +49,11 @@ public class JsfView implements View {
private RequestContext context;
+ private String viewId;
+
public JsfView(UIViewRoot viewRoot, Lifecycle facesLifecycle, RequestContext context) {
this.viewRoot = viewRoot;
+ this.viewId = viewRoot.getViewId();
this.facesLifecycle = facesLifecycle;
this.context = context;
}
@@ -74,7 +75,7 @@ public class JsfView implements View {
* This implementation performs the standard duties of the JSF RENDER_RESPONSE phase.
*/
public void render() throws IOException {
- FacesContext facesContext = createFlowFacesContext();
+ FacesContext facesContext = FlowFacesContext.newInstance(context, facesLifecycle);
facesContext.setViewRoot(viewRoot);
facesContext.renderResponse();
try {
@@ -91,16 +92,7 @@ public class JsfView implements View {
}
}
- private FacesContext createFlowFacesContext() {
- FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
- .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
- FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
- .getNativeContext(), context.getExternalContext().getNativeRequest(), context.getExternalContext()
- .getNativeResponse(), facesLifecycle);
- return new FlowFacesContext(context, defaultFacesContext);
- }
-
public String toString() {
- return "[JSFView = '" + viewRoot.getViewId() + "']";
+ return "[JSFView = '" + viewId + "']";
}
}
\ No newline at end of file
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java
index ccf9ffbf..ec0a6a29 100644
--- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java
@@ -17,15 +17,16 @@ package org.springframework.faces.webflow;
import java.util.Iterator;
-import javax.faces.FactoryFinder;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
-import javax.faces.context.FacesContextFactory;
import javax.faces.el.ValueBinding;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,9 +34,12 @@ import org.springframework.binding.expression.Expression;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.faces.ui.AjaxViewRoot;
+import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.View;
import org.springframework.webflow.execution.ViewFactory;
+import org.springframework.webflow.mvc.AjaxHandler;
+import org.springframework.webflow.mvc.SpringJavascriptAjaxHandler;
/**
* JSF-specific {@link ViewFactory} implementation.
@@ -64,7 +68,7 @@ public class JsfViewFactory implements ViewFactory {
public View getView(RequestContext context) {
- FacesContext facesContext = createFlowFacesContext(context, lifecycle);
+ FacesContext facesContext = FlowFacesContext.newInstance(context, lifecycle);
try {
boolean restored = false;
@@ -118,20 +122,21 @@ public class JsfViewFactory implements ViewFactory {
}
private JsfView createJsfView(UIViewRoot root, Lifecycle lifecycle, RequestContext context) {
- if (context.getExternalContext().isAjaxRequest()) {
+ if (isSpringJavascriptAjaxRequest(context.getExternalContext())) {
return new JsfView(new AjaxViewRoot(root), lifecycle, context);
} else {
return new JsfView(root, lifecycle, context);
}
}
- private FacesContext createFlowFacesContext(RequestContext context, Lifecycle lifecycle) {
- FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
- .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
- FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
- .getNativeContext(), context.getExternalContext().getNativeRequest(), context.getExternalContext()
- .getNativeResponse(), lifecycle);
- return new FlowFacesContext(context, defaultFacesContext);
+ private boolean isSpringJavascriptAjaxRequest(ExternalContext context) {
+ if (context.getNativeContext() instanceof ServletContext) {
+ AjaxHandler handler = new SpringJavascriptAjaxHandler();
+ return handler.isAjaxRequest((ServletContext) context.getNativeContext(), (HttpServletRequest) context
+ .getNativeRequest(), (HttpServletResponse) context.getNativeResponse());
+ } else {
+ return false;
+ }
}
private String resolveViewName(RequestContext context) {
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java
index 11a7cc74..9175ca55 100644
--- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java
@@ -15,9 +15,7 @@
*/
package org.springframework.faces.webflow;
-import javax.faces.FactoryFinder;
import javax.faces.lifecycle.Lifecycle;
-import javax.faces.lifecycle.LifecycleFactory;
import org.springframework.binding.expression.Expression;
import org.springframework.core.io.ResourceLoader;
@@ -43,16 +41,9 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
return viewStateId + FACELETS_EXTENSION;
}
- private Lifecycle createFlowFacesLifecycle() {
- LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
- .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
- Lifecycle defaultLifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
- return new FlowLifecycle(defaultLifecycle);
- }
-
private Lifecycle getLifecycle() {
if (lifecycle == null) {
- lifecycle = createFlowFacesLifecycle();
+ lifecycle = FlowLifecycle.newInstance();
}
return lifecycle;
}
diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java
index 8da33eb9..9fbcd8f9 100644
--- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java
+++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java
@@ -20,6 +20,9 @@ import org.jboss.el.ExpressionFactoryImpl;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.support.ParserContextImpl;
import org.springframework.faces.ui.AjaxViewRoot;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockServletContext;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.LocalParameterMap;
@@ -54,10 +57,19 @@ public class JsfViewFactoryTests extends TestCase {
private MockExternalContext extContext = new MockExternalContext();
+ private MockServletContext servletContext = new MockServletContext();
+
+ private MockHttpServletRequest request = new MockHttpServletRequest();
+
+ private MockHttpServletResponse response = new MockHttpServletResponse();
+
private String event = "foo";
protected void setUp() throws Exception {
configureJsf();
+ extContext.setNativeContext(servletContext);
+ extContext.setNativeRequest(request);
+ extContext.setNativeResponse(response);
RequestContextHolder.setRequestContext(context);
EasyMock.expect(context.getFlashScope()).andStubReturn(flashMap);
EasyMock.expect(context.getExternalContext()).andStubReturn(extContext);
@@ -138,7 +150,7 @@ public class JsfViewFactoryTests extends TestCase {
existingRoot.setViewId(VIEW_ID);
((MockViewHandler) viewHandler).setRestoreView(existingRoot);
- extContext.setAjaxRequest(true);
+ request.addHeader("Accept", "text/html;type=ajax");
EasyMock.expect(context.getCurrentState()).andReturn(new ModalViewState());
diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java
index 2e0aef4f..4ff824bf 100644
--- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java
+++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java
@@ -88,8 +88,12 @@ public class JsfViewTests extends TestCase {
EasyMock.expect(requestContext.getFlowScope()).andStubReturn(flowMap);
EasyMock.expect(requestContext.getFlowExecutionContext()).andStubReturn(flowExecutionContext);
EasyMock.expect(flowExecutionContext.getKey()).andStubReturn(key);
- EasyMock.expect(flashMap.put(EasyMock.matches("renderResponse"), EasyMock.anyObject())).andStubReturn(null);
- EasyMock.expect(flashMap.put(EasyMock.matches("responseComplete"), EasyMock.anyObject())).andStubReturn(null);
+ EasyMock.expect(
+ flashMap.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock
+ .anyObject())).andStubReturn(null);
+ EasyMock.expect(
+ flashMap.put(EasyMock.matches(FlowFacesContext.RESPONSE_COMPLETE_KEY), EasyMock
+ .anyObject())).andStubReturn(null);
EasyMock.replay(new Object[] { requestContext, flowExecutionContext, flowMap, flashMap });
@@ -103,8 +107,12 @@ public class JsfViewTests extends TestCase {
EasyMock.expect(requestContext.getExternalContext()).andStubReturn(new MockExternalContext());
EasyMock.expect(requestContext.getFlashScope()).andStubReturn(flashMap);
- EasyMock.expect(flashMap.put(EasyMock.matches("renderResponse"), EasyMock.anyObject())).andStubReturn(null);
- EasyMock.expect(flashMap.put(EasyMock.matches("responseComplete"), EasyMock.anyObject())).andStubReturn(null);
+ EasyMock.expect(
+ flashMap.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock
+ .anyObject())).andStubReturn(null);
+ EasyMock.expect(
+ flashMap.put(EasyMock.matches(FlowFacesContext.RESPONSE_COMPLETE_KEY), EasyMock
+ .anyObject())).andStubReturn(null);
EasyMock.replay(new Object[] { requestContext, flowExecutionContext, flashMap });
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java b/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java
index 080efb35..1b3d43a9 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/execution/View.java
@@ -29,7 +29,7 @@ public interface View {
/**
* Well-known attribute name for storing a render fragments value.
*/
- public static final String RENDER_FRAGMENTS_ATTRIBUTE = "webflowRenderFragments";
+ public static final String RENDER_FRAGMENTS_ATTRIBUTE = "flowRenderFragments";
/**
* Render this view's content.
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/AjaxHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/AjaxHandler.java
index 029848c2..84534498 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/AjaxHandler.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/AjaxHandler.java
@@ -15,6 +15,9 @@
*/
package org.springframework.webflow.mvc;
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -29,7 +32,7 @@ public interface AjaxHandler {
* Is the current request an Ajax request?
* @param request the current request
*/
- public boolean isAjaxRequest(HttpServletRequest request);
+ public boolean isAjaxRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response);
/**
* Send a redirect request to the Ajax client. This should cause the client-side agent to send a new request to the
@@ -38,5 +41,6 @@ public interface AjaxHandler {
* @param targetUrl the target url to redirect to
* @param popup wheter the redirect should be sent from a new popup dialog window
*/
- public void sendAjaxRedirect(HttpServletResponse response, String targetUrl, boolean popup);
+ public void sendAjaxRedirect(ServletContext context, HttpServletRequest request, HttpServletResponse response,
+ String targetUrl, boolean popup) throws IOException;
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowController.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowController.java
index 0775d57f..b2b51218 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowController.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowController.java
@@ -149,7 +149,7 @@ public class FlowController extends AbstractController {
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
HttpServletResponse response) {
ServletExternalContext context = new ServletExternalContext(getServletContext(), request, response, urlHandler);
- context.setAjaxRequest(ajaxHandler.isAjaxRequest(request));
+ context.setAjaxRequest(ajaxHandler.isAjaxRequest(getServletContext(), request, response));
return context;
}
@@ -191,13 +191,13 @@ public class FlowController extends AbstractController {
if (logger.isDebugEnabled()) {
logger.debug("Sending flow execution redirect to " + url);
}
- sendRedirect(context, response, url);
+ sendRedirect(context, request, response, url);
return null;
} else if (context.externalRedirectRequested()) {
if (logger.isDebugEnabled()) {
logger.debug("Sending external redirect to " + context.getExternalRedirectUrl());
}
- sendRedirect(context, response, context.getExternalRedirectUrl());
+ sendRedirect(context, request, response, context.getExternalRedirectUrl());
return null;
} else {
// nothing to do: flow has handled the response
@@ -211,13 +211,13 @@ public class FlowController extends AbstractController {
if (logger.isDebugEnabled()) {
logger.debug("Sending flow definition to " + url);
}
- sendRedirect(context, response, url);
+ sendRedirect(context, request, response, url);
return null;
} else if (context.externalRedirectRequested()) {
if (logger.isDebugEnabled()) {
logger.debug("Sending external redirect to " + context.getExternalRedirectUrl());
}
- sendRedirect(context, response, context.getExternalRedirectUrl());
+ sendRedirect(context, request, response, context.getExternalRedirectUrl());
return null;
} else {
return handleFlowOutcome(result.getFlowId(), result.getEndedOutcome(), result.getEndedOutput(),
@@ -228,10 +228,10 @@ public class FlowController extends AbstractController {
}
}
- private void sendRedirect(ServletExternalContext context, HttpServletResponse response, String targetUrl)
- throws IOException {
+ private void sendRedirect(ServletExternalContext context, HttpServletRequest request, HttpServletResponse response,
+ String targetUrl) throws IOException {
if (context.isAjaxRequest()) {
- ajaxHandler.sendAjaxRedirect(response, targetUrl, context.redirectInPopup());
+ ajaxHandler.sendAjaxRedirect(getServletContext(), request, response, targetUrl, context.redirectInPopup());
} else {
response.sendRedirect(response.encodeRedirectURL(targetUrl));
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowHandlerAdapter.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowHandlerAdapter.java
index c34c1e15..4d014841 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowHandlerAdapter.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/FlowHandlerAdapter.java
@@ -134,7 +134,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
protected ServletExternalContext createServletExternalContext(HttpServletRequest request,
HttpServletResponse response) {
ServletExternalContext context = new ServletExternalContext(getServletContext(), request, response, urlHandler);
- context.setAjaxRequest(ajaxHandler.isAjaxRequest(request));
+ context.setAjaxRequest(ajaxHandler.isAjaxRequest(getServletContext(), request, response));
return context;
}
@@ -176,13 +176,13 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
if (logger.isDebugEnabled()) {
logger.debug("Sending flow execution redirect to " + url);
}
- sendRedirect(context, response, url);
+ sendRedirect(context, request, response, url);
return null;
} else if (context.externalRedirectRequested()) {
if (logger.isDebugEnabled()) {
logger.debug("Sending external redirect to " + context.getExternalRedirectUrl());
}
- sendRedirect(context, response, context.getExternalRedirectUrl());
+ sendRedirect(context, request, response, context.getExternalRedirectUrl());
return null;
} else {
return null;
@@ -195,13 +195,13 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
if (logger.isDebugEnabled()) {
logger.debug("Sending flow definition to " + url);
}
- sendRedirect(context, response, url);
+ sendRedirect(context, request, response, url);
return null;
} else if (context.externalRedirectRequested()) {
if (logger.isDebugEnabled()) {
logger.debug("Sending external redirect to " + context.getExternalRedirectUrl());
}
- sendRedirect(context, response, context.getExternalRedirectUrl());
+ sendRedirect(context, request, response, context.getExternalRedirectUrl());
return null;
} else {
ModelAndView mv = handler.handleExecutionOutcome(result.getEndedOutcome(), result.getEndedOutput(),
@@ -214,10 +214,10 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
}
}
- private void sendRedirect(ServletExternalContext context, HttpServletResponse response, String targetUrl)
- throws IOException {
+ private void sendRedirect(ServletExternalContext context, HttpServletRequest request, HttpServletResponse response,
+ String targetUrl) throws IOException {
if (context.isAjaxRequest()) {
- ajaxHandler.sendAjaxRedirect(response, targetUrl, context.redirectInPopup());
+ ajaxHandler.sendAjaxRedirect(getServletContext(), request, response, targetUrl, context.isAjaxRequest());
} else {
response.sendRedirect(response.encodeRedirectURL(targetUrl));
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/SpringJavascriptAjaxHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/SpringJavascriptAjaxHandler.java
index 2ea6a0ed..cb0b7b17 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/SpringJavascriptAjaxHandler.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/SpringJavascriptAjaxHandler.java
@@ -15,6 +15,9 @@
*/
package org.springframework.webflow.mvc;
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -48,7 +51,7 @@ public class SpringJavascriptAjaxHandler implements AjaxHandler {
*/
private static final String AJAX_SOURCE_PARAM = "ajaxSource";
- public boolean isAjaxRequest(HttpServletRequest request) {
+ public boolean isAjaxRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response) {
String acceptHeader = request.getHeader("Accept");
String ajaxParam = request.getParameter(AJAX_SOURCE_PARAM);
if (AJAX_ACCEPT_CONTENT_TYPE.equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
@@ -58,7 +61,8 @@ public class SpringJavascriptAjaxHandler implements AjaxHandler {
}
}
- public void sendAjaxRedirect(HttpServletResponse response, String targetUrl, boolean popup) {
+ public void sendAjaxRedirect(ServletContext context, HttpServletRequest request, HttpServletResponse response,
+ String targetUrl, boolean popup) throws IOException {
if (popup) {
response.setHeader(POPUP_VIEW_HEADER, "true");
}