servletmapper.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 483 行
JAVA
483 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.server.dispatch;import com.caucho.config.*;import com.caucho.make.DependencyContainer;import com.caucho.server.webapp.WebApp;import com.caucho.util.L10N;import com.caucho.vfs.Depend;import com.caucho.vfs.Path;import javax.servlet.FilterChain;import javax.servlet.ServletContext;import javax.servlet.ServletException;import java.io.InputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.logging.Level;import java.util.logging.Logger;/** * Manages dispatching: servlets and filters. */public class ServletMapper { static final Logger log = Logger.getLogger(ServletMapper.class.getName()); static final L10N L = new L10N(ServletMapper.class); private ServletContext _servletContext; private ServletManager _servletManager; private UrlMap<String> _servletMap = new UrlMap<String>(); private ArrayList<String> _welcomeFileList = new ArrayList<String>(); private HashMap<String,ServletMapping> _regexpMap = new HashMap<String,ServletMapping>(); private ArrayList<String> _ignorePatterns = new ArrayList<String>(); private String _defaultServlet; /** * Sets the servlet context. */ public void setServletContext(ServletContext servletContext) { _servletContext = servletContext; } /** * Gets the servlet context. */ public ServletContext getServletContext() { return _servletContext; } /** * Returns the servlet manager. */ public ServletManager getServletManager() { return _servletManager; } /** * Sets the servlet manager. */ public void setServletManager(ServletManager manager) { _servletManager = manager; } /** * Adds a servlet mapping */ public void addUrlRegexp(String regexp, ServletMapping mapping) throws ServletException { _servletMap.addRegexp(regexp, regexp); _regexpMap.put(regexp, mapping); } /** * Adds a servlet mapping */ void addUrlMapping(String urlPattern, String servletName, ServletMapping mapping) throws ServletException { try { if (servletName == null) { throw new ConfigException(L.l("servlets need a servlet-name.")); } else if (servletName.equals("invoker")) { // special case } else if (servletName.equals("plugin_match") || servletName.equals("plugin-match")) { // special case } else if (servletName.equals("plugin_ignore") || servletName.equals("plugin-ignore")) { if (urlPattern != null) _ignorePatterns.add(urlPattern); return; } else if (_servletManager.getServlet(servletName) == null) throw new ConfigException(L.l("'{0}' is an unknown servlet-name. servlet-mapping requires that the named servlet be defined in a <servlet> configuration before the <servlet-mapping>.", servletName)); if ("/".equals(urlPattern)) { _defaultServlet = servletName; } else if (mapping.isStrictMapping()) { _servletMap.addStrictMap(urlPattern, null, servletName); } else _servletMap.addMap(urlPattern, servletName); log.config("servlet-mapping " + urlPattern + " -> " + servletName); } catch (ServletException e) { throw e; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw ConfigException.create(e); } } /** * Sets the default servlet. */ public void setDefaultServlet(String servletName) throws ServletException { _defaultServlet = servletName; } /** * Adds a welcome-file */ public void addWelcomeFile(String fileName) { ArrayList<String> welcomeFileList = new ArrayList<String>(_welcomeFileList); welcomeFileList.add(fileName); _welcomeFileList = welcomeFileList; } /** * Sets the welcome-file list */ public void setWelcomeFileList(ArrayList<String> list) { _welcomeFileList = new ArrayList<String>(list); } public FilterChain mapServlet(ServletInvocation invocation) throws ServletException { String contextURI = invocation.getContextURI(); String servletName = null; ArrayList<String> vars = new ArrayList<String>(); invocation.setClassLoader(Thread.currentThread().getContextClassLoader()); if (_servletMap != null) { servletName = _servletMap.map(contextURI, vars); ServletMapping servletRegexp = _regexpMap.get(servletName); if (servletRegexp != null) { servletName = servletRegexp.initRegexp(_servletContext, _servletManager, vars); } } if (servletName == null) { try { InputStream is; is = _servletContext.getResourceAsStream(contextURI); if (is != null) { is.close(); servletName = _defaultServlet; } } catch (Exception e) { } } if (servletName == null) { ArrayList<String> welcomeFileList = _welcomeFileList; int size = welcomeFileList.size(); for (int i = 0; i < size; i++) { String file = welcomeFileList.get(i); try { String welcomeURI; if (contextURI.endsWith("/")) welcomeURI = contextURI + file; else welcomeURI = contextURI + '/' + file; InputStream is; is = _servletContext.getResourceAsStream(welcomeURI); if (is != null) is.close(); if (is == null) { } else if (! contextURI.endsWith("/") && ! (invocation instanceof SubInvocation)) { String contextPath = invocation.getContextPath(); return new RedirectFilterChain(contextPath + contextURI + "/"); } else { servletName = _servletMap.map(welcomeURI, vars); if (servletName != null || _defaultServlet != null) { contextURI = welcomeURI; if (invocation instanceof Invocation) { Invocation inv = (Invocation) invocation; inv.setContextURI(contextURI); // server/10r9 // inv.setRawURI(inv.getRawURI() + file); } break; } } } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); } } } if (servletName == null) { servletName = _defaultServlet; vars.clear(); vars.add(contextURI); addWelcomeFileDependency(invocation); } if (servletName == null) { log.fine(L.l("'{0}' has no default servlet defined", contextURI)); return new ErrorFilterChain(404); } String servletPath = vars.get(0); invocation.setServletPath(servletPath); if (servletPath.length() < contextURI.length()) invocation.setPathInfo(contextURI.substring(servletPath.length())); else invocation.setPathInfo(null); ServletMapping regexp = _regexpMap.get(servletName); if (regexp != null) servletName = regexp.initRegexp(_servletContext, _servletManager, vars); if (servletName.equals("invoker")) servletName = handleInvoker(invocation); invocation.setServletName(servletName); if (log.isLoggable(Level.FINE)) log.fine("invoke (uri:" + contextURI + " -> " + servletName + ")"); ServletConfigImpl config = _servletManager.getServlet(servletName); if (config != null) { invocation.setSecurityRoleMap(config.getRoleMap()); } FilterChain chain = _servletManager.createServletChain(servletName); if (chain instanceof PageFilterChain) { PageFilterChain pageChain = (PageFilterChain) chain; chain = PrecompilePageFilterChain.create(invocation, pageChain); } return chain; } private void addWelcomeFileDependency(ServletInvocation servletInvocation) { if (! (servletInvocation instanceof Invocation)) return; Invocation invocation = (Invocation) servletInvocation; String contextURI = invocation.getContextURI(); DependencyContainer dependencyList = new DependencyContainer(); WebApp app = (WebApp) _servletContext; Path contextPath = app.getAppDir().lookup(app.getRealPath(contextURI)); if (! contextPath.isDirectory()) return; for (int i = 0; i < _welcomeFileList.size(); i++) { String file = _welcomeFileList.get(i); String realPath = app.getRealPath(contextURI + "/" + file); Path path = app.getAppDir().lookup(realPath); dependencyList.add(new Depend(path)); } dependencyList.clearModified(); invocation.setDependency(dependencyList); } private String handleInvoker(ServletInvocation invocation) throws ServletException { String tail; if (invocation.getPathInfo() != null) tail = invocation.getPathInfo(); else tail = invocation.getServletPath(); // XXX: this is really an unexpected, internal error that should never // happen if (! tail.startsWith("/")) { throw new ConfigException("expected '/' starting " + " sp:" + invocation.getServletPath() + " pi:" + invocation.getPathInfo() + " sn:invocation" + invocation); } int next = tail.indexOf('/', 1); String servletName; if (next < 0) servletName = tail.substring(1); else servletName = tail.substring(1, next); // XXX: This should be generalized, possibly with invoker configuration if (servletName.startsWith("com.caucho")) { throw new ConfigException(L.l("servlet '{0}' forbidden from invoker. com.caucho.* classes must be defined explicitly in a <servlet> declaration.", servletName)); } else if (servletName.equals("")) { throw new ConfigException(L.l("invoker needs a servlet name in URL '{0}'.", invocation.getContextURI())); } addServlet(servletName); String servletPath = invocation.getServletPath(); if (invocation.getPathInfo() == null) { } else if (next < 0) { invocation.setServletPath(servletPath + tail); invocation.setPathInfo(null); } else if (next < tail.length()) { invocation.setServletPath(servletPath + tail.substring(0, next)); invocation.setPathInfo(tail.substring(next)); } else { invocation.setServletPath(servletPath + tail); invocation.setPathInfo(null); } return servletName; } public String getServletPattern(String uri) { ArrayList<String> vars = new ArrayList<String>(); Object value = null; if (_servletMap != null) value = _servletMap.map(uri, vars); if (value == null) return null; else return uri; } /** * Returns the servlet matching patterns. */ public ArrayList<String> getURLPatterns() { ArrayList<String> patterns = _servletMap.getURLPatterns(); return patterns; } /** * Returns the servlet plugin_ignore patterns. */ public ArrayList<String> getIgnorePatterns() { return _ignorePatterns; } private void addServlet(String servletName) throws ServletException { if (_servletManager.getServlet(servletName) != null) return; ServletConfigImpl config = new ServletConfigImpl(); config.setServletContext(_servletContext); config.setServletName(servletName); try { config.setServletClass(servletName); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new ServletException(e); } config.init(); _servletManager.addServlet(config); } public void destroy() { _servletManager.destroy(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?