📄 requestdispatcherimpl.java
字号:
// 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 + -