我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class文件的过程需要考虑的事情比较多,其中一个比较重要的就是调试问题,由于语法不一样,jsp某行执行的逻辑怎样与java文件对应起来,这样在JVM执行过程发生异常或错误才能找到JSP对应的行,提供一个友好的调试信息。类似的,jsp文件名编译后的java文件名同样也要有映射关系。

总的来说,为了解决从非java语言到java语言调试时文件名及行号映射的问题,java community process组织提出了JSR-45(Debugging Support for Other Languages)规范,它为非java语言提供了一个进行调试的标准机制。这里的JSP其实就是属于非java语言,JSP如果想要方便开发者开发,它就必须要遵循JSR-45规范。其实可以简单的说就是为了解决JSP编译后的java文件与JSP文件的对应关系,而且是提供一个统一的标准,从而避免不同厂商有不同的实现方式。

JSR-45规范的核心对象是资源映射表(Source Map),简称SMAP。在这里它是指JSP文件文件名及行号的映射表,这个映射表存放到class文件中,在基于JPDA的调试工具中就可以通过此映射表获取到对应JSP文件及行号,向开发者提示对应JSP文件的信息。

接下去以前面的HelloWorld.jsp例子看看SMAP映射表是如何映射的,HelloWorld.jsp文件被编译后变成HelloWorld_jsp.java文件,根据JSR-45的规范最终我们会生成一份如下的映射表,这里不打算探究SMAP的整个语法,只专注行号映射相关的部分,即从*L到*E中间的内容,其中1,10:62表示HelloWorld.jsp文件与HelloWorld_jsp.java的映射关系为1-62、2-63、3-64、...10-71。同样的,10,3:72表时的对应关系为10-72、11-73、12-74。有了这些映射表就可以方便地将java执行的行号与JSP的行号对应起来了。

SMAP

HelloWorld_jsp.java

JSP

*S JSP

*F

+ 0 HelloWorld.jsp

HelloWorld.jsp

*L

1,10:62

10,3:72

*E

说完SMAP,我们已经知道生成的SMAP的格式,那么要如何保存?保存到哪里呢?因为JVM只会通过Class文件去加载相关信息,所以唯一的办法是通过class文件附带SMAP消息,class文件格式中可以附带信息的就只有属性表集合,在class文件格式中其他数据项都有严格的长度、顺序和格式,而属性列表集合则没有严格要求,只要属性名不与已有属性冲突即可,任何人都可以往class文件的属性列表中写入自定义的属性,虚拟机会自动忽略不认识的属性,所以我们需要在支持调试信息的JVM中附带此属性,这里的属性名称就是SourceDebugExtension属性。这个属性的结构如下,首先2个字节表示名称的索引值,接着4个字节表示属性长度,最后一个数组表示属性值。按照格式写入class文件JVM即可识别。

SourceDebugExtension_attribute {

u2 attribute_name_index;

u4 attribute_length;

u1 debug_extension[attribute_length];

}

通过JSR45标准解决了JSP到java之间的映射关系问题,从而让调试更加方便。在Java的世界中为了达到统一而又不失灵活,基本都是由java community process制定规范然后由厂商按照规范进行实现。

JSP编译成Servlet(四)JSP与Java行关系映射的更多相关文章

  1. JSP编译成Servlet(三)JSP编译后的Servlet

    JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什 ...

  2. JSP编译成Servlet(五)JDT Compiler编译器

    通过JSP编译器编译后生成了对应的java文件,接下去要把Java文件编译成class文件.对于这部分完全没有必要重新造轮子,常见的优秀编译工具有Eclipse JDT Java编译器和Ant编译器. ...

  3. JSP编译成Servlet(一)语法树的生成——语法解析

    一般来说,语句按一定规则进行推导后会形成一个语法树,这种树状结构有利于对语句结构层次的描述.同样Jasper对JSP语法解析后也会生成一棵树,这棵树各个节点包含了不同的信息,但对于JSP来说解析后的语 ...

  4. JSP编译成Servlet(二)语法树的遍历——访问者模式

    语法树可以理解成是一种数据结构,假如某些语句已经被解析成一棵语法树,那么接下来就是要对此语法树进行处理,但考虑到不将处理操作与数据结构混合在一块,我们需要一种方法将其分离.其实对于语法树的处理最典型的 ...

  5. Servlet和JSP之有关Servlet和JSP的梳理(一)

    大二第一学期的时候有学JSP的课,但是因为在开学之前做过JSP的小项目,所以一个学期的课也没听,直到期末考试成绩出来了,才回想JSP的内容还有多少记得,没想到模模糊糊也记不起多少,赶紧回头学回来.接下 ...

  6. jsp页面编译成Servlet类文件

    package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.js ...

  7. Servlet和JSP之有关Servlet和JSP的梳理(二)

    JSP JSP页面本质上是一个Servlet,JSP页面在JSP容器中运行,一个Servlet容器通常也是JSP容器. 当一个JSP页面第一次被请求时,Servlet/JSP容器主要做一下两件事情: ...

  8. JSP转译成Servlet详细过程【转】

    JSP转译成Servlet详细过程 JSP是Servlet的扩展,在没有JSP之前,就已经出现了Servlet技术.Servlet是利用输出流动态生成HTML页面,包括每一个HTML标签和每个在HTM ...

  9. 图解 servlet 与jsp的关系

    Servlet是Java提供的用于开发Web服务器应用程序的一个组件,运行在服务器端,由Servlet容器所管理,用于生成动态的内容.Servlet是平台独立的Java类,编写一个Servlet,实际 ...

随机推荐

  1. cannot open file "cxcore.lib"

    运行例子程序的时候总是出现连接错误:LINK : fatal error LNK1104: cannot open file "cxcore.lib". 在VC选项里把C:\Pro ...

  2. Angular4.0入门

    angular与其他的差别 angular cli安装 cnpm install -g @angular/cli 最新版本 cnpm uninstall -g @angular/cli 卸载全局版本 ...

  3. Linux shell爬虫实现树洞网自动回复Robot

    奇怪的赞数 人生在世,不如意事十之八九,可与言者无二三人.幸好我们生在互联网时代,现实中找不到可以倾诉的人还可以在网络上寻找发情绪宣泄口,树洞这类产品就是提供一个让人在网络上匿名倾诉的平台. 我是偶然 ...

  4. JVM初探- 内存分配、GC原理与垃圾收集器

    JVM初探- 内存分配.GC原理与垃圾收集器 标签 : JVM JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收. 除了在概念 ...

  5. Bootstrap3 排版-地址

    让联系信息以最接近日常使用的格式呈现.在每行结尾添加 可以保留需要的样式. Twitter, Inc. 795 Folsom Ave, Suite 600 San Francisco, CA 9410 ...

  6. Tomcat7源码环境搭建

    一.下载Tomcat7源码 从官网上下载Tomcat源码,   http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.70/src/apache-t ...

  7. [CSDN_Markdown] 使用CSDN Markdown编辑器

    简介 最近CSDN支持Markdown语法写博客了,甚是欢喜.前几天写了一篇实验了下,感觉不错.准备写几篇文章介绍一下如何使用CSDN的Markdown编辑器写博客,不求全面,但求够用,望大家批评指正 ...

  8. Swift中if与switch语句使用一例

    在Swift中相同的条件处理有if和switch两个语句,我们如何取舍呢? 一种情况下我们只在乎x是否在一个范围内,但并不关心x是否穷尽!换句话说不关心在满足范围条件的其他情况下,此时我们可以考虑用i ...

  9. Xcode Organizational Identifiers

    操作系统(不管是iOS或是OS X)使用bundle标识去唯一标识你的应用.Bundle标识由一个组织id和你App的名字组成. 一般的,组织id是你域名的反转.如果你的域名是example.com那 ...

  10. nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解

    1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...