JSP编译成Servlet(三)JSP编译后的Servlet
JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什么样。
①HelloWorld.jsp
<%@ page contentType="text/html; charset=gb2312" language="java" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>HelloWorld</TITLE>
</HEAD>
<BODY>
<%
out.println("HelloWorld");
%>
</BODY>
</HTML>
②HelloWorld_jsp.java
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class HelloWorld_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=gb2312");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n");
out.write("<HTML>\r\n");
out.write(" <HEAD>\r\n");
out.write(" <TITLE>HelloWorld</TITLE>\r\n");
out.write(" </HEAD>\r\n");
out.write("<BODY>\r\n");
out.println("HelloWorld");
out.write("\r\n");
out.write("</BODY>\r\n");
out.write("</HTML>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
经过前面介绍的语法解析及使用访问者模式对HelloWorld.jsp文件编译成相应的HelloWorld_jsp.java文件,可以看到Servlet类名是由jsp文件名_jsp拼成。再往下看HelloWorld_jsp.java文件的详细内容,类包名默认为org.apache.jsp,默认有三个导入“import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;”。
接下去是真正的类主体,jsp生成的java类都必须继承org.apache.jasper.runtime.HttpJspBase,这个类的结构图如下,继承了HttpServlet是为了将HttpServlet的所有功能都继承下来,另外又实现HttpJspPage接口定义了一个JSP类的Servlet的核心处理方法_jspService,除此之外还有_jspInit和_jspDestroy用于在jsp初始化和销毁时执行,这些方法其实都是由Servlet的service、init、destroy方法间接去调用,所以jsp生成servlet主要就是实现这三个方法。
除了继承HttpJspBase外还需实现org.apache.jasper.runtime.JspSourceDependent接口,这个接口只有一个返回Map<String,Long>类型的getDependants()方法,Map的键值分别为资源名和最后修改时间,这个实现主要是为了记录某些依赖资源是否过时,依赖资源可能是page指令导入的也可能是标签文件引用等。在生成servlet时如果jsp页面做了上述依赖的话则会在servlet类中添加一个static块,static块会将资源及最后修改时间添加到Map中。
在jsp类servlet处理过程中会依赖很多资源,比如我要操作会话的话就需要此次访问的HttpSession对象,比如我要操作Context容器级别的对象就要ServletContext对象,再比如我要获取servlet配置信息就要ServletConfig对象,最后还需要一个输出对象用于在处理过程中将内容输出。这些对象都在核心方法_jspService中使用,作为servlet类要获取这些对象其实非常简单,因为这些本身就属于servlet属性,有相关方法直接获取。但这里因为JSP有自己的标准,所以必须按照它的标准去实现。
具体的JSP标准是怎样的?首先,为了方便JSP的实现提供一个统一的工厂类JspFactory用于获取不同的资源;其次,由于按照标准规定不能直接使用servlet上下文,所以需要定义一个PageContext类封装servlet上下文;最后,同样按照标准需要定义一个输出类JspWriter封装servlet的输出。所以可以看到PageContext对象通过JspFactory获取,其他ServletContext对象、ServletConfig对象、HttpSession对象及JspWriter则通过PageContext对象获取。通过这些对象再加上前面章节语法解析得到的语法树对象,再利用访问者模式对语法树遍历就可以生成核心处理方法_jspService了。
上面只是介绍了最简单的一个jsp页面转变成servlet的过程,旨在说明jsp到servlet转化的原理,实际上需要处理很多jsp指令标签。
喜欢java的同学可以交个朋友
JSP编译成Servlet(三)JSP编译后的Servlet的更多相关文章
- Mac上把python源文件编译成so文件
把python源文件编译成so文件 前言 实际上属于一种代码混淆/加密的技术,大家知道python的源文件放在那里,大家是都可以看的,不像C语言编译出来可以拿编译后的东西去运行,所以就出现了这种需求. ...
- 【CLR via C#】CSC将源代码编译成托管模块
下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模块(managedmod ...
- android NDK编译(导入).a文件和编译多个so文件(转)
源:android NDK编译(导入).a文件和编译多个so文件 一.编译一个静态库 libstatic_android.a LOCAL_PATH := $(call my-dir) include ...
- JSP编译成Servlet(五)JDT Compiler编译器
通过JSP编译器编译后生成了对应的java文件,接下去要把Java文件编译成class文件.对于这部分完全没有必要重新造轮子,常见的优秀编译工具有Eclipse JDT Java编译器和Ant编译器. ...
- JSP编译成Servlet(四)JSP与Java行关系映射
我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class ...
- JSP编译成Servlet(一)语法树的生成——语法解析
一般来说,语句按一定规则进行推导后会形成一个语法树,这种树状结构有利于对语句结构层次的描述.同样Jasper对JSP语法解析后也会生成一棵树,这棵树各个节点包含了不同的信息,但对于JSP来说解析后的语 ...
- jsp页面编译成Servlet类文件
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.js ...
- weblogic对JSP预编译、weblogic读取JSP编译后的class文件、ant中weblogic.jspc预编译JSP
我们都知道在weblogic中JSP是每次第一次访问的时候才会编译,这就造成第一次访问某个JSP的时候性能下降,有时候我们也希望JSP被编译成class然后打包在jar中实现隐藏JSP的功能,下面介绍 ...
- JSP常见的三个编译指令
JSP常见的三个编译指令 1.page指令 是针对当前页面的指令 2.include指令 用于指定包含另一个页面 3.taglib指令 用于定义和访问自定义标签
随机推荐
- vue--"卡片层叠" 组件 开发小记
背景:影城移动点餐web App增加会员卡支付功能 需求:确认订单页点击会员卡项弹出会员卡列表,多张会员卡依次叠加覆盖上一张80%的高度,点击任意卡片则改卡片置为当前卡片,只有当前卡片显示全部卡片信息 ...
- js密码64加密
可以在客户端对密码进行简单的64位加密,服务端对应使用64位解密即可. /** * * Base64 encode / decode * * @author * @date * @email */ f ...
- python学习之路网络编程篇(第五篇)
paramiko简介 paramiko 是基于Python实现的SSH2远程安装连接,支持认证及秘钥方式.可以实现远程命令执行.文件传输.中间SSH代理等功能. paramiko安装 #!/bin/b ...
- ACM Curling 2.0
在行星MM-21上,今年奥运会之后,冰壶(curling)越来越受欢迎. 但规则与我们有所不同. 该游戏是在冰盘上进行的,在冰棋盘上标有方形网格.他们只用一块石头. 游戏的目的是以最少的动作( th ...
- JAVA中的常量定义在class中还是interface中比较合理?
本文地址:http://blog.csdn.net/sushengmiyan 本文作者:苏生米沿 java中使用的常量可以集中定义在一个文件中. 有两种解决方案: 1.在Constants.java中 ...
- 基于AOP的iOS用户操作引导框架设计
背景 有一种现象,App设计者觉得理所当然的操作方式,却常常被用户所忽视,为了防止这种现象发生,就要为App设计一个帮助,一种低成本的方案是将帮助文档写成HTML然后展示给用户,这样的方式常常不能带来 ...
- 剑指Offer——联通研究院笔、面试题 (Offer已收割)
剑指Offer--联通研究院笔.面试题 1.二叉树适宜存储什么样的数据? 树最适合用来表示( C ). A.有序数据元素 B.无序数据元素 C.元素之间具有分支层次关系的数据 D.元素之间无联系的数据 ...
- APP中一种在Java层实现的简单守护进程方式
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52779986 守护进程是一个黑色 ...
- 11 吐司 Toast 代码案例
package com.qf.day11_toast_demo05; import android.app.Activity; import android.graphics.Color; impor ...
- AMH 5.X下安装 Flarum
如果移动端访问不佳,请尝试–>Github版 背景 最近无意间发现几个开源软件的Bug反馈系统使用的是Flarum,Flarum是一款优雅简洁论坛软件,看起来还是相当不错的,一时抑制不住想要尝试 ...