⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 requestdispatcherimpl.java

📁 低版本的tomcat 对于有些老版本的应用还真的需要老版的中间件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	}

	// Here the spec is very special, pay attention

	// We need to pass the original request, with all the paths -
	// and the new paths in special attributes.

	// We still need to find out where do we want to go ( today )
	// That means we create a subRequest with the new paths ( since
	// the mapping and aliasing is done on Requests), and run it
	// through prepare.

	// That also means that some special cases ( like the invoker !! )
	// will have to pay attention to the attributes, or we'll get a loop

	Request subRequest=context.getContextManager().
	    createRequest( context, path );
	subRequest.setParent( realRequest );
	subRequest.getTop(); // control inclusion depth
	
	// I hope no interceptor (or code) in processRequest use any
	// of the original request info ( like Auth headers )
	//
	// XXX We need to clone the request, so that processRequest can
	// make an informed mapping ( Auth, Authorization, etc)
	//
	// This will never work corectly unless we do a full clone - but
	// for simple cases ( no auth, etc) it does

	// note that we also need a dummy response - SessionInterceptors may
	// change something !
	subRequest.setResponse( realResponse );
	
	context.getContextManager().processRequest(subRequest);
	// Now subRequest containse the processed and aliased paths, plus
	// the wrapper that will handle the request.

	// We will use the stack a bit - save all path attributes, set the
	// new values, and after return from wrapper revert to the original
	Object old_request_uri=realRequest.
	    getAttribute("javax.servlet.include.request_uri");
	realRequest.setAttribute("javax.servlet.include.request_uri",
				 //				 path);
				 context.getPath() + path );

	Object old_context_path=realRequest.
	    getAttribute("javax.servlet.include.context_path");
	realRequest.setAttribute("javax.servlet.include.context_path",
				 context.getPath());
	// never change anyway - RD can't get out

	Object old_servlet_path=realRequest.
	    getAttribute("javax.servlet.include.servlet_path");
	realRequest.setAttribute("javax.servlet.include.servlet_path",
				 subRequest.getServletPath());
	
	Object old_path_info=realRequest.
	    getAttribute("javax.servlet.include.path_info");
	realRequest.setAttribute("javax.servlet.include.path_info",
				 subRequest.getPathInfo());

	Object old_query_string=realRequest.
	    getAttribute("javax.servlet.include.query_string");
	realRequest.setAttribute("javax.servlet.include.query_string",
				 queryString);
	
	
	// Not explicitely stated, but we need to save the old parameters
	// before adding the new ones
	realRequest.getParameterNames();
	// force reading of parameters from POST
	Hashtable old_parameters=(Hashtable)realRequest.getParameters().clone();

	// NOTE: it has a side effect of _reading_ the form data - which
	// is against the specs ( you can't read the post until asked for
	// parameters). I see no way of dealing with that -
	// if we don't do it and the included request need a parameter,
	// the form will be read and we'll have no way to know that.

	// IMHO the spec should do something about that - or smarter
	// people should implement the spec. ( costin )

	addQueryString( realRequest, queryString );

	Request old_child = realRequest.getChild();
	realRequest.setChild( subRequest );
	
 	// now it's really strange: we call the wrapper on the subrequest
	// for the realRequest ( since the real request will still have the
	// original handler/wrapper )
	ServletWrapper wr=subRequest.getWrapper();
	Throwable t = null;
	if( wr!=null ) {
	    try {
		wr.service(realRequest, realResponse);
	    } catch (Throwable t1) {
		t = t1;
	    }
	}

	// After request, we want to restore the include attributes - for
	// chained includes.
	realRequest.setChild( old_child );

	realRequest.setParameters( old_parameters);

	replaceAttribute( realRequest, "javax.servlet.include.request_uri",
				 old_request_uri);
	replaceAttribute( realRequest, "javax.servlet.include.context_path",
				 old_context_path); 
	replaceAttribute( realRequest, "javax.servlet.include.servlet_path",
				 old_servlet_path);
	replaceAttribute( realRequest, "javax.servlet.include.path_info",
				 old_path_info);
	replaceAttribute( realRequest, "javax.servlet.include.query_string",
				 old_query_string);
	// revert to the response behavior
	if( ! old_included ) {
	    realResponse.setIncluded( false );
	}

        // Rethrow any exception thrown by the included servlet
	if (t != null) {
	    if (t instanceof IOException)
		throw (IOException) t;
	    else if (t instanceof ServletException)
		throw (ServletException) t;
            else
                throw new ServletException
                    (sm.getString("dispatcher.includeException", t));
	}

    }

	

    /** Named dispatcher include
     *  Separate from normal include - which is still too messy
     */
    public void includeNamed(ServletRequest request, ServletResponse response)
	throws ServletException, IOException
    {

	// We got here if name!=null, so assert it
	ServletWrapper wrapper = context.getServletByName( name );

	// Use the original request - as in specification !
        Request realRequest = ((HttpServletRequestFacade)request).
	    getRealRequest();
	Response realResponse = realRequest.getResponse();

        // Set the "included" flag so that things like header setting in the
        // included servlet will be correctly ignored
	boolean old_included=realResponse.isIncluded();
	if( ! old_included ) {
	    realResponse.setIncluded( true );
	}

        // Call the included servlet
        Throwable t = null;
	if( wrapper!=null) {
            try {
                wrapper.service( realRequest, realRequest.getResponse());
            } catch (Throwable t1) {
                t = t1;
            }
        }

        // Clean up the request and response as needed
	if( ! old_included ) {
	    realResponse.setIncluded( false );
	}

        // Rethrow any exception thrown by the included servlet
	if (t != null) {
	    if (t instanceof IOException)
		throw (IOException) t;
	    else if (t instanceof ServletException)
		throw (ServletException) t;
            else
                throw new ServletException
                    (sm.getString("dispatcher.includeException", t));
	}

    }

    /** Named forward
     */
    public void forwardNamed(ServletRequest request, ServletResponse response)
	throws ServletException, IOException
    {

	// We got here if name!=null, so assert it
	ServletWrapper wrapper = context.getServletByName( name );

	// Use the original request - as in specification !
        Request realRequest = ((HttpServletRequestFacade)request).
	    getRealRequest();
	Response realResponse = realRequest.getResponse();

        // Call the forwarded-to servlet
        Throwable t = null;
	if( wrapper!=null) {
            try {
                wrapper.service( realRequest, realRequest.getResponse());
            } catch (Throwable t1) {
                t = t1;
            }
        }

        // Clean up the request and response as needed
        ;       // No action required

        // Rethrow any exception thrown by the forwarded-to servlet
	if (t != null) {
	    if (t instanceof IOException)
		throw (IOException) t;
	    else if (t instanceof ServletException)
		throw (ServletException) t;
            else
                throw new ServletException
                    (sm.getString("dispatcher.forwardException", t));
	}

    }    

    /**
     * Adds a query string to the existing set of parameters.
     * The additional parameters represented by the query string will be
     * merged with the existing parameters.
     * Used by the RequestDispatcherImpl to add query string parameters
     * to the request.
     *
     * @param inQueryString URLEncoded parameters to add
     */
    void addQueryString(Request req, String inQueryString) {
        // if query string is null, do nothing
        if ((inQueryString == null) || (inQueryString.trim().length() <= 0))
            return;

	Hashtable newParams = HttpUtils.parseQueryString(queryString);
	Hashtable parameters= req.getParameters();

	// add new to old ( it alters the original hashtable in request)
	Enumeration e=newParams.keys();
	while(e.hasMoreElements() ) {
	    String key=(String)e.nextElement();
	    Object oldValue = parameters.get(key);
	    Object newValue = newParams.get(key);
	    // The simple case -- no existing parameters with this name
	    if (oldValue == null) {
		parameters.put( key, newValue);
		continue;
	    }
	    // Construct arrays of the old and new values
	    String oldValues[] = null;
	    if (oldValue instanceof String[]) {
		oldValues = (String[]) oldValue;
	    } else if (oldValue instanceof String) {
		oldValues = new String[1];
		oldValues[0] = (String) oldValue;
	    } else {
		// Can not happen?
		oldValues = new String[1];
		oldValues[0] = oldValue.toString();
	    }
	    String newValues[] = null;
	    if (newValue instanceof String[]) {
		newValues = (String[]) newValue;
	    } else if (newValue instanceof String) {
		newValues = new String[1];
		newValues[0] = (String) newValue;
	    } else {
		// Can not happen?
		newValues = new String[1];
		newValues[0] = newValue.toString();
	    }
	    // Merge the two sets of values into a new array
	    String mergedValues[] =
		new String[newValues.length + oldValues.length];
	    for (int i = 0; i < newValues.length; i++)
		mergedValues[i] = newValues[i];	// New values first per spec
	    for (int i = newValues.length; i < mergedValues.length; i++)
		mergedValues[i] = oldValues[i - newValues.length];
	    // Save the merged values list in the original request
	    parameters.put(key, mergedValues);
	}
    }

    /** Restore attribute - if value is null, remove the attribute.
     *  X Maybe it should be the befavior of setAttribute() - it is not
     *  specified what to do with null.
     *  ( or it is - null means no value in getAttribute, so setting to
     *    null should mean setting to no value. ?)
     */
    private void replaceAttribute( Request realRequest, String name, Object value) {
	if( value == null )
	    realRequest.removeAttribute( name );
	else
	    realRequest.setAttribute( name, value );
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -