📄 abstracthttpservlet.java
字号:
/* * $Id: AbstractHttpServlet.java,v 1.9 2006/01/23 10:36:22 cstein Exp $ * * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved. * * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided that the * following conditions are met: * * 1. Redistributions of source code must retain copyright statements and * notices. Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name "groovy" must not be used to endorse or promote products derived * from this Software without prior written permission of The Codehaus. For * written permission, please contact info@codehaus.org. * * 4. Products derived from this Software may not be called "groovy" nor may * "groovy" appear in their names without prior written permission of The * Codehaus. "groovy" is a registered trademark of The Codehaus. * * 5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/ * * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */package groovy.servlet;import groovy.lang.MetaClass;import groovy.util.ResourceConnector;import groovy.util.ResourceException;import java.io.File;import java.io.IOException;import java.net.URL;import java.net.URLConnection;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.servlet.ServletConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;/** * A common ground dealing with the HTTP servlet API wrinkles. * * <h4>Resource name mangling (pattern replacement)</h4> * * <p> * Also implements Groovy's {@link groovy.util.ResourceConnector} in dynamic * manner. It allows to modifiy the resource name that is searched for with a * <i>replace all</i> operation. See {@link java.util.regex.Pattern} and * {@link java.util.regex.Matcher} for details. * The servlet init parameter names are: * <pre> * resource.name.regex = empty - defaults to null * resource.name.replacement = empty - defaults to null * resource.name.replace.all = true (default) | false means replaceFirst() * </pre> * Note: If you specify a regex, you have to specify a replacement string too! * Otherwise an exception gets raised. * * <h4>Logging and bug-hunting options</h4> * * <p> * This implementation provides a verbosity flag switching log statements. * The servlet init parameter name is: * <pre> * verbose = false(default) | true * </pre> * * <p> * In order to support class-loading-troubles-debugging with Tomcat 4 or * higher, you can log the class loader responsible for loading some classes. * See {@linkplain http://jira.codehaus.org/browse/GROOVY-861} for details. * The servlet init parameter name is: * <pre> * log.GROOVY861 = false(default) | true * </pre> * * <p> * If you experience class-loading-troubles with Tomcat 4 (or higher) or any * other servlet container using custom class loader setups, you can fallback * to use (slower) reflection in Groovy's MetaClass implementation. Please * contact the dev team with your problem! Thanks. * The servlet init parameter name is: * <pre> * reflection = false(default) | true * </pre> * * * @author Christian Stein */public abstract class AbstractHttpServlet extends HttpServlet implements ResourceConnector { /** * Content type of the HTTP response. */ public static final String CONTENT_TYPE_TEXT_HTML = "text/html"; /** * Servlet API include key name: path_info */ public static final String INC_PATH_INFO = "javax.servlet.include.path_info"; /* *** Not used, yet. See comments in getScriptUri(HttpServletRequest). *** * Servlet API include key name: request_uri */ public static final String INC_REQUEST_URI = "javax.servlet.include.request_uri"; /** * Servlet API include key name: servlet_path */ public static final String INC_SERVLET_PATH = "javax.servlet.include.servlet_path"; /** * Servlet (or the web application) context. */ protected ServletContext servletContext; /** * <b>Null</b> or compiled pattern matcher read from "resource.name.regex" * and used in {@link AbstractHttpServlet#getResourceConnection(String)}. */ protected Matcher resourceNameMatcher; /** * The replacement used by the resource name matcher. */ protected String resourceNameReplacement; /** * The replace method to use on the matcher. * <pre> * true - replaceAll(resourceNameReplacement); (default) * false - replaceFirst(resourceNameReplacement); * </pre> */ protected boolean resourceNameReplaceAll; /** * Controls almost all log output. */ protected boolean verbose; /** * Mirrors the static value of the reflection flag in MetaClass. * See {@link AbstractHttpServlet#logGROOVY861} */ protected boolean reflection; /** * Debug flag logging the class the class loader of the request. */ private boolean logGROOVY861; /** * Initializes all fields with default values. */ public AbstractHttpServlet() { this.servletContext = null; this.resourceNameMatcher = null; this.resourceNameReplacement = null; this.resourceNameReplaceAll = true; this.verbose = false; this.reflection = false; this.logGROOVY861 = false; } /** * Interface method for ResourceContainer. This is used by the GroovyScriptEngine. */ public URLConnection getResourceConnection(String name) throws ResourceException { /* * First, mangle resource name with the compiled pattern. */ Matcher matcher = resourceNameMatcher; if (matcher != null) { matcher.reset(name); String replaced; if (resourceNameReplaceAll) { replaced = resourceNameMatcher.replaceAll(resourceNameReplacement); } else { replaced = resourceNameMatcher.replaceFirst(resourceNameReplacement); } if (!name.equals(replaced)) { if (verbose) { log("Replaced resource name \"" + name + "\" with \"" + replaced + "\"."); } name = replaced; } } /* * Try to locate the resource and return an opened connection to it. */ try { URL url = servletContext.getResource("/" + name); if (url == null) { url = servletContext.getResource("/WEB-INF/groovy/" + name); } if (url == null) { throw new ResourceException("Resource \"" + name + "\" not found!"); } return url.openConnection(); } catch (IOException e) { throw new ResourceException("Problems getting resource named \"" + name + "\"!", e); } } /** * Returns the include-aware uri of the script or template file. * * @param request * the http request to analyze * @return the include-aware uri either parsed from request attributes or * hints provided by the servlet container */ protected String getScriptUri(HttpServletRequest request) { /* * Log some debug information for http://jira.codehaus.org/browse/GROOVY-861 */ if (logGROOVY861) { log("Logging request class and its class loader:"); log(" c = request.getClass() :\"" + request.getClass() + "\""); log(" l = c.getClassLoader() :\"" + request.getClass().getClassLoader() + "\""); log(" l.getClass() :\"" + request.getClass().getClassLoader().getClass() + "\""); /* * Keep logging, if we're verbose. Else turn it off. */ logGROOVY861 = verbose; } // // NOTE: This piece of code is heavily inspired by Apaches Jasper2! // // http://cvs.apache.org/viewcvs.cgi/jakarta-tomcat-jasper/jasper2/ \ // src/share/org/apache/jasper/servlet/JspServlet.java?view=markup // // Why doesn't it use request.getRequestURI() or INC_REQUEST_URI? // String uri = null; String info = null; // // Check to see if the requested script/template source file has been the // target of a RequestDispatcher.include(). // uri = (String) request.getAttribute(INC_SERVLET_PATH); if (uri != null) { // // Requested script/template file has been target of // RequestDispatcher.include(). Its path is assembled from the relevant // javax.servlet.include.* request attributes and returned! // info = (String) request.getAttribute(INC_PATH_INFO); if (info != null) { uri += info; } return uri; } // // Requested script/template file has not been the target of a // RequestDispatcher.include(). Reconstruct its path from the request's // getServletPath() and getPathInfo() results. // uri = request.getServletPath(); info = request.getPathInfo(); if (info != null) { uri += info; } /* * TODO : Enable auto ".groovy" extension replacing here! * http://cvs.groovy.codehaus.org/viewrep/groovy/groovy/groovy-core/src/main/groovy/servlet/GroovyServlet.java?r=1.10#l259 */ return uri; } /** * Parses the http request for the real script or template source file. * * @param request * the http request to analyze * @param context * the context of this servlet used to get the real path string * @return a file object using an absolute file path name */ protected File getScriptUriAsFile(HttpServletRequest request) { String uri = getScriptUri(request); String real = servletContext.getRealPath(uri); File file = new File(real).getAbsoluteFile(); return file; } /** * Overrides the generic init method to set some debug flags. * * @param config * the servlet coniguration provided by the container * @throws ServletException if init() method defined in super class * javax.servlet.GenericServlet throws it */ public void init(ServletConfig config) throws ServletException { /* * Never forget super.init()! */ super.init(config); /* * Grab the servlet context. */ this.servletContext = config.getServletContext(); /* * Get verbosity hint. */ String value = config.getInitParameter("verbose"); if (value != null) { this.verbose = Boolean.valueOf(value).booleanValue(); } /* * And now the real init work... */ if (verbose) { log("Parsing init parameters..."); } String regex = config.getInitParameter("resource.name.regex"); if (regex != null) { String replacement = config.getInitParameter("resource.name.replacement"); if (replacement == null) { Exception npex = new NullPointerException("resource.name.replacement"); String message = "Init-param 'resource.name.replacement' not specified!"; log(message, npex); throw new ServletException(message, npex); } int flags = 0; // TODO : Parse pattern compile flags. this.resourceNameMatcher = Pattern.compile(regex, flags).matcher(""); this.resourceNameReplacement = replacement; String all = config.getInitParameter("resource.name.replace.all"); if (all != null) { this.resourceNameReplaceAll = Boolean.valueOf(all).booleanValue(); } } value = config.getInitParameter("reflection"); if (value != null) { this.reflection = Boolean.valueOf(value).booleanValue(); MetaClass.setUseReflection(reflection); } value = config.getInitParameter("logGROOVY861"); if (value != null) { this.logGROOVY861 = Boolean.valueOf(value).booleanValue(); // nothing else to do here } /* * If verbose, log the parameter values. */ if (verbose) { log("(Abstract) init done. Listing some parameter name/value pairs:"); log("verbose = " + verbose); // this *is* verbose! ;) log("reflection = " + reflection); log("logGROOVY861 = " + logGROOVY861); if (resourceNameMatcher != null) { log("resource.name.regex = " + resourceNameMatcher.pattern().pattern()); } else { log("resource.name.regex = null"); } log("resource.name.replacement = " + resourceNameReplacement); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -