
net.sourceforge.stripes.action.ForwardResolution Maven / Gradle / Ivy
Show all versions of stripes Show documentation
/* Copyright 2005-2006 Tim Fennell
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sourceforge.stripes.action;
import net.sourceforge.stripes.controller.AsyncResponse;
import net.sourceforge.stripes.controller.StripesConstants;
import net.sourceforge.stripes.util.Log;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
*
* Resolution that uses the Servlet API to forward the user to another
* path within the same web application using a server side forward.
*
*
* There is one case when this resolution will issue an include instead of a
* forward. The Servlet specification is ambiguous about what should happen when
* a forward is issued inside of an include. The behaviour varies widely by
* container, from outputting only the content of the forward, to only the
* content prior to the include! To make this behaviour more consistent the
* ForwardResolution will automatically determine if it is executing inside of
* an include, and if that is the case it will include the appropriate
* URL instead of
* forwarding to it. This behaviour can be turned off be calling
* {@literal autoInclude(false)}.
*
*
* You can optionally set an HTTP status code with {@link #setStatus(int)}, in
* which case a call to {@code response.setStatus(status)} will be made when
* executing the resolution.
*
* @see RedirectResolution
* @author Tim Fennell
*/
public class ForwardResolution extends OnwardResolution {
private boolean autoInclude = true;
private static final Log log = Log.getInstance(ForwardResolution.class);
private String event;
private Integer status;
/**
* Simple constructor that takes in the path to forward the user to.
*
* @param path the path within the web application that the user should be
* forwarded to
*/
public ForwardResolution(String path) {
super(path);
}
/**
* Constructs a ForwardResolution that will forward to the URL appropriate
* for the ActionBean supplied. This constructor should be preferred when
* forwarding to an ActionBean as it will ensure the correct URL is always
* used.
*
* @param beanType the Class object representing the ActionBean to redirect
* to
*/
public ForwardResolution(Class extends ActionBean> beanType) {
super(beanType);
}
/**
* Constructs a ForwardResolution that will forward to the URL appropriate
* for the ActionBean supplied. This constructor should be preferred when
* forwarding to an ActionBean as it will ensure the correct URL is always
* used.
*
* @param beanType the Class object representing the ActionBean to redirect
* to
* @param event the event that should be triggered on the redirect
*/
public ForwardResolution(Class extends ActionBean> beanType, String event) {
super(beanType, event);
this.event = event;
}
/**
* If true then the ForwardResolution will automatically detect when it is
* executing as part of a server-side Include and include the
* supplied URL instead of forwarding to it. Defaults to true.
*
* @param auto whether or not to automatically detect and use includes
*/
public void autoInclude(boolean auto) {
this.autoInclude = auto;
}
/**
* Get the HTTP status, or null
if none was explicitly set.
*
* @return HTTP status code associated with this resolution or null if none was set.
*/
public Integer getStatus() {
return status;
}
/**
* Explicitly sets an HTTP status code, in which case a call to
* {@code response.setStatus(status)} will be made when executing the
* resolution.
*
* @param status - HTTP status code to associated with this resolution.
* @return Current resolution object
*/
public ForwardResolution setStatus(int status) {
this.status = status;
return this;
}
/**
* Attempts to forward the user to the specified path.
*
* @throws ServletException thrown when the Servlet container encounters an
* error
* @throws IOException thrown when the Servlet container encounters an error
*/
public void execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (status != null) {
response.setStatus(status);
}
String path = getUrl(request.getLocale());
// Set event name as a request attribute
String oldEvent = (String) request.getAttribute(StripesConstants.REQ_ATTR_EVENT_NAME);
request.setAttribute(StripesConstants.REQ_ATTR_EVENT_NAME, event);
// are we asynchronous ?
AsyncResponse asyncResponse = AsyncResponse.get(request);
if (asyncResponse != null) {
// async started, dispatch...
log.trace("Async mode, dispatching to URL: ", path);
asyncResponse.dispatch(path);
} else {
// Figure out if we're inside an include, and use an include instead of a forward
if (autoInclude && request.getAttribute(StripesConstants.REQ_ATTR_INCLUDE_PATH) != null) {
log.trace("Including URL: ", path);
request.getRequestDispatcher(path).include(request, response);
} else {
log.trace("Forwarding to URL: ", path);
request.getRequestDispatcher(path).forward(request, response);
}
// Revert event name to its original value
request.setAttribute(StripesConstants.REQ_ATTR_EVENT_NAME, oldEvent);
}
}
}