JSON

嵌入式Tomcat:提示、技巧和秘籍

字号+ 作者:H5之家 来源:H5之家 2017-04-19 16:01 我要评论( )

嵌入式Tomcat的API非常方便,只需要几行代码就可以在应用程序中启动Tomcat实例。用户很容易地从Apache Tomcat中得到有用的特性,并应用到自己的应用程序中。

本文由 ImportNew - 李阳 翻译自 kishanthan。欢迎加入翻译小组。转载请见文末要求。

嵌入式Tomcat的API非常方便,只需要几行代码就可以在应用程序中启动Tomcat实例。用户很容易地从Apache Tomcat中得到有用的特性,并应用到自己的应用程序中。

在大多数情况下,用户期望嵌入式Tomcat以与独立Tomcat的运行方式相同。例如,如果他们想要改变全局服务器配置,希望可以使用同样的sever.xml应用到嵌入式Tomcat。

但是当使用嵌入式Tomcat时,会发现他们是不支持即插即用。你必须对使用一些秘籍(Hack)进行改善将其集成到应用程序中,使它得到更充分的利用。

嵌入式Tomcat中一些实用的特性并不支持即插即用:

在这篇文章里,我将解释在使用嵌入式Tomcat时克服上述局限的一些技巧和窍门。

Tomcat类用来在应用程序中嵌入Tomcat。但最好用我们自己的方式扩展这个类,这将使得我们可以自由重写一些需要自定义的重要方法。下面是克服上述局限的一些技巧:

1、支持服务器描述符(server.xml)

在一个标准的服务器实例中,可以通过Catalina类读取、解析和初始化sever.xml。它创建了一个Digester类的实例,把sever.xml文件转化成文件流。在继承的Tomcat类中,我们可以创建一个继承Catalina的内部类,然后重载创建Digester实例的方法就可以了。

private static class MyExtendedCatalina extends Catalina { @Override public Digester createStartDigester() { return super.createStartDigester(); } }

可以使用这个方法读取sever.xml作为输入流:

Digester digester = extendedCatalina.createStartDigester(); digester.push(extendedTomcat); try { digester.parse(inputStreamOfServerXml); } catch (IOException e) { log.error("Error while parsing server.xml", e); }

可以看出,在初始阶段Digester 实例和Tomcat 实例共同作用,按照一定顺序自动运行。上述代码片应当在扩展后的Tomcat实例初始化阶段执行。

2、支持全局部署描述符(web.xml)

全局部署描述也就是所谓的root(默认的Webapps部署描述符)。Webapps从web.xml中继承了默认值,并使用应用特定部署描述符的值进行覆盖。这个文件提供了一些便利,比如可以为Webapps定义一些全局属性(默认会话超时等)。

为了把web.xml添加到所有Webapp中,必须覆盖Tomcat类的“addWebapp”方法,然后添加以下代码到重写(Overridden)后的方法。

Context context = null; try { context = new StandardContext(); context.setName(contextPath); context.setPath(contextPath); context.setDocBase(webappFilePath); context.setRealm(this.getHost().getRealm()); ContextConfig contextConfig = new ContextConfig(); context.addLifecycleListener(contextConfig); if (new File(pathToGlobalWebXml).exists()) { contextConfig.setDefaultWebXml(pathToGlobalWebXml); } else { // 1 contextConfig.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML"); } host.addChild(context); } catch (Exception e) { log.error("Error while deploying webapp", e); }

上面的代码在服务器主机上添加并部署了一个子应用Webapp,Tomcat类的“addWebapp”方法也具有同样的功能。但是需要注意的是(代码1),在上述代码中我们使用setDefaultWebXml方法将web.xml设置到当前webapp的上下文中。在通常Tomcat类的addWebapp方法中,总是将其设置成NO_DEFAULT_XML。

3 、支持Webapp特定上下文描述符 (context.xml)

使用全局web.xml时,还有一个非常实用的特性:用户可以在文件中为自己的Webapp添加一些元数据。这些信息同样会添加到Webapp的META-INF目录中。通常会用来添加环境资源信息,例如数据源、JNDI资源、阀门(Valve)、类加载器等Webapp特定信息。为了使用此特性,应该在主机对象(host object)调用“addChild”方法前,添加下面代码段到Tomcat类中重写的“addWebapp”方法。

JarFile webappWarFile = new JarFile(webappFilePath); JarEntry contextXmlFileEntry = webappWarFile.getJarEntry("META-INF/context.xml"); if (contextXmlFileEntry != null) { // 2 context.setConfigFile(new URL("jar:file:" + webappFilePath + "!/" + "META-INF/context.xml")); }

应该注意的是(代码2),它调用了Webapp中context对象的setConfigFile方法,反过来将context.xml描述符添加到Webapps的上下文中。

总结

上述三种特性是通常的Tomcat环境中最常用的。通过学习上述技巧,可以克服在使用嵌入式Tomcat时所遇到的问题。可以进一步拓展这些技巧以获取更多的特性,例如支持全局context.xml等。

原文链接: kishanthan 翻译: ImportNew.com - 李阳
译文链接:
[ 转载请保留原文出处、译者和译文链接。]

关于作者: 李阳

(新浪微博:@蠡暘)

查看李阳的更多文章 >>

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • WordPress实现更新主题提示

    WordPress实现更新主题提示

    2016-10-08 12:00

  • 华清远见嵌入式学院

    华清远见嵌入式学院

    2016-09-30 15:00

  • js对象转换json数组 『Word2007技巧』转换嵌入式 的相关知识

    js对象转换json数组 『Word2007技巧』转换嵌入式 的相关知识

    2016-08-16 13:00

  • IE浏览器返回JSON数据提示下载的解决办法

    IE浏览器返回JSON数据提示下载的解决办法

    2016-01-18 15:13

网友点评