📄 webappservlet.java
字号:
/* tjws - WebAppServlet.java
* Copyright (C) 1999-2007 Dmitriy Rogatkin. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS 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 AUTHOR OR 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.
*
* $Id: WebAppServlet.java,v 1.37 2006/12/31 18:20:19 rogatkin Exp $
* Created on Dec 14, 2004
*/
package rogatkin.web;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionListener;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import Acme.Utils;
import Acme.Serve.Serve;
/**
* @author dmitriy
*
*
*/
public class WebAppServlet extends HttpServlet implements ServletContext {
public static final String DEF_DEBUG = "rogatkin.web.WebAppServlet.debug";
public static final String WAR_NAME_AS_CONTEXTPATH = "tjws.wardeploy.warname-as-context";
protected static final String WEBAPPCLASSLOADER = "rogatkin.web.WebAppServlet.AppClassLoader";
List<ServletAccessDescr> servlets;
List<FilterAccessDescriptor> filters;
URL[] cpUrls;
URLClassLoader ucl;
File deployDir;
Serve server;
int sessionTimeout;
// / context methods
protected String contextName;
protected String contextPath;
protected Hashtable<String, Object> attributes;
protected Hashtable<String, String> contextParameters;
protected List<String> welcomeFiles;
protected List<ErrorPageDescr> errorPages;
protected List<EventListener> listeners;
protected List<HttpSessionListener> sessionListeners;
protected Map<String, String> mimes;
protected static class MappingEntry {
String servPath;
Pattern pathPat;
MappingEntry(String path, String pattern) {
servPath = path;
pathPat = Pattern.compile(pattern);
}
public String toString() {
return String.format("Mapping of %s with regexp pat %s", servPath, pathPat);
}
}
protected class ServletAccessDescr implements ServletConfig {
String className;
String name;
HttpServlet instance;
// String servPath;
// String pathPat;
MappingEntry[] mapping;
Map<String, String> initParams;
String label;
boolean loadOnStart;
String descr;
long timeToReactivate; // if servlet suspended
public java.lang.String getServletName() {
return name;
}
public java.util.Enumeration getInitParameterNames() {
return new Enumeration<String>() {
Iterator<String> i;
{
i = initParams.keySet().iterator();
}
public boolean hasMoreElements() {
return i.hasNext();
}
public String nextElement() {
return i.next();
}
};
}
public ServletContext getServletContext() {
return WebAppServlet.this;
}
public String getInitParameter(java.lang.String name) {
return initParams.get(name);
}
public void add(MappingEntry entry) {
if (mapping == null)
mapping = new MappingEntry[1];
else { // can't use copyOf in 1.5
MappingEntry[] copy = new MappingEntry[mapping.length + 1];
System.arraycopy(mapping, 0, copy, 0, mapping.length);
mapping = copy;
}
mapping[mapping.length - 1] = entry;
}
int matchPath(String path) {
if (mapping == null)
return -1;
for (int i = 0; i < mapping.length; i++)
if (mapping[i].pathPat.matcher(path).matches())
return i;
return -1;
}
public String toString() {
return "Servlet " + name + " class " + className + " path/patern " + Arrays.toString(mapping) + " init"
+ initParams + " inst " + instance;
}
}
static enum DispatchFilterType {
FORWARD, INCLUDE, REQUEST, ERROR
};
protected class FilterAccessDescriptor extends ServletAccessDescr implements FilterConfig {
String[] servletNames;
Filter filterInstance;
DispatchFilterType[] dispatchTypes;
public java.lang.String getFilterName() {
return name;
}
public void add(String name) {
// note the local name shadows name as class memeber
if (servletNames == null)
servletNames = new String[1];
else
servletNames = Utils.copyOf(servletNames, servletNames.length + 1);
servletNames[servletNames.length - 1] = name;
}
public void add(DispatchFilterType dispatcher) {
if (dispatchTypes == null)
dispatchTypes = new DispatchFilterType[1];
else {
DispatchFilterType[] copy = new DispatchFilterType[dispatchTypes.length + 1];
System.arraycopy(dispatchTypes, 0, copy, 0, dispatchTypes.length);
dispatchTypes = copy;
}
dispatchTypes[dispatchTypes.length - 1] = dispatcher;
}
int matchServlet(String servletName) {
if (servletNames == null)
return -1;
for (int i = 0; i < this.servletNames.length; i++)
if (servletNames[i].equals(servletName))
return i;
return -1;
}
boolean matchDispatcher(DispatchFilterType dispatcher) {
if (dispatchTypes == null)
if (dispatcher.equals(DispatchFilterType.REQUEST))
return true;
else
return false;
for (int i = 0; i < dispatchTypes.length; i++)
if (dispatcher.equals(dispatchTypes[i]))
return true;
return false;
}
public String toString() {
return String.format("Filter for servlets %s and types %s based on %s", Arrays.toString(servletNames),
Arrays.toString(dispatchTypes), super.toString());
}
}
protected static class ErrorPageDescr {
String errorPage;
Class exception;
int errorCode;
ErrorPageDescr(String page, String exClass, String code) {
if (page == null || page.length() == 0 || page.charAt(0) != '/')
throw new IllegalArgumentException("Error page path '" + page + "' must start with '/'");
if (page.charAt(0) == '/')
errorPage = page;
else
errorPage = "/" + page;
try {
exception = Class.forName(exClass);
} catch (Exception e) {
}
try {
errorCode = Integer.parseInt(code);
} catch (Exception e) {
}
}
}
protected WebAppServlet(String context) {
this.contextPath = "/" + context;
attributes = new Hashtable<String, Object>();
contextParameters = new Hashtable<String, String>();
// TODO consider
// _DEBUG = System.getProperty(getClass().getName() + ".debug") != null;
}
public static WebAppServlet create(File deployDir, String context, Serve server) throws ServletException {
XPath xp = XPathFactory.newInstance().newXPath();
WebAppServlet result = new WebAppServlet(context);
result.server = server;
try {
result.makeCP(deployDir); // /web-app
Node document = (Node) xp.evaluate("/*", new InputSource(new FileInputStream(new File(deployDir,
"WEB-INF/web.xml"))), XPathConstants.NODE);
final String namespaceURI = document.getNamespaceURI();
String prefix = namespaceURI == null ? "" : "j2ee:";
xp.setNamespaceContext(new NamespaceContext() {
public String getNamespaceURI(String prefix) {
// System.err.printf("Resolver called with %s%n", prefix);
if (prefix == null)
throw new IllegalArgumentException("Prefix is null.");
if (namespaceURI == null)
return XMLConstants.NULL_NS_URI;
if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX))
return namespaceURI;
if ("j2ee".equals(prefix))
return namespaceURI;
return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String arg0) {
throw new UnsupportedOperationException("getPrefix(" + arg0 + ");");
}
public Iterator getPrefixes(String arg0) {
throw new UnsupportedOperationException("getPrefixes(" + arg0 + ");");
}
});
document = (Node) xp.evaluate("//" + prefix + "web-app", document, XPathConstants.NODE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -