Richfaces integration.

This commit is contained in:
Jeremy Grelle
2008-03-12 20:57:39 +00:00
parent 9f9e9234e9
commit 30ea4171b0
17 changed files with 193 additions and 66 deletions

View File

@@ -21,6 +21,7 @@
<!-- build time only dependencies -->
<dependency org="javax.servlet" name="servlet-api" rev="2.4" conf="buildtime->default" />
<dependency org="javax.el" name="el-api" rev="1.0" conf="buildtime->default" />
<dependency org="org.richfaces.framework" name="richfaces-api" rev="3.1.4.GA" conf="buildtime->default" />
<!-- JSF 1.2 dependencies -->
<!-- note that at this time we depend on MyFaces, not JSF-RI -->

View File

@@ -10,7 +10,6 @@
<action-listener>org.springframework.faces.model.SelectionTrackingActionListener</action-listener>
<variable-resolver>org.springframework.faces.webflow.FlowVariableResolver</variable-resolver>
<property-resolver>org.springframework.faces.webflow.FlowPropertyResolver</property-resolver>
<state-manager>org.springframework.faces.webflow.FlowViewStateManager</state-manager>
<view-handler>org.springframework.faces.webflow.FlowViewHandler</view-handler>
</application>

View File

@@ -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");
}
}

View File

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

View File

@@ -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();
}
}
}
}

View File

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

View File

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

View File

@@ -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 + "']";
}
}

View File

@@ -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) {

View File

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

View File

@@ -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());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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");
}