深入刨析tomcat 之---第21篇 tomcat 对jsp页面支持的实现原理
writedby 张艳涛
web技术,以前的动态网页技术多是jsp页面,比如点击一个菜单目录,直接访问了一个LRJSDetailInput.jsp页面,这个页面
有<html><body><form><table>标签,有对应的js,当对某个button标签设置了onClick方法后就调用js中的方法将
<INPUT class=cssButton VALUE="查 询" TYPE=button onClick="queryDetailData();">
<INPUT class=cssButton VALUE="下 载" TYPE=button onClick="downLoadData();">
在js中为
function downLoadData()
{
if(checkValid() == false){
return false;
}
tSQL ="select c.belongyear,c.belongquarter,c.recomname,c.recontcode,c.riskcode,c.costcernter,NVL(c.cessprem,0),NVL(c.reprocfee,0),NVL(c.claimbackfee,0),NVL(c.adjustfee,0),NVL(c.balancelend,0),c.year,c.month from LRJSDetail c where 1=1 "
+getWherePart('belongyear','belongyear')
+getWherePart('belongquarter','belongquarter')
+getWherePart('recontcode','recontcode')
+getWherePart('riskcode','riskcode')
+getWherePart('recomname','recomname')
+getWherePart('costcernter','costcernter')
+getWherePart('year','year')
+getWherePart('month','month')
; tSQL+=" order by c.belongquarter,c.recomname,c.recontcode,c.riskcode,c.costcernter";
fm.action="./LRJSDetailDownload.jsp?querySql="+tSQL;
fm.submit();
}
把数据提供并访问LRJSDetailDownload.jsp
对于传过去的form表单中的数据如何获取呢?
比如说一个table中
<table class= common border=0 width=100%>
<TR class= common>
<TD class= title>起始日期</TD>
<TD class= input>
<Input name=StartDate class='coolDatePicker' dateFormat='short' verify="起始日期|notnull&Date" elementtype=nacessary>
</TD>
<TD class= title>终止日期</TD>
<TD class= input>
<Input name=EndDate class='coolDatePicker' dateFormat='short' verify="终止日期|notnull&Date" elementtype=nacessary>
</TD> </TR>
<TR class= common>
<TD class= title>再保合同号</TD>
<TD class= input>
<Input class= common name="ReContCode" id="ReContCode" >
</TD>
<TD class= title>险种号</TD>
<TD class= input>
<Input class= common name="RiskCode" id="RiskCode" >
</TD>
</TR>
<TR class= common>
<TD class= title>团单号</TD>
<TD class= input>
<Input class= common name="GrpContNo" id="GrpContNo" >
</TD>
<TD class= title>个单号</TD>
<TD class= input>
<Input class= common name="ContNo" id="ContNo" >
</TD>
</TR>
<TR class= common>
<TD class= title>PolNo</TD>
<TD class= input>
<Input class= common name="PolNo" id="PolNo" >
</TD>
<TD class= title>操作者</TD>
<TD class= input>
<Input class= common name="Operator" id="Operator" >
</TD>
</TR>
</table>
对于其中的input标签 有一个name= ReContCode,value就是你填入输入框中的值
那么你取数据就这样取
在你提交表格的jsp中
<% String tStartDate=request.getParameter("StartDate");
String tEndDate=request.getParameter("EndDate");
String tReContCode=request.getParameter("ReContCode");
String tRiskCode=request.getParameter("RiskCode");
String tGrpContNo=request.getParameter("GrpContNo");
String tContNo=request.getParameter("ContNo");
String tPolNo=request.getParameter("PolNo");
String tOperator=request.getParameter("Operator");
%>
本质上就是将数据放入到了request对象中了;注意要有这个<% %>
那么tomcat是如何解析jsp的呢?
现在看工程的实现tomcat/webapp/app1/WEB-INF/下面有一个go.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
${item}
</body>
</html>
url访问地址
http://localhost:8080/app1/go
配置应用内web.xml
<web-app>
<servlet>
<servlet-name>Modern</servlet-name>
<servlet-class>ModernServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Primitive</servlet-name>
<servlet-class>PrimitiveServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>gojsp</servlet-name>
<jsp-file>/WEB-INF/go.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Modern</servlet-name>
<url-pattern>/Modern</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Primitive</servlet-name>
<url-pattern>/Primitive</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>gojsp</servlet-name>
<url-pattern>/go</url-pattern>
</servlet-mapping>
</web-app>
能比较发现对于jsp文件的配置是和servlet不一样的,servlet有一个servlet-class的属性值,
现在描述一个实现过程
- 第一步读取web.xml文件,在app1的standardcontext中生成俩重要信息
- HashMap servletMappings 这里面是
- 为每个servlet生成一个standardWrapper,并且放到standarcontext的children变量内

那么当我们浏览器中开始访问go时候
connector 调用调用engine的invoke==>调用host.invoke==>调用context.invoke==>调用wrapper.invoke
调用standardwrappervalue.invoke,
==>进入 instance = loadServlet();

进入

这里就是关键,如果是jsp的wrpper他是没有dervletClass的所以进入到if括号内
Wrapper jspWrapper = (Wrapper) ((Context) getParent()).findChild(Constants.JSP_SERVLET_NAME);
public static final String JSP_SERVLET_NAME = "jsp";
这句话是在context内找一个叫jsp的wrapper,这个wrapper是哪里来的呢?答案是tomcat/conf/web.xml文件目录下定义的
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</param-value>
</init-param>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
那么其实找到的就是
这个org.apache.jasper.servlet.JspServlet的servlet 现在和go.jsp还没建立联系呢
接着进入
入service方法

那么进入了JspServlet类内部了

最后

新建了个JspServletWrapper,

进入到jsp对应的servlet,
package org.apache.jsp; import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*; public class go_jsp extends HttpJspBase { private static java.util.Vector _jspx_includes; public java.util.List getIncludes() {
return _jspx_includes;
} public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException { JspFactory _jspxFactory = null;
javax.servlet.jsp.PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null; try {
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out; out.write("\n<html>\n<body>\n${msg}\n</body>\n</html>\n");
} catch (Throwable t) {
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (pageContext != null) pageContext.handlePageException(t);
} finally {
if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);
}
}
}
那么整个就分析完成了,其实这里还提到tomcat是如何解析jsp的,和新建go_jsp.class文件的,和新建的路径在哪里
先说路径

在tomcat根目录的work文件夹中
在这里

编译 this.jspCompiler.isOutDated(),这里创建编译文件路径和确定是否已经编译过了,编译过了不会再次编译

看这个complier对象

进入

就不想看了

最后

然后是

先结束了吧,后面是看不下去了.
顺便记录下,el表达式本质上就是从request中根据key 取得value
深入刨析tomcat 之---第21篇 tomcat 对jsp页面支持的实现原理的更多相关文章
- 深入刨析tomcat 之---第13篇 tomcat的三种部署方法
writedby 张艳涛 一般我们都知道将web 应用打成war包,放到tomcat的webapp目录下,就是部署了,这是部署方法1 第2种部署方法我们也知道,就是讲web应用的文件夹拷贝到webap ...
- 深入刨析tomcat 之---第3篇 HTTP/1.1 长连接的实现原理
writedby 张艳涛 长连接是HTTP/1.1的特征之一,1.1出现的原因是因为一个客户请求一个网页,这是一个http请求,这个网页中如果有图片,那么也会变为一个http请求,对于java客户端, ...
- 深入刨析tomcat 之---第8篇 how tomcat works 第11章 11.9应用程序,自定义Filter,及注册
writed by 张艳涛, 标签:全网独一份, 自定义一个Filter 起因:在学习深入刨析tomcat的学习中,第11章,说了调用过滤链的原理,但没有给出实例来,自己经过分析,给出来了一个Filt ...
- 深入刨析tomcat 之---第2篇,解决第3章bug 页面不显示内容http://localhost:8080/servlet/ModernServlet?userName=zhangyantao&password=1234
writedby 张艳涛7月2日, 在学习第4张的过程中,发现了前一篇文章写的是关于1,2张的bug不用设置response响应头,需要在servlet的service()方法里面写是错误想 serv ...
- 深入刨析tomcat 之---第14篇 对应19章,使用manager管理 web应用
writedby 张艳涛 第19章讲的是管理程序,当一个tomcat启动的时候,能通过远程浏览器能访问tomcat,启动web应用,关闭web应用,查看web应用 怎么实现的呢? 在webapp 文件 ...
- Orchard 刨析:导航篇
之前承诺过针对Orchard Framework写一个系列.本应该在昨天写下这篇导航篇,不过昨天比较累偷懒的去玩了两盘单机游戏哈哈.下面进入正题. 写在前面 面向读者 之前和本文一再以Orchard ...
- 30s源码刨析系列之函数篇
前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ...
- 温故知新-多线程-深入刨析volatile关键词
文章目录 摘要 volatile的作用 volatile如何解决线程可见? CPU Cache CPU Cache & 主内存 缓存一致性协议 volatile如何解决指令重排序? volat ...
- Orchard 刨析:Logging
最近事情比较多,有预研的,有目前正在研发的,都是很需要时间的工作,所以导致这周只写了两篇Orchard系列的文章,这边不能保证后期会很频繁的更新该系列,但我会写完这整个系列,包括后面会把正在研发的东西 ...
随机推荐
- HashMap 中7种遍历方式的性能分析
随着 JDK 1.8 Streams API 的发布,使得 HashMap 拥有了更多的遍历的方式,但应该选择那种遍历方式?反而成了一个问题. 本文先从 HashMap 的遍历方法讲起,然后再从性能. ...
- 从零实操基于WSL2 Docker部署Asp.Net Core项目
前言 平日在公司里都是基于阿里Teambition中的飞流进行Docker部署Api项目或服务,已经习惯了那一套成熟的操作流程,开发和部署确实快捷方便,但是还没在自己的电脑上进行操作过,特别是Wind ...
- Mysql在线DDL
1. Mysql各版本DDL方式 1.1 MysqlDDL演进 当mysql某个业务表上有未提交的活动事务的时候,你去执行在线DDL,这相当危险,直接会被卡住,show processlist里面会 ...
- 试着给VuePress添加登录授权支持,基于v-dialogs
背景介绍 VuePress是个不错的能基于Markdown快速构建静态网站的框架,初步来说,对外访问都是透明的. 但是可能因为一些保密需要,有些站点的文档,我们希望控制一下访问,所以我们借着别人的轮子 ...
- 15.3、mysql之InnoDB和MyISAM表空间详解
15.3.1.InnoDB引擎表空间: 1.表空间分类: 共享表空间: 某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在 data目录下. 默认的文件名为:ibd ...
- 教你几招HASH表查找的方法
摘要:根据设定的哈希函数 H(key) 和所选中的处理冲突的方法,将一组关键字映象到一个有限的.地址连续的地址集 (区间) 上,并以关键字在地址集中的"象"作为相应记录在表中的存储 ...
- 题解 P5327 [ZJOI2019]语言
P5327 [ZJOI2019]语言 解题思路 暴力 首先讲一下我垃圾的 40pts 的暴力(其他 dalao 都是 60pts 起步): 当然评测机快的话(比如 LOJ 的),可以卡过 3,4 个点 ...
- ACdream 1007 a+b 快速幂 java秒啊,快速幂 避免 负数移位出错
a + b ( sigma (ai^x) ) % mod 1 import java.util.*; 2 import java.math.*; 3 import java.io.*; 4 p ...
- linux sort uniq命令详解
sort 功能说明:将文本文件内容加以排序,sort可针对文本文件的内容,以行为单位来排序. sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+&l ...
- Acunetix临时扫描是不够的
Web漏洞扫描程序通常被视为即席工具.最初,所有漏洞扫描程序都是这种工具,并且当前的开源Web应用程序安全解决方案仍遵循该模型.但是,随着Web技术的复杂性和可用性的大幅增加,临时模型已经过时,无法满 ...