View Javadoc

    1   /*
    2    * $Id: ServletDispatcherResult.java 471756 2006-11-06 15:01:43Z husted $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  package org.apache.struts2.dispatcher;
    22
    23  import javax.servlet.RequestDispatcher;
    24  import javax.servlet.http.HttpServletRequest;
    25  import javax.servlet.http.HttpServletResponse;
    26  import javax.servlet.jsp.PageContext;
    27
    28  import org.apache.commons.logging.Log;
    29  import org.apache.commons.logging.LogFactory;
    30  import org.apache.struts2.ServletActionContext;
    31
    32  import com.opensymphony.xwork2.ActionInvocation;
    33
    34
    35  /***
    36   * <!-- START SNIPPET: description -->
    37   *
    38   * Includes or forwards to a view (usually a jsp). Behind the scenes Struts
    39   * will use a RequestDispatcher, where the target servlet/JSP receives the same
    40   * request/response objects as the original servlet/JSP. Therefore, you can pass
    41   * data between them using request.setAttribute() - the Struts action is
    42   * available.
    43   * <p/>
    44   * There are three possible ways the result can be executed:
    45   *
    46   * <ul>
    47   *
    48   * <li>If we are in the scope of a JSP (a PageContext is available), PageContext's
    49   * {@link PageContext#include(String) include} method is called.</li>
    50   *
    51   * <li>If there is no PageContext and we're not in any sort of include (there is no
    52   * "javax.servlet.include.servlet_path" in the request attributes), then a call to
    53   * {@link RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) forward}
    54   * is made.</li>
    55   *
    56   * <li>Otherwise, {@link RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) include}
    57   * is called.</li>
    58   *
    59   * </ul>
    60   * <!-- END SNIPPET: description -->
    61   *
    62   * <b>This result type takes the following parameters:</b>
    63   *
    64   * <!-- START SNIPPET: params -->
    65   *
    66   * <ul>
    67   *
    68   * <li><b>location (default)</b> - the location to go to after execution (ex. jsp).</li>
    69   *
    70   * <li><b>parse</b> - true by default. If set to false, the location param will not be parsed for Ognl expressions.</li>
    71   *
    72   * </ul>
    73   *
    74   * <!-- END SNIPPET: params -->
    75   *
    76   * <b>Example:</b>
    77   *
    78   * <pre><!-- START SNIPPET: example -->
    79   * &lt;result name="success" type="dispatcher"&gt;
    80   *   &lt;param name="location"&gt;foo.jsp&lt;/param&gt;
    81   * &lt;/result&gt;
    82   * <!-- END SNIPPET: example --></pre>
    83   *
    84   * This result follows the same rules from {@link StrutsResultSupport}.
    85   *
    86   * @see javax.servlet.RequestDispatcher
    87   */
    88  public class ServletDispatcherResult extends StrutsResultSupport {
    89
    90      private static final long serialVersionUID = -1970659272360685627L;
    91
    92      private static final Log log = LogFactory.getLog(ServletDispatcherResult.class);
    93
    94      public ServletDispatcherResult() {
    95          super();
    96      }
    97
    98      public ServletDispatcherResult(String location) {
    99          super(location);
    100     }
    101
    102     /***
    103      * Dispatches to the given location. Does its forward via a RequestDispatcher. If the
    104      * dispatch fails a 404 error will be sent back in the http response.
    105      *
    106      * @param finalLocation the location to dispatch to.
    107      * @param invocation    the execution state of the action
    108      * @throws Exception if an error occurs. If the dispatch fails the error will go back via the
    109      *                   HTTP request.
    110      */
    111     public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
    112         if (log.isDebugEnabled()) {
    113             log.debug("Forwarding to location " + finalLocation);
    114         }
    115
    116         PageContext pageContext = ServletActionContext.getPageContext();
    117
    118         if (pageContext != null) {
    119             pageContext.include(finalLocation);
    120         } else {
    121             HttpServletRequest request = ServletActionContext.getRequest();
    122             HttpServletResponse response = ServletActionContext.getResponse();
    123             RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
    124
    125             // if the view doesn't exist, let's do a 404
    126             if (dispatcher == null) {
    127                 response.sendError(404, "result '" + finalLocation + "' not found");
    128
    129                 return;
    130             }
    131
    132             // If we're included, then include the view
    133             // Otherwise do forward
    134             // This allow the page to, for example, set content type
    135             if (!response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) {
    136                 request.setAttribute("struts.view_uri", finalLocation);
    137                 request.setAttribute("struts.request_uri", request.getRequestURI());
    138
    139                 dispatcher.forward(request, response);
    140             } else {
    141                 dispatcher.include(request, response);
    142             }
    143         }
    144     }
    145 }