|
Glassfish example source code file (ApplicationDispatcher.java)
The Glassfish ApplicationDispatcher.java source code/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2004 The Apache Software Foundation
*
* 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 org.apache.catalina.core;
import org.apache.catalina.*;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.catalina.connector.ResponseFacade;
import org.apache.catalina.util.InstanceSupport;
import org.apache.catalina.util.StringManager;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.apache.catalina.InstanceEvent.EventType.AFTER_DISPATCH_EVENT;
/**
* Standard implementation of <code>RequestDispatcher that allows a
* request to be forwarded to a different resource to create the ultimate
* response, or to include the output of another resource in the response
* from this resource. This implementation allows application level servlets
* to wrap the request and/or response objects that are passed on to the
* called resource, as long as the wrapping classes extend
* <code>javax.servlet.ServletRequestWrapper and
* <code>javax.servlet.ServletResponseWrapper.
*
* @author Craig R. McClanahan
* @version $Revision: 1.16 $ $Date: 2007/02/26 22:57:08 $
*/
public final class ApplicationDispatcher
implements RequestDispatcher {
protected class PrivilegedDispatch implements PrivilegedExceptionAction {
private ServletRequest request;
private ServletResponse response;
private DispatcherType dispatcherType;
PrivilegedDispatch(ServletRequest request, ServletResponse response,
DispatcherType dispatcherType) {
this.request = request;
this.response = response;
this.dispatcherType = dispatcherType;
}
public Object run() throws java.lang.Exception {
doDispatch(request, response, dispatcherType);
return null;
}
}
protected class PrivilegedInclude implements PrivilegedExceptionAction {
private ServletRequest request;
private ServletResponse response;
PrivilegedInclude(ServletRequest request, ServletResponse response) {
this.request = request;
this.response = response;
}
public Object run() throws ServletException, IOException {
doInclude(request,response);
return null;
}
}
/**
* Used to pass state when the request dispatcher is used. Using instance
* variables causes threading issues and state is too complex to pass and
* return single ServletRequest or ServletResponse objects.
*/
private class State {
// Outermost request that will be passed on to the invoked servlet
ServletRequest outerRequest = null;
// Outermost response that will be passed on to the invoked servlet.
ServletResponse outerResponse = null;
// Request wrapper we have created and installed (if any).
ServletRequest wrapRequest = null;
// Response wrapper we have created and installed (if any).
ServletResponse wrapResponse = null;
// The type of dispatch we are performing
DispatcherType dispatcherType;
State(ServletRequest request, ServletResponse response,
DispatcherType dispatcherType) {
this.outerRequest = request;
this.outerResponse = response;
this.dispatcherType = dispatcherType;
}
}
// ----------------------------------------------------------- Constructors
/**
* Construct a new instance of this class, configured according to the
* specified parameters. If both servletPath and pathInfo are
* <code>null, it will be assumed that this RequestDispatcher
* was acquired by name, rather than by path.
*
* @param wrapper The Wrapper associated with the resource that will
* be forwarded to or included (required)
* @param requestURI The request URI to this resource (if any)
* @param servletPath The revised servlet path to this resource (if any)
* @param pathInfo The revised extra path information to this resource
* (if any)
* @param queryString Query string parameters included with this request
* (if any)
* @param name Servlet name (if a named dispatcher was created)
* else <code>null
*/
public ApplicationDispatcher
(Wrapper wrapper, String requestURI, String servletPath,
String pathInfo, String queryString, String name) {
super();
// Save all of our configuration parameters
this.wrapper = wrapper;
this.context = (Context) wrapper.getParent();
this.requestURI = requestURI;
this.servletPath = servletPath;
this.pathInfo = pathInfo;
this.queryString = queryString;
this.name = name;
if (log.isLoggable(Level.FINE))
log.fine("servletPath=" + this.servletPath + ", pathInfo=" +
this.pathInfo + ", queryString=" + queryString +
", name=" + this.name);
}
// ----------------------------------------------------- Instance Variables
private static final Logger log = Logger.getLogger(
ApplicationDispatcher.class.getName());
//START OF 6364900
/**
* is this dispatch cross context
*/
private Boolean crossContextFlag = null;
//END OF 6364900
/**
* The Context this RequestDispatcher is associated with.
*/
private Context context = null;
/**
* The debugging detail level for this component.
*/
private int debug = 0;
/**
* Descriptive information about this implementation.
*/
private static final String info =
"org.apache.catalina.core.ApplicationDispatcher/1.0";
/**
* The servlet name for a named dispatcher.
*/
private String name = null;
/**
* The extra path information for this RequestDispatcher.
*/
private String pathInfo = null;
/**
* The query string parameters for this RequestDispatcher.
*/
private String queryString = null;
/**
* The request URI for this RequestDispatcher.
*/
private String requestURI = null;
/**
* The servlet path for this RequestDispatcher.
*/
private String servletPath = null;
/**
* The StringManager for this package.
*/
private static final StringManager sm =
StringManager.getManager(Constants.Package);
/**
* The Wrapper associated with the resource that will be forwarded to
* or included.
*/
private Wrapper wrapper = null;
// ------------------------------------------------------------- Properties
/**
* Return the descriptive information about this implementation.
*/
public String getInfo() {
return (this.info);
}
// --------------------------------------------------------- Public Methods
/**
* Forwards the given request and response to the resource
* for which this dispatcher was acquired.
*
* <p>Any runtime exceptions, IOException, or ServletException thrown
* by the target will be propagated to the caller.
*
* @param request The request to be forwarded
* @param response The response to be forwarded
*
* @throws IOException if an input/output error occurs
* @throws ServletException if a servlet exception occurs
*/
public void forward(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
dispatch(request, response, DispatcherType.FORWARD);
}
/**
* Dispatches the given request and response to the resource
* for which this dispatcher was acquired.
*
* <p>Any runtime exceptions, IOException, or ServletException thrown
* by the target will be propagated to the caller.
*
* @param request The request to be forwarded
* @param response The response to be forwarded
* @param dispatcherType The type of dispatch to be performed
*
* @throws IOException if an input/output error occurs
* @throws ServletException if a servlet exception occurs
* @throws IllegalArgumentException if the dispatcher type is different
* from FORWARD, ERROR, and ASYNC
*/
public void dispatch(ServletRequest request, ServletResponse response,
DispatcherType dispatcherType)
throws ServletException, IOException {
if (!DispatcherType.FORWARD.equals(dispatcherType) &&
!DispatcherType.ERROR.equals(dispatcherType) &&
!DispatcherType.ASYNC.equals(dispatcherType)) {
throw new IllegalArgumentException("Illegal dispatcher type");
}
boolean isCommit = (DispatcherType.FORWARD.equals(dispatcherType) ||
DispatcherType.ERROR.equals(dispatcherType));
if (Globals.IS_SECURITY_ENABLED) {
try {
PrivilegedDispatch dp = new PrivilegedDispatch(
request, response, dispatcherType);
AccessController.doPrivileged(dp);
// START SJSAS 6374990
if (isCommit) {
ApplicationDispatcherForward.commit(request, response,
context, wrapper);
}
// END SJSAS 6374990
} catch (PrivilegedActionException pe) {
Exception e = pe.getException();
if (e instanceof ServletException)
throw (ServletException) e;
throw (IOException) e;
}
} else {
doDispatch(request, response, dispatcherType);
// START SJSAS 6374990
if (isCommit) {
ApplicationDispatcherForward.commit(request, response,
context, wrapper);
}
// END SJSAS 6374990
}
}
private void doDispatch(ServletRequest request, ServletResponse response,
DispatcherType dispatcherType)
throws ServletException, IOException {
if (!DispatcherType.ASYNC.equals(dispatcherType)) {
// Reset any output that has been buffered, but keep
// headers/cookies
if (response.isCommitted()) {
if (log.isLoggable(Level.FINE))
log.fine(" Forward on committed response --> ISE");
throw new IllegalStateException
(sm.getString("applicationDispatcher.forward.ise"));
}
try {
response.resetBuffer();
} catch (IllegalStateException e) {
if (log.isLoggable(Level.FINE))
log.fine(" Forward resetBuffer() returned ISE: " + e);
throw e;
}
}
// Set up to handle the specified request and response
State state = new State(request, response, dispatcherType);
// Identify the HTTP-specific request and response objects (if any)
HttpServletRequest hrequest = null;
if (request instanceof HttpServletRequest) {
hrequest = (HttpServletRequest) request;
}
HttpServletResponse hresponse = null;
if (response instanceof HttpServletResponse) {
hresponse = (HttpServletResponse) response;
}
if ((hrequest == null) || (hresponse == null)) {
// Handle a non-HTTP forward
ApplicationHttpRequest wrequest = wrapRequest(state);
processRequest(request, response, state,
wrequest.getRequestFacade());
unwrapRequest(state);
} else if ((servletPath == null) && (pathInfo == null)) {
// Handle an HTTP named dispatcher forward
ApplicationHttpRequest wrequest = wrapRequest(state);
wrequest.setRequestURI(hrequest.getRequestURI());
wrequest.setContextPath(hrequest.getContextPath());
wrequest.setServletPath(hrequest.getServletPath());
wrequest.setPathInfo(hrequest.getPathInfo());
wrequest.setQueryString(hrequest.getQueryString());
processRequest(request, response, state,
wrequest.getRequestFacade());
wrequest.recycle();
unwrapRequest(state);
} else {
// Handle an HTTP path-based forward
ApplicationHttpRequest wrequest = wrapRequest(state);
// If the request is being FORWARD- or ASYNC-dispatched for
// the first time, initialize it with the required request
// attributes
if ((DispatcherType.FORWARD.equals(dispatcherType) &&
hrequest.getAttribute(
RequestDispatcher.FORWARD_REQUEST_URI) == null) ||
(DispatcherType.ASYNC.equals(dispatcherType) &&
hrequest.getAttribute(
AsyncContext.ASYNC_REQUEST_URI) == null)) {
wrequest.initSpecialAttributes(hrequest.getRequestURI(),
hrequest.getContextPath(),
hrequest.getServletPath(),
hrequest.getPathInfo(),
hrequest.getQueryString());
}
String targetContextPath = context.getPath();
// START IT 10395
RequestFacade requestFacade = wrequest.getRequestFacade();
String originContextPath = requestFacade.getContextPath(false);
if (originContextPath != null &&
originContextPath.equals(targetContextPath)) {
targetContextPath = hrequest.getContextPath();
}
// END IT 10395
wrequest.setContextPath(targetContextPath);
wrequest.setRequestURI(requestURI);
wrequest.setServletPath(servletPath);
wrequest.setPathInfo(pathInfo);
if (queryString != null) {
wrequest.setQueryString(queryString);
wrequest.setQueryParams(queryString);
}
processRequest(request, response, state,
wrequest.getRequestFacade());
wrequest.recycle();
unwrapRequest(state);
}
}
/**
* Prepare the request based on the filter configuration.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @throws IOException if an input/output error occurs
* @throws ServletException if a servlet error occurs
*/
private void processRequest(ServletRequest request,
ServletResponse response,
State state,
RequestFacade requestFacade)
throws IOException, ServletException {
if (request != null) {
if (state.dispatcherType != DispatcherType.ERROR) {
state.outerRequest.setAttribute(
Globals.DISPATCHER_REQUEST_PATH_ATTR,
getCombinedPath());
invoke(state.outerRequest, response, state, requestFacade);
} else {
invoke(state.outerRequest, response, state, requestFacade);
}
}
}
/**
* Combines the servletPath and the pathInfo.
*
* If pathInfo is <code>null, it is ignored. If servletPath
* is <code>null, then
Other Glassfish examples (source code examples)Here is a short list of links related to this Glassfish ApplicationDispatcher.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.