001: /*
002: * $Id: ServletRedirectResult.java 501746 2007-01-31 06:22:43Z mrdon $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.dispatcher;
022:
023: import javax.servlet.http.HttpServletRequest;
024: import javax.servlet.http.HttpServletResponse;
025:
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028: import org.apache.struts2.ServletActionContext;
029: import org.apache.struts2.dispatcher.mapper.ActionMapper;
030: import org.apache.struts2.dispatcher.mapper.ActionMapping;
031:
032: import com.opensymphony.xwork2.ActionContext;
033: import com.opensymphony.xwork2.ActionInvocation;
034: import com.opensymphony.xwork2.inject.Inject;
035:
036: /**
037: * <!-- START SNIPPET: description -->
038: *
039: * Calls the {@link HttpServletResponse#sendRedirect(String) sendRedirect}
040: * method to the location specified. The response is told to redirect the
041: * browser to the specified location (a new request from the client). The
042: * consequence of doing this means that the action (action instance, action
043: * errors, field errors, etc) that was just executed is lost and no longer
044: * available. This is because actions are built on a single-thread model. The
045: * only way to pass data is through the session or with web parameters
046: * (url?name=value) which can be OGNL expressions.
047: *
048: * <!-- END SNIPPET: description -->
049: * <p/>
050: * <b>This result type takes the following parameters:</b>
051: *
052: * <!-- START SNIPPET: params -->
053: *
054: * <ul>
055: *
056: * <li><b>location (default)</b> - the location to go to after execution.</li>
057: *
058: * <li><b>parse</b> - true by default. If set to false, the location param will
059: * not be parsed for Ognl expressions.</li>
060: *
061: * </ul>
062: *
063: * <p>
064: * This result follows the same rules from {@link StrutsResultSupport}.
065: * </p>
066: *
067: * <!-- END SNIPPET: params -->
068: *
069: * <b>Example:</b>
070: *
071: * <pre><!-- START SNIPPET: example -->
072: * <result name="success" type="redirect">
073: * <param name="location">foo.jsp</param>
074: * <param name="parse">false</param>
075: * </result>
076: * <!-- END SNIPPET: example --></pre>
077: *
078: */
079: public class ServletRedirectResult extends StrutsResultSupport {
080:
081: private static final long serialVersionUID = 6316947346435301270L;
082:
083: private static final Log log = LogFactory
084: .getLog(ServletRedirectResult.class);
085:
086: protected boolean prependServletContext = true;
087:
088: protected ActionMapper actionMapper;
089:
090: public ServletRedirectResult() {
091: super ();
092: }
093:
094: public ServletRedirectResult(String location) {
095: super (location);
096: }
097:
098: @Inject
099: public void setActionMapper(ActionMapper mapper) {
100: this .actionMapper = mapper;
101: }
102:
103: /**
104: * Sets whether or not to prepend the servlet context path to the redirected URL.
105: *
106: * @param prependServletContext <tt>true</tt> to prepend the location with the servlet context path,
107: * <tt>false</tt> otherwise.
108: */
109: public void setPrependServletContext(boolean prependServletContext) {
110: this .prependServletContext = prependServletContext;
111: }
112:
113: /**
114: * Redirects to the location specified by calling {@link HttpServletResponse#sendRedirect(String)}.
115: *
116: * @param finalLocation the location to redirect to.
117: * @param invocation an encapsulation of the action execution state.
118: * @throws Exception if an error occurs when redirecting.
119: */
120: protected void doExecute(String finalLocation,
121: ActionInvocation invocation) throws Exception {
122: ActionContext ctx = invocation.getInvocationContext();
123: HttpServletRequest request = (HttpServletRequest) ctx
124: .get(ServletActionContext.HTTP_REQUEST);
125: HttpServletResponse response = (HttpServletResponse) ctx
126: .get(ServletActionContext.HTTP_RESPONSE);
127:
128: if (isPathUrl(finalLocation)) {
129: if (!finalLocation.startsWith("/")) {
130: ActionMapping mapping = actionMapper.getMapping(
131: request, Dispatcher.getInstance()
132: .getConfigurationManager());
133: String namespace = null;
134: if (mapping != null) {
135: namespace = mapping.getNamespace();
136: }
137:
138: if ((namespace != null) && (namespace.length() > 0)
139: && (!"/".equals(namespace))) {
140: finalLocation = namespace + "/" + finalLocation;
141: } else {
142: finalLocation = "/" + finalLocation;
143: }
144: }
145:
146: // if the URL's are relative to the servlet context, append the servlet context path
147: if (prependServletContext
148: && (request.getContextPath() != null)
149: && (request.getContextPath().length() > 0)) {
150: finalLocation = request.getContextPath()
151: + finalLocation;
152: }
153:
154: finalLocation = response.encodeRedirectURL(finalLocation);
155: }
156:
157: if (log.isDebugEnabled()) {
158: log.debug("Redirecting to finalLocation " + finalLocation);
159: }
160:
161: response.sendRedirect(finalLocation);
162: }
163:
164: private static boolean isPathUrl(String url) {
165: // filter out "http:", "https:", "mailto:", "file:", "ftp:"
166: // since the only valid places for : in URL's is before the path specification
167: // either before the port, or after the protocol
168: return (url.indexOf(':') == -1);
169: }
170: }
|