View Javadoc

1   /*
2    * $Id: ServletRedirectResult.java 462586 2006-10-10 21:35:35Z mrdon $
3    *
4    * Copyright 2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.struts2.dispatcher;
19  
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.struts2.ServletActionContext;
26  import org.apache.struts2.dispatcher.mapper.ActionMapperFactory;
27  
28  import com.opensymphony.xwork2.ActionContext;
29  import com.opensymphony.xwork2.ActionInvocation;
30  
31  
32  /***
33   * <!-- START SNIPPET: description -->
34   *
35   * Calls the {@link HttpServletResponse#sendRedirect(String) sendRedirect}
36   * method to the location specified. The response is told to redirect the
37   * browser to the specified location (a new request from the client). The
38   * consequence of doing this means that the action (action instance, action
39   * errors, field errors, etc) that was just executed is lost and no longer
40   * available. This is because actions are built on a single-thread model. The
41   * only way to pass data is through the session or with web parameters
42   * (url?name=value) which can be OGNL expressions.
43   *
44   * <!-- END SNIPPET: description -->
45   * <p/>
46   * <b>This result type takes the following parameters:</b>
47   *
48   * <!-- START SNIPPET: params -->
49   *
50   * <ul>
51   *
52   * <li><b>location (default)</b> - the location to go to after execution.</li>
53   *
54   * <li><b>parse</b> - true by default. If set to false, the location param will 
55   * not be parsed for Ognl expressions.</li>
56   *
57   * </ul>
58   *
59   * <p>
60   * This result follows the same rules from {@link StrutsResultSupport}.
61   * </p>
62   *
63   * <!-- END SNIPPET: params -->
64   *
65   * <b>Example:</b>
66   *
67   * <pre><!-- START SNIPPET: example -->
68   * &lt;result name="success" type="redirect"&gt;
69   *   &lt;param name="location"&gt;foo.jsp&lt;/param&gt;
70   *   &lt;param name="parse"&gt;false&lt;/param&gt;
71   * &lt;/result&gt;
72   * <!-- END SNIPPET: example --></pre>
73   *
74   */
75  public class ServletRedirectResult extends StrutsResultSupport {
76  	
77  	private static final long serialVersionUID = 6316947346435301270L;
78  
79  	private static final Log log = LogFactory.getLog(ServletRedirectResult.class);
80  
81      protected boolean prependServletContext = true;
82  
83      public ServletRedirectResult() {
84      	super();
85      }
86      
87      public ServletRedirectResult(String location) {
88      	super(location);
89      }
90      
91      /***
92       * Sets whether or not to prepend the servlet context path to the redirected URL.
93       *
94       * @param prependServletContext <tt>true</tt> to prepend the location with the servlet context path,
95       *                              <tt>false</tt> otherwise.
96       */
97      public void setPrependServletContext(boolean prependServletContext) {
98          this.prependServletContext = prependServletContext;
99      }
100 
101     /***
102      * Redirects to the location specified by calling {@link HttpServletResponse#sendRedirect(String)}.
103      *
104      * @param finalLocation the location to redirect to.
105      * @param invocation    an encapsulation of the action execution state.
106      * @throws Exception if an error occurs when redirecting.
107      */
108     protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
109         ActionContext ctx = invocation.getInvocationContext();
110         HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
111         HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
112 
113         if (isPathUrl(finalLocation)) {
114             if (!finalLocation.startsWith("/")) {
115                 String namespace = ActionMapperFactory.getMapper().getMapping(
116                         request, Dispatcher.getInstance().getConfigurationManager()).getNamespace();
117 
118                 if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace))) {
119                     finalLocation = namespace + "/" + finalLocation;
120                 } else {
121                     finalLocation = "/" + finalLocation;
122                 }
123             }
124 
125             // if the URL's are relative to the servlet context, append the servlet context path
126             if (prependServletContext && (request.getContextPath() != null) && (request.getContextPath().length() > 0)) {
127                 finalLocation = request.getContextPath() + finalLocation;
128             }
129 
130             finalLocation = response.encodeRedirectURL(finalLocation);
131         }
132 
133         if (log.isDebugEnabled()) {
134             log.debug("Redirecting to finalLocation " + finalLocation);
135         }
136 
137         response.sendRedirect(finalLocation);
138     }
139 
140     private static boolean isPathUrl(String url) {
141         // filter out "http:", "https:", "mailto:", "file:", "ftp:"
142         // since the only valid places for : in URL's is before the path specification
143         // either before the port, or after the protocol
144         return (url.indexOf(':') == -1);
145     }
146 }