我们在开发的过程中,修改JSP的内容后,不启动容器的情况下,可以进行应用,这是为什么呢? 容器到底做了什么呢? 它怎么知道我们的JSP有变化呢? 哈哈,接下来我们就来揭开TOMCAT的这层面纱:
1.我们在访问JSP面的的时候执行的流程为:
容器启动后,会有一个无限循环的等待来接由客户端的请求,这个是由JIoEndpoint.Acceptor线程来完成的,代码如下:
protected class Acceptor implements Runnable {
/**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
public void run() {
// Loop until we receive a shutdown command
while (running) {
// Loop if endpoint is paused
while (paused) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
// Accept the next incoming connection from the server socket
try {
Socket socket = serverSocketFactory.acceptSocket(serverSocket);
serverSocketFactory.initSocket(socket);
// Hand this socket off to an appropriate processor
if (!processSocket(socket)) {
// Close socket right away
try {
socket.close();
} catch (IOException e) {
// Ignore
}
}
}catch ( IOException x ) {
if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);
} catch (Throwable t) {
log.error(sm.getString("endpoint.accept.fail"), t);
}
// The processor will recycle itself when it finishes
}
}
}
2.当容器收到一个请求后,CoyoteAdapter类的service方法来处理 ,然后通过责任链模式调用到StandardWrapperValve.java类invoke方法中调用ApplicationFilterChain类的doFilter 接着来到HttpServlet的Service方法中 调用JspServlet.java类的service方法中,serviceJspFile 。。。JspServletWrapper.java类的service方法中, if (options.getDevelopment() || firstTime ) {
synchronized (this) {
firstTime = false;
// The following sets reload to true, if necessary
ctxt.compile();
}
} else {
if (compileException != null) {
// Throw cached compilation exception
throw compileException;
}
}
最后来到,JspCompilationContext.java类的compile方法中,重点来了,
public void compile() throws JasperException, FileNotFoundException {
createCompiler();
[b]if (jspCompiler.isOutDated()) {[/b]
try {
jspCompiler.removeGeneratedFiles();
jspLoader = null;
jspCompiler.compile();
jsw.setReload(true);
jsw.setCompilationException(null);
} catch (JasperException ex) {
// Cache compilation exception
jsw.setCompilationException(ex);
throw ex;
} catch (Exception ex) {
JasperException je = new JasperException(
Localizer.getMessage("jsp.error.unable.compile"),
ex);
// Cache compilation exception
jsw.setCompilationException(je);
throw je;
}
}
}
以上加粗的地方来判断是否进行重新编译JSP页面,
public boolean isOutDated(boolean checkClass) {
String jsp = ctxt.getJspFile();
if (jsw != null
&& (ctxt.getOptions().getModificationTestInterval() > 0)) {
if (jsw.getLastModificationTest()
+ (ctxt.getOptions().getModificationTestInterval() * 1000) > System
.currentTimeMillis()) {
return false;
} else {
jsw.setLastModificationTest(System.currentTimeMillis());
}
}
long jspRealLastModified = 0;
try {
URL jspUrl = ctxt.getResource(jsp);
if (jspUrl == null) {
ctxt.incrementRemoved();
return false;
}
URLConnection uc = jspUrl.openConnection();
if (uc instanceof JarURLConnection) {
jspRealLastModified =
((JarURLConnection) uc).getJarEntry().getTime();
} else {
jspRealLastModified = uc.getLastModified();
}
uc.getInputStream().close();
} catch (Exception e) {
return true;
}
long targetLastModified = 0;
File targetFile;
if (checkClass) {
targetFile = new File(ctxt.getClassFileName());
} else {
targetFile = new File(ctxt.getServletJavaFileName());
}
if (!targetFile.exists()) {
return true;
}
targetLastModified = targetFile.lastModified();
if (checkClass && jsw != null) {
jsw.setServletClassLastModifiedTime(targetLastModified);
}
if (targetLastModified < jspRealLastModified) {
if (log.isDebugEnabled()) {
log.debug("Compiler: outdated: " + targetFile + " "
+ targetLastModified);
}
return true;
}
// determine if source dependent files (e.g. includes using include
// directives) have been changed.
if (jsw == null) {
return false;
}
List depends = jsw.getDependants();
if (depends == null) {
return false;
}
Iterator it = depends.iterator();
while (it.hasNext()) {
String include = (String) it.next();
try {
URL includeUrl = ctxt.getResource(include);
if (includeUrl == null) {
return true;
}
URLConnection iuc = includeUrl.openConnection();
long includeLastModified = 0;
if (iuc instanceof JarURLConnection) {
includeLastModified =
((JarURLConnection) iuc).getJarEntry().getTime();
} else {
includeLastModified = iuc.getLastModified();
}
iuc.getInputStream().close();
if (includeLastModified > targetLastModified) {
return true;
}
} catch (Exception e) {
return true;
}
}
return false;
}
分享到:
相关推荐
1. **开发模式与生产模式**: `development`属性控制JSP是否处于开发模式。在开发模式下,Tomcat会自动重新加载修改过的JSP页面,显示详细的错误信息。在生产环境中,通常会关闭开发模式以提高性能和安全性。 2. **...
编译源码时,会用到`ecj.jar`,这是Eclipse Java Compiler的jar包,用于编译JSP文件。 6. **其他依赖库**:Tomcat源码中还包括了其他一些必要的库,如`servlet-api.jar`、`jsp-api.jar`等,这些都是Java Web应用的...
【标题】:“Tomcat6编译”涉及到的知识点主要涵盖了Apache Tomcat的版本历史、源码获取、编译环境配置、编译步骤以及部署与运行等核心内容。 【描述】:“Tomcat6源码编译,需要的朋友可以下载”表明这是一项针对...
在Tomcat中,JSP文件被编译成Servlet,然后执行生成动态内容。JSP使得开发者能够将表现层和业务逻辑分离,提高代码的可维护性和复用性。 4. 集成与应用:在实际开发中,开发者通常会在JSP页面中编写HTML结构,然后...
在编译Tomcat时,通常会依赖于servlet-api.jar和jsp-api.jar这两个文件,它们通常位于Tomcat的lib目录下。 五、Apache Tomcat Native Library 为了提高性能,Tomcat提供了一个原生库(Tomcat Native),它允许...
【手工编译jsp】是一个关于Java Web开发中的特殊主题,主要涉及如何在没有使用Web容器(如Tomcat、Jetty等)的情况下,直接对JSP(JavaServer Pages)页面进行预编译为Java类的过程。这个过程对于理解JSP的工作原理...
总结,"jsp.rar_JSP TOMCAT SQL_jsp sql_jsp sql tomcat_tomcat server jsp_"这个项目涵盖了JSP动态网页技术、Tomcat服务器的使用、SQL Server数据库的管理和JSP与SQL的交互等多个关键知识点,是一个综合性的Web应用...
2. **目录结构**:Tomcat的源码目录通常包含`conf`(配置文件)、`webapps`(Web应用部署目录)、`work`(编译JSP后的临时文件)、`logs`(日志文件)等关键部分。 3. **生命周期管理**:Tomcat对Web应用程序和...
总的来说,将JSP编译打包成jar是一个将静态的JSP文件转换为可执行的Servlet代码,并利用构建工具Ant完成打包的过程,这样可以方便地在不支持JSP的环境中运行和部署。这个过程涉及到JSP、Servlet、Ant构建工具以及web...
Tomcat作为JSP容器,能够编译JSP文件为Servlet,然后执行这些Servlet来生成动态内容。 “标签”中提到了“tomcat6.0”、“JSP”和“测试”,这进一步强调了这个压缩包的重点内容。Tomcat 6.0是Tomcat的一个版本,...
为了实现这一目标,攻击者可能需要修改Tomcat的配置或利用特定的漏洞,使得Tomcat在找不到源JSP文件时不会立即清理`JspServletWrapper`,从而保持对已编译JSP的访问权限。 在进行源代码调试时,开发者可以跟踪`...
但如果你想修改JSP版本或者配置JSP的编译选项,可以在Tomcat的conf目录下的`web.xml`文件中找到相关的servlet配置。 **四、部署JSP应用** 1. 创建Web应用目录结构:在Tomcat的webapps目录下创建一个新的文件夹,...
Tomcat 编译安装详解 Tomcat 是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun 和其他一些公司及个人共同开发而成。Tomcat 是一个免费的开放源代码的 Web 应用...
在Tomcat中,编译后的JSP文件(即Servlet类文件)是以UTF-8编码保存的。 3. **GB2312-80/GBK**:这是中文操作系统中常用的编码方式,GB2312-80主要用于简体中文,GBK是其扩展版本,能支持更多的汉字,包括繁体字。...
在IT行业中,Tomcat是一个非常重要的应用服务器,它主要用于部署和运行Java Servlet和JavaServer Pages (JSP)。本文将详细讲解如何编译Tomcat依赖的包,以便于理解其工作原理并进行自定义配置。 首先,让我们了解...
Tomcat,作为Apache软件基金会的一个开源项目,是Java Servlet、JavaServer Pages(JSP)以及Java Expression Language(EL)的实现,是世界上最流行的Java应用服务器之一。深入理解并编译Tomcat源码,对于Java...
【标题】"jsp-tomcat安装包-8.5.94" 提供的是一个用于部署和运行JavaServer Pages(JSP)应用的Tomcat服务器的版本8.5.94。Tomcat是Apache软件基金会的Jakarta项目下的一个开源应用服务器,特别适合于小型到中型的...
### Tomcat+JSP+MySQL 经典配置实例详解 #### 一、环境搭建与配置 在本章节中,我们将详细介绍如何配置一个基于Tomcat、JSP和MySQL的经典开发环境。这种组合是Java Web开发中非常常见的配置之一,能够帮助开发者...
MyEclipse会通过源码编译并启动Tomcat,你可以在"Console"视图中观察启动日志,确认服务器是否成功运行。 在深入研究Tomcat源码时,理解其模块结构和主要组件是非常重要的。Tomcat的主要组件包括Catalina(核心...