1.jsp运行时都要先转换成servlet,使用tomcat时会在tomcat安装目录下的work生成一系列的文件夹和.java文件和.class文件.
2.jsp最终转化为servlet,work的作用就是加快速度,如果jsp没有变化就不重新编译了.
3.jsp最终变成输出的html代码的生命周期是这样的:
Web服务器读取jsp文件,将jsp文件转换为同名+_jsp.java文件,然后编译生成.class文件,Web服务器通过执行该.class文件,输出其中的html代码,就是你看到的在浏览器中的页面了。tomcat将所有生成的.java文件放在work目录下面,work目录下面的文件对于你直接纠错和学习jsp机制都是很有用的
4.当请求jsp页面时,Tomcat会分派给JspServlet来处理,在 jspServlet的方法 service()中有一句 
boolean precompile = preCompile(request); 
它会判断你请求jsp页面时有没有带?jsp_precompile查询字符串,如果带了就会重新编译 
然后再由  
serviceJspFile(request, response, jspUri, null, precompile); 
进一步判断是否要进行编译jsp文件 
下面由JspServletWraper service方法 
if (options.getDevelopment() || firstTime ) { 
synchronized (this) { 
if (firstTime) { 
firstTime = false; 

// The following sets reload to true, if necessary 
ctxt.compile(); 


再到JspCompilationContext.compile()方法 
if (isPackagedTagFile || jspCompiler.isOutDated()) { 
才编译 
关键就在Compiler的 
isOutDated(boolean checkClass) 
的判断上 
如果你真要研究就应该去看看这段代码,判断标准是:如果jsp最后修改时间大于目标文件的最后修改时间要重新编译。 
还有一种情况就是即使jsp的最后修改时间晚于目标文件的最后修改时间,但只要jsp中用了 
include指令包含的某个文件的最后修改时间早于对应目标文件的修改时间的话,也是需要重新编译主jsp文件的
 
从这里可以看出,虽然jsp文件没改,但是被包含的jsp文件改了仍然会重新编译的,有些应用服务器就没做到这一点,被包含文件改了,还得动一动主文件才能看到效果。

解决方案 »

  1.   

    to:lixinbill
    你红字写的那一部分不管tomcat如何设置都会那样执行吗?
      

  2.   

    这个有可能是浏览器对你的页面进行缓存的,把下列语句加入到你的jsp文件中的<head></head>部分,可以防止浏览器将你的页面放入缓存之中:
    <%
    response.setHeader("Pragma","no-cache");
    response.setHeader("Cache-Control","no-cache");
    response.setDateHeader("Expires", 0);
    %><meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="Expires" content="0">
      

  3.   

    如楼上
    JSP页面设置禁止缓存
      

  4.   

    huoyin的想法值得表扬。但是困扰我的不是这个问题,大家再想想