📄 jspservlet.java
字号:
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. 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.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``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 APACHE SOFTWARE FOUNDATION 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.jasper.servlet;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;
import javax.servlet.jsp.JspFactory;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.FileNotFoundException;
import org.apache.jasper.JasperException;
import org.apache.jasper.Constants;
import org.apache.jasper.Options;
import org.apache.jasper.EmbededServletOptions;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.JspEngineContext;
import org.apache.jasper.compiler.Mangler;
import org.apache.jasper.runtime.*;
import org.apache.jasper.compiler.Compiler;
import org.apache.tomcat.logging.Logger;
/**
* The JSP engine (a.k.a Jasper)!
*
* @author Anil K. Vijendran
* @author Harish Prabandham
* @author Marc A. Saegesser
*/
public class JspServlet extends HttpServlet {
/**
* Adds reference counting to the JSP implementation servlet. This
* is required to handle the case where a JSP implementation servlet
* is executing requests on several threads when a new implementation
* arrives (the JSP source was updated). We need to wait until all
* the requests complete before calling the implementation servlet's
* destroy() method.
*/
class JspCountedServlet extends HttpServlet
{
private Servlet servlet = null;
private int threadCount = 0;
private boolean destroyed = false;
public JspCountedServlet(Servlet servlet)
{
this.servlet = servlet;
}
public void init(ServletConfig config) throws ServletException, JasperException
{
try{
servlet.init(config);
}catch(NullPointerException e){
throw new JasperException(e);
}
}
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException, JasperException
{
try{
incrementCount();
servlet.service(req, res);
}catch(NullPointerException e){
throw new JasperException(e);
}finally{
decrementCount();
}
}
/*
* Flags this servlet for destrction once all active requests have completed.
* After calling this method it is invalid to call service().
*/
public void destroy()
{
destroyed = true;
if(getCount() == 0)
doDestroy();
}
private void doDestroy()
{
try{
servlet.destroy();
servlet = null;
}catch(NullPointerException e){
}
}
private synchronized void incrementCount()
{
threadCount++;
}
private synchronized void decrementCount()
{
if(threadCount <= 0){
Constants.message("jsp.error.badcount", Logger.ERROR);
return;
}
--threadCount;
if(threadCount == 0 && destroyed)
doDestroy();
}
private synchronized int getCount()
{
return threadCount;
}
}
class JspServletWrapper {
JspCountedServlet theServlet;
String jspUri;
boolean isErrorPage;
Class servletClass;
JspServletWrapper(String jspUri, boolean isErrorPage) {
this.jspUri = jspUri;
this.isErrorPage = isErrorPage;
this.theServlet = null;
}
public synchronized void instantiateServlet(Class servletClass) throws JasperException, ServletException
{
try {
this.servletClass = servletClass;
// If we're replacing an existing JSP Implementation class, then
// schedule it for destruction
if(theServlet != null)
theServlet.destroy();
// Create an instance of the JSP implementation class
Servlet servlet = (Servlet) servletClass.newInstance();
// Set the class loader
if(servlet instanceof HttpJspBase) {
((HttpJspBase)servlet).setClassLoader(JspServlet.this.parentClassLoader);
}
// Wrap this servlet in a counted servlet
theServlet = new JspCountedServlet(servlet);
// Call the JSP Implementation servlet's init() method. This
// will cause the page's jspInit() method to be invoked if one exists.
theServlet.init(JspServlet.this.config);
} catch(Exception ex) {
throw new JasperException(ex);
}
}
public synchronized Servlet getServlet()
{
return theServlet;
}
public synchronized boolean isInstantiated()
{
return theServlet != null;
}
private void loadIfNecessary(HttpServletRequest req, HttpServletResponse res)
throws JasperException, ServletException, FileNotFoundException
{
// First try context attribute; if that fails then use the
// classpath init parameter.
// Should I try to concatenate them if both are non-null?
String cp = (String) context.getAttribute(Constants.SERVLET_CLASSPATH);
String accordingto;
if(cp == null || cp.equals("")) {
accordingto = "according to the init parameter";
cp = options.getClassPath();
} else
accordingto = "according to the Servlet Engine";
Constants.message("jsp.message.cp_is",
new Object[] {
accordingto,
cp == null ? "" : cp
},
Logger.INFORMATION);
loadJSP(jspUri, cp, isErrorPage, req, res);
}
public void service(HttpServletRequest request,
HttpServletResponse response,
boolean precompile)
throws ServletException, IOException, FileNotFoundException
{
Servlet servlet = null;
try {
loadIfNecessary(request, response);
servlet = getServlet();
// If a page is to only to be precompiled return.
if(precompile)
return;
if(servlet instanceof SingleThreadModel) {
// sync on the wrapper so that the freshness
// of the page is determined right before servicing
synchronized (this) {
servlet.service(request, response);
}
} else {
servlet.service(request, response);
}
} catch(FileNotFoundException ex) {
try {
if(insecure_TMI) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
Constants.getString
("jsp.error.file.not.found.TMI",
new Object[] {
ex.getMessage()
}));
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
Constants.getString
("jsp.error.file.not.found",
new Object[] {
// Too Much Information -- ex.getMessage()
}));
}
} catch(IllegalStateException ise) {
// logs are presumed to be secure, thus the TMI info can be logged
Constants.jasperLog.log(Constants.getString
("jsp.error.file.not.found.TMI",
new Object[] {
ex.getMessage()
}), ex,
Logger.ERROR);
// rethrow FileNotFoundException so someone higher up can handle
if(insecure_TMI)
throw ex;
else
throw new FileNotFoundException(Constants.getString
("jsp.error.file.not.found",
new Object[] {
// Too Much Information -- ex.getMessage()
}));
}
return;
}
}
public void destroy()
{
if(theServlet != null)
theServlet.destroy();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -