📄 servlethandler.java
字号:
// ========================================================================// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.// ------------------------------------------------------------------------// 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.mortbay.jetty.servlet;import java.io.IOException;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.RequestDispatcher;import javax.servlet.Servlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.ServletResponse;import javax.servlet.UnavailableException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.mortbay.jetty.EofException;import org.mortbay.jetty.HttpConnection;import org.mortbay.jetty.HttpException;import org.mortbay.jetty.Request;import org.mortbay.jetty.RetryRequest;import org.mortbay.jetty.Server;import org.mortbay.jetty.handler.AbstractHandler;import org.mortbay.jetty.handler.ContextHandler;import org.mortbay.log.Log;import org.mortbay.util.LazyList;import org.mortbay.util.MultiException;import org.mortbay.util.MultiMap;import org.mortbay.util.URIUtil;/* --------------------------------------------------------------------- *//** Servlet HttpHandler. * This handler maps requests to servlets that implement the * javax.servlet.http.HttpServlet API. * <P> * This handler does not implement the full J2EE features and is intended to * be used when a full web application is not required. Specifically filters * and request wrapping are not supported. * * Unless run as part of a {@link Context} or derivative, the {@link #initialize()} * method must be called manually after start(). * * @see org.mortbay.jetty.webapp.WebAppContext * @author Greg Wilkins */public class ServletHandler extends AbstractHandler{ /* ------------------------------------------------------------ */ public static final String __DEFAULT_SERVLET="default"; public static final String __J_S_CONTEXT_TEMPDIR="javax.servlet.context.tempdir"; public static final String __J_S_ERROR_EXCEPTION="javax.servlet.error.exception"; public static final String __J_S_ERROR_EXCEPTION_TYPE="javax.servlet.error.exception_type"; public static final String __J_S_ERROR_MESSAGE="javax.servlet.error.message"; public static final String __J_S_ERROR_REQUEST_URI="javax.servlet.error.request_uri"; public static final String __J_S_ERROR_SERVLET_NAME="javax.servlet.error.servlet_name"; public static final String __J_S_ERROR_STATUS_CODE="javax.servlet.error.status_code"; /* ------------------------------------------------------------ */ private ContextHandler _contextHandler; private ContextHandler.SContext _servletContext; private FilterHolder[] _filters; private FilterMapping[] _filterMappings; private boolean _filterChainsCached=true; private int _maxFilterChainsCacheSize=1000; private boolean _startWithUnavailable=true; private ServletHolder[] _servlets; private ServletMapping[] _servletMappings; private transient Map _filterNameMap= new HashMap(); private transient List _filterPathMappings; private transient MultiMap _filterNameMappings; private transient Map _servletNameMap=new HashMap(); private transient PathMap _servletPathMap; protected transient HashMap _chainCache[]; /* ------------------------------------------------------------ */ /** Constructor. */ public ServletHandler() { } /* ------------------------------------------------------------ */ /* * @see org.mortbay.jetty.handler.AbstractHandler#setServer(org.mortbay.jetty.Server) */ public void setServer(Server server) { if (getServer()!=null && getServer()!=server) { getServer().getContainer().update(this, _filters, null, "filter",true); getServer().getContainer().update(this, _filterMappings, null, "filterMapping",true); getServer().getContainer().update(this, _servlets, null, "servlet",true); getServer().getContainer().update(this, _servletMappings, null, "servletMapping",true); } if (server!=null && getServer()!=server) { server.getContainer().update(this, null, _filters, "filter",true); server.getContainer().update(this, null, _filterMappings, "filterMapping",true); server.getContainer().update(this, null, _servlets, "servlet",true); server.getContainer().update(this, null, _servletMappings, "servletMapping",true); } super.setServer(server); } /* ----------------------------------------------------------------- */ protected synchronized void doStart() throws Exception { _servletContext=ContextHandler.getCurrentContext(); _contextHandler=_servletContext==null?null:_servletContext.getContextHandler(); updateNameMappings(); updateMappings(); if(_filterChainsCached) _chainCache= new HashMap[]{null,new HashMap(),new HashMap(),null,new HashMap(),null,null,null,new HashMap()}; super.doStart(); if (_contextHandler==null || !(_contextHandler instanceof Context)) initialize(); } /* ----------------------------------------------------------------- */ protected synchronized void doStop() throws Exception { super.doStop(); // Stop filters if (_filters!=null) { for (int i=_filters.length; i-->0;) { try { _filters[i].stop(); }catch(Exception e){Log.warn(Log.EXCEPTION,e);} } } // Stop servlets if (_servlets!=null) { for (int i=_servlets.length; i-->0;) { try { _servlets[i].stop(); }catch(Exception e){Log.warn(Log.EXCEPTION,e);} } } _filterPathMappings=null; _filterNameMappings=null; _servletPathMap=null; _chainCache=null; } /* ------------------------------------------------------------ */ /** * @return Returns the contextLog. */ public Object getContextLog() { return null; } /* ------------------------------------------------------------ */ /** * @return Returns the filterMappings. */ public FilterMapping[] getFilterMappings() { return _filterMappings; } /* ------------------------------------------------------------ */ /** Get Filters. * @return Array of defined servlets */ public FilterHolder[] getFilters() { return _filters; } /* ------------------------------------------------------------ */ /** ServletHolder matching path. * @param pathInContext Path within _context. * @return PathMap Entries pathspec to ServletHolder */ public PathMap.Entry getHolderEntry(String pathInContext) { if (_servletPathMap==null) return null; return _servletPathMap.getMatch(pathInContext); } /* ------------------------------------------------------------ */ /** Whether there is a ServletHolder that matches this path * @param pathInContext Path within _context. * @return whether there is a ServletHolder that matches this path */ public boolean matchesPath(String pathInContext) { return _servletPathMap.containsMatch(pathInContext); } /* ------------------------------------------------------------ */ /** * @return A {@link RequestDispatcher dispatcher} wrapping the resource at <code>uriInContext</code>, * or <code>null</code> if the specified uri cannot be dispatched to. */ public RequestDispatcher getRequestDispatcher(String uriInContext) { if (uriInContext == null) return null; if (!uriInContext.startsWith("/")) return null; try { String query=null; int q=0; if ((q=uriInContext.indexOf('?'))>0) { query=uriInContext.substring(q+1); uriInContext=uriInContext.substring(0,q); } if ((q=uriInContext.indexOf(';'))>0) uriInContext=uriInContext.substring(0,q); String pathInContext=URIUtil.canonicalPath(URIUtil.decodePath(uriInContext)); String uri=URIUtil.addPaths(_contextHandler.getContextPath(), uriInContext); return new Dispatcher(_contextHandler, uri, pathInContext, query); } catch(Exception e) { Log.ignore(e); } return null; } /* ------------------------------------------------------------ */ public ServletContext getServletContext() { return _servletContext; } /* ------------------------------------------------------------ */ /** * @return Returns the servletMappings. */ public ServletMapping[] getServletMappings() { return _servletMappings; } /* ------------------------------------------------------------ */ /** Get Servlets. * @return Array of defined servlets */ public ServletHolder[] getServlets() { return _servlets; } /* ------------------------------------------------------------ */ public ServletHolder getServlet(String name) { return (ServletHolder)_servletNameMap.get(name); } /* ------------------------------------------------------------ */ /* * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) */ public void handle(String target, HttpServletRequest request,HttpServletResponse response, int type) throws IOException, ServletException { if (!isStarted()) return; // Get the base requests final Request base_request=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest(); final String old_servlet_name=base_request.getServletName(); final String old_servlet_path=base_request.getServletPath(); final String old_path_info=base_request.getPathInfo(); final Map old_role_map=base_request.getRoleMap(); Object request_listeners=null; ServletRequestEvent request_event=null; try { ServletHolder servlet_holder=null; FilterChain chain=null; // find the servlet if (target.startsWith("/")) { // Look for the servlet by path PathMap.Entry entry=getHolderEntry(target); if (entry!=null) { servlet_holder=(ServletHolder)entry.getValue(); base_request.setServletName(servlet_holder.getName()); base_request.setRoleMap(servlet_holder.getRoleMap()); if(Log.isDebugEnabled())Log.debug("servlet="+servlet_holder); String servlet_path_spec=(String)entry.getKey(); String servlet_path=entry.getMapped()!=null?entry.getMapped():PathMap.pathMatch(servlet_path_spec,target); String path_info=PathMap.pathInfo(servlet_path_spec,target); if (type==INCLUDE) { base_request.setAttribute(Dispatcher.__INCLUDE_SERVLET_PATH,servlet_path); base_request.setAttribute(Dispatcher.__INCLUDE_PATH_INFO, path_info); } else { base_request.setServletPath(servlet_path); base_request.setPathInfo(path_info); } if (servlet_holder!=null && _filterMappings!=null && _filterMappings.length>0) chain=getFilterChain(type, target, servlet_holder); } } else { // look for a servlet by name! servlet_holder=(ServletHolder)_servletNameMap.get(target); if (servlet_holder!=null && _filterMappings!=null && _filterMappings.length>0) { base_request.setServletName(servlet_holder.getName()); chain=getFilterChain(type, null,servlet_holder); } } if (Log.isDebugEnabled()) { Log.debug("chain="+chain); Log.debug("servlet holder="+servlet_holder); } // Handle context listeners request_listeners = base_request.takeRequestListeners(); if (request_listeners!=null) { request_event = new ServletRequestEvent(getServletContext(),request); final int s=LazyList.size(request_listeners); for(int i=0;i<s;i++) { final ServletRequestListener listener = (ServletRequestListener)LazyList.get(request_listeners,i); listener.requestInitialized(request_event); } } // Do the filter/handling thang if (servlet_holder!=null) { base_request.setHandled(true); if (chain!=null) chain.doFilter(request, response); else servlet_holder.handle(request,response); } else notFound(request, response); } catch(RetryRequest e) { base_request.setHandled(false); throw e; } catch(EofException e) { throw e; } catch(Exception e) { if (type!=REQUEST) { if (e instanceof IOException) throw (IOException)e; if (e instanceof RuntimeException) throw (RuntimeException)e; if (e instanceof ServletException) throw (ServletException)e; } // unwrap cause Throwable th=e; if (th instanceof UnavailableException) { Log.debug(th); } else if (th instanceof ServletException) { Log.debug(th); Throwable cause=((ServletException)th).getRootCause(); if (cause!=th && cause!=null) th=cause; } // hnndle or log exception if (th instanceof RetryRequest) { base_request.setHandled(false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -