使用嵌入式 Tomcat 简化程序调试
来源:互联网 发布:package.json scripts 编辑:程序博客网 时间:2024/05/22 12:28
原文:http://www.blogcn.com/User8/flier_lu/blog/4740621.html
在开发基于 Tomcat 的 Web 程序时,一个比较头痛的问题就是如何将以接口分离的后台服务与前台页面进行联调。以 Tomcat 为中心的运行环境中虽然能够支持 IDE 直接进行跟踪调试,但配置麻烦、速度较慢且限制很多,总不如直接对后台程序进行调试来的方便。
一个较好的解决方法,是利用 Tomcat 的嵌入式版本,将 Tomcat 反过来嵌入到后台服务中,以后台服务为主进行调试。这样一来 Tomcat 从整体容器变为后台服务的一种,在不改变行为的前提下,能够自行定制调试环境。例如笔者开发的一个后台服务调试环境,支持基于命令行的简便移用的调试命令,直接对各种后台服务进行控制,并通过前台界面验证结果,大大减轻了整合时的调试难度。
虽然普通配置的 Tomcat 理论上也可以直接嵌入到后台程序,但推荐还是使用 Tomcat 定制的 Embeded 版本,这样集成度更高且性能较好。同时因为代码完全相同,不会存在调试环境内外的功能上的差异问题。
Tomcat 5.0.28 Embed tar.gz
在解压 Tomcat Embed 版本后,将其 lib 目录下所有 .jar 文件加入到 Java 项目的 classpath 中,就可以着手在 Java 程序中启动 Tomcat 了。与普通的 Tomcat 配置类似,其运行需要创建如下组织的结构:
只不过平时是配置 web.xml,而在嵌入版本中直接以程序方式完成。
首先是建立 Tomcat 服务器,并指定其运行目录,此目录最好与 Tomcat Embed 版本路径相同。
然后创建缺省 Engine 和 Host,并将 Host 加入到 Engine 中。这里的名字只是起到标记作用,但 Host 的路径最好与 tomcat 路径保持一致。同一 Engine 实际上是可以有多个虚拟 Host 的,对大型站点的自动测试可以将之分离进行。
对 Host 的内容填充,实际上就是具体 Web 应用程序的环境的建立过程。首先应该有一个缺省的 Context,在 URL 路径不匹配的时候会被使用。缺省 Context 的虚拟路径可以被设置为 "",内部实现时自动转换为 "/";而其物理路径可以直接使用 Tomcat 自带的 /webapps/ROOT 内容,或者使用自定义内容。
值得注意的是这里设置 ROOT 为特权程序,其区别主要在于 Context 容器的 ClassLoader 等。具体细节有兴趣的朋友可以参考 Tomcat 中关于 classloading 的文档
而对用户自己的 WebApp 实际上并不限于相同目录,完全可以任意设置,使用与创建 ROOT 程序类似的方式即可。
最后需要创建合适的 Connector 接受 http/https 请求。推荐将 web 服务绑定在本地 loopback 地址上,限制只能本机访问。
完整的嵌入式 Tomcat 创建代码示例如下:
然后就可以在合适的时候调用其 start/stop 方法启动或停止服务,感觉比标准配置的 tomcat 反映迅速许多。
此外可以通过一个辅助类的方法 ServerInfo.getServerInfo() 获取当前 Tomcat 版本信息用于显式状态
在此过程中有一些需要注意的细节问题。
1.运行此程序时需要使用 JDK 而非 JRE,因为 Tomcat 需要动态编译 JSP 页面,可能还需要手工把 JDK 的 /lib/tools.jar 加入到项目 classpath 中。
2.因为嵌入式版本 Tomcat 没有 common/lib 目录,如果碰到 JAXP 的 Provider 没有找到的 bug,可能需要直接将 xercesImpl.jar 等实现包复制到 JDK 的 /jre/lib/endorsed 目录下。
3.注意 classpath 中不要有其他版本 tomcat 的包,否则可能会出现冲突。
如果需要进一步了解相关信息,可以参考 Tomcat 自带 JavaDoc 文档,或者 O'Reilly 的 Embedding Tomcat Into Java Applications 一文。
在开发基于 Tomcat 的 Web 程序时,一个比较头痛的问题就是如何将以接口分离的后台服务与前台页面进行联调。以 Tomcat 为中心的运行环境中虽然能够支持 IDE 直接进行跟踪调试,但配置麻烦、速度较慢且限制很多,总不如直接对后台程序进行调试来的方便。
一个较好的解决方法,是利用 Tomcat 的嵌入式版本,将 Tomcat 反过来嵌入到后台服务中,以后台服务为主进行调试。这样一来 Tomcat 从整体容器变为后台服务的一种,在不改变行为的前提下,能够自行定制调试环境。例如笔者开发的一个后台服务调试环境,支持基于命令行的简便移用的调试命令,直接对各种后台服务进行控制,并通过前台界面验证结果,大大减轻了整合时的调试难度。
虽然普通配置的 Tomcat 理论上也可以直接嵌入到后台程序,但推荐还是使用 Tomcat 定制的 Embeded 版本,这样集成度更高且性能较好。同时因为代码完全相同,不会存在调试环境内外的功能上的差异问题。
Tomcat 5.0.28 Embed tar.gz
在解压 Tomcat Embed 版本后,将其 lib 目录下所有 .jar 文件加入到 Java 项目的 classpath 中,就可以着手在 Java 程序中启动 Tomcat 了。与普通的 Tomcat 配置类似,其运行需要创建如下组织的结构:
|
只不过平时是配置 web.xml,而在嵌入版本中直接以程序方式完成。
首先是建立 Tomcat 服务器,并指定其运行目录,此目录最好与 Tomcat Embed 版本路径相同。
|
然后创建缺省 Engine 和 Host,并将 Host 加入到 Engine 中。这里的名字只是起到标记作用,但 Host 的路径最好与 tomcat 路径保持一致。同一 Engine 实际上是可以有多个虚拟 Host 的,对大型站点的自动测试可以将之分离进行。
|
对 Host 的内容填充,实际上就是具体 Web 应用程序的环境的建立过程。首先应该有一个缺省的 Context,在 URL 路径不匹配的时候会被使用。缺省 Context 的虚拟路径可以被设置为 "",内部实现时自动转换为 "/";而其物理路径可以直接使用 Tomcat 自带的 /webapps/ROOT 内容,或者使用自定义内容。
|
值得注意的是这里设置 ROOT 为特权程序,其区别主要在于 Context 容器的 ClassLoader 等。具体细节有兴趣的朋友可以参考 Tomcat 中关于 classloading 的文档
|
而对用户自己的 WebApp 实际上并不限于相同目录,完全可以任意设置,使用与创建 ROOT 程序类似的方式即可。
最后需要创建合适的 Connector 接受 http/https 请求。推荐将 web 服务绑定在本地 loopback 地址上,限制只能本机访问。
|
完整的嵌入式 Tomcat 创建代码示例如下:
|
然后就可以在合适的时候调用其 start/stop 方法启动或停止服务,感觉比标准配置的 tomcat 反映迅速许多。
此外可以通过一个辅助类的方法 ServerInfo.getServerInfo() 获取当前 Tomcat 版本信息用于显式状态
在此过程中有一些需要注意的细节问题。
1.运行此程序时需要使用 JDK 而非 JRE,因为 Tomcat 需要动态编译 JSP 页面,可能还需要手工把 JDK 的 /lib/tools.jar 加入到项目 classpath 中。
2.因为嵌入式版本 Tomcat 没有 common/lib 目录,如果碰到 JAXP 的 Provider 没有找到的 bug,可能需要直接将 xercesImpl.jar 等实现包复制到 JDK 的 /jre/lib/endorsed 目录下。
3.注意 classpath 中不要有其他版本 tomcat 的包,否则可能会出现冲突。
如果需要进一步了解相关信息,可以参考 Tomcat 自带 JavaDoc 文档,或者 O'Reilly 的 Embedding Tomcat Into Java Applications 一文。
- 使用嵌入式 Tomcat 简化程序调试
- 使用嵌入式Tomcat简化程序调试
- 使用嵌入式Tomcat简化程序调试
- 使用嵌入式 Tomcat 简化程序调试
- 使用嵌入式 Tomcat 简化程序调试
- 使用eclipse进行调试嵌入式Linux程序
- 使用gdb+gdbserver调试嵌入式程序
- 嵌入式程序调试方案
- Ubuntu 下使用Eclipse编译、调试嵌入式程序的方法
- gdb远程调试嵌入式程序
- 社区版本idea如何使用tomcat插件调试程序
- eclipse下maven使用及tomcat调试manven程序
- 嵌入式(embed)Tomcat的使用
- 使用Hibernate Tool简化hibernate程序开发
- 使用泛型程序简化代码设计
- 使用do...while循环简化程序
- Eclipse+tomcat调试jsp程序
- Java技巧:用匿名类来实现简化程序调试
- 源码--删除指定目录下(包含子目录)的文件
- Eclipse 的字符串分区共享优化机制
- Visual C#.Net 网络程序开发-Socket篇
- 如何利用JDBC发送SQL语句,并取回多个结果集
- 忘记ROOT密码怎么办
- 使用嵌入式 Tomcat 简化程序调试
- .......................
- ORACLE语法中的INSERT INTO。。。SELECT。。。
- 使用JAVA中的动态代理实现数据库连接池
- 在 .NET 中获取 AD 上帐号密码过期时间
- 我的电子书架IV
- AndroMDA 3.0--开源的MDA方案
- 老板最爱“炒”的15种员工
- Oracle SQL依然无可替代--《Mastering Oracle SQL》