001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.dispatcher;
006:
007: import com.opensymphony.webwork.ServletActionContext;
008: import com.opensymphony.webwork.dispatcher.mapper.ActionMapperFactory;
009: import com.opensymphony.xwork.ActionContext;
010: import com.opensymphony.xwork.ActionInvocation;
011: import org.apache.commons.logging.Log;
012: import org.apache.commons.logging.LogFactory;
013:
014: import javax.servlet.http.HttpServletRequest;
015: import javax.servlet.http.HttpServletResponse;
016:
017: /**
018: * <!-- START SNIPPET: description -->
019: *
020: * Calls the {@link HttpServletResponse#sendRedirect(String) sendRedirect}
021: * method to the location specified. The response is told to redirect the
022: * browser to the specified location (a new request from the client). The
023: * consequence of doing this means that the action (action instance, action
024: * errors, field errors, etc) that was just executed is lost and no longer
025: * available. This is because actions are built on a single-thread model. The
026: * only way to pass data is through the session or with web parameters
027: * (url?name=value) which can be OGNL expressions.
028: *
029: * <!-- END SNIPPET: description -->
030: * <p/>
031: * <b>This result type takes the following parameters:</b>
032: *
033: * <!-- START SNIPPET: params -->
034: *
035: * <ul>
036: *
037: * <li><b>location (default)</b> - the location to go to after execution.</li>
038: *
039: * <li><b>parse</b> - true by default. If set to false, the location param will
040: * not be parsed for Ognl expressions.</li>
041: *
042: * </ul>
043: *
044: * <p>
045: * This result follows the same rules from {@link WebWorkResultSupport}.
046: * </p>
047: *
048: * <!-- END SNIPPET: params -->
049: *
050: * <b>Example:</b>
051: *
052: * <pre><!-- START SNIPPET: example -->
053: * <result name="success" type="redirect">
054: * <param name="location">foo.jsp</param>
055: * <param name="parse">false</param>
056: * </result>
057: * <!-- END SNIPPET: example --></pre>
058: *
059: * @author Patrick Lightbody
060: */
061: public class ServletRedirectResult extends WebWorkResultSupport {
062:
063: private static final long serialVersionUID = -4787182693920514194L;
064:
065: private static final Log log = LogFactory
066: .getLog(ServletRedirectResult.class);
067:
068: protected boolean prependServletContext = true;
069:
070: /**
071: * Sets whether or not to prepend the servlet context path to the redirected URL.
072: *
073: * @param prependServletContext <tt>true</tt> to prepend the location with the servlet context path,
074: * <tt>false</tt> otherwise.
075: */
076: public void setPrependServletContext(boolean prependServletContext) {
077: this .prependServletContext = prependServletContext;
078: }
079:
080: /**
081: * Redirects to the location specified by calling {@link HttpServletResponse#sendRedirect(String)}.
082: *
083: * @param finalLocation the location to redirect to.
084: * @param invocation an encapsulation of the action execution state.
085: * @throws Exception if an error occurs when redirecting.
086: */
087: protected void doExecute(String finalLocation,
088: ActionInvocation invocation) throws Exception {
089: ActionContext ctx = invocation.getInvocationContext();
090: HttpServletRequest request = (HttpServletRequest) ctx
091: .get(ServletActionContext.HTTP_REQUEST);
092: HttpServletResponse response = (HttpServletResponse) ctx
093: .get(ServletActionContext.HTTP_RESPONSE);
094:
095: if (isPathUrl(finalLocation)) {
096: if (!finalLocation.startsWith("/")) {
097: String namespace = ActionMapperFactory.getMapper()
098: .getMapping(request).getNamespace();
099:
100: if ((namespace != null) && (namespace.length() > 0)
101: && (!"/".equals(namespace))) {
102: finalLocation = namespace + "/" + finalLocation;
103: } else {
104: finalLocation = "/" + finalLocation;
105: }
106: }
107:
108: // if the URL's are relative to the servlet context, append the servlet context path
109: if (prependServletContext
110: && (request.getContextPath() != null)
111: && (request.getContextPath().length() > 0)) {
112: finalLocation = request.getContextPath()
113: + finalLocation;
114: }
115:
116: finalLocation = response.encodeRedirectURL(finalLocation);
117: }
118:
119: if (log.isDebugEnabled()) {
120: log.debug("Redirecting to finalLocation " + finalLocation);
121: }
122:
123: response.sendRedirect(finalLocation);
124: }
125:
126: private static boolean isPathUrl(String url) {
127: // filter out "http:", "https:", "mailto:", "file:", "ftp:"
128: // since the only valid places for : in URL's is before the path specification
129: // either before the port, or after the protocol
130: return (url.indexOf(':') == -1);
131: }
132: }
|