Ringo.js嵌入集成:java-web应用嵌入JsgiServlet

来源:互联网 发布:php 小端转大端 编辑:程序博客网 时间:2024/04/29 12:32

  从这篇开始会逐渐介绍集成改造Ringo.js成为我心目中的东西,而不光是学习使用。

  ringo.js作为一个基于jvm的运行时,与java交互是非常重要的部分。但是,官方文档主要描述ringo作为运行时如何利用底层java库。而我其实需要的是ringo如何嵌入到已有java运行框架。

  找了半天,终于有一个切入点:jsgi集成。

  jsgi:

  jsgi是啥?osgi?不是,完全不是。jsgi来源是wsgi,python的web框架标准。jsgi同样也是common-js的标准之一。

  此外这里是扩展阅读:http://www.sitepen.com/blog/2010/01/19/commonjsjsgi-the-emerging-javascript-application-server-platform/

  JsgiServlet类

  ok既然Ringo.js实现了jsgi,其必然存在一个调用入口。这个就是这次主要讲的JsgiServlet类。显而易见,是一个Servlet实现,那么它本身可以配置到web.xml并设置webpath接管部分入口访问路径。其实我主要目的是研究它内部如何实现,以便更好实现集成目标。而现在主要描述它怎么工作,当然其中一些内容是阅读了源码之后才知道的。官方似乎没有提供直接的文档。

  另外提一句,整体查看代码时,可做为样例程序的类有两个:JsgiServlet以及RingoShell。httpServer模块使用时JsgiServlet会被默认使用。这也是Ringo.js入门中helloWorld例子的request处理部分如此写法原因。

  集成使用JsgiServlet

 而这里主要是想描述一下JsgiServlet嵌入已有javaweb的使用方式。

1.将rhino包以及ringo-core jar包(还有ringo-module jar包)放入web应用目录WEB-INF/lib目录下。

 ringo-module包内部其实是默认的module实现,与下载的ringo-home目录下的module目下内容一致。这个包主要是为了当engine在home目录下找不到module等系统模块库路径时,自动从默认jar包中读取。

2.将JsgiServlet注册到web.xml

<!-- ringojs路径准发以及执行容器入口 --><servlet><servlet-name>ringo</servlet-name><servlet-class>org.ringojs.jsgi.JsgiServlet</servlet-class><init-param><description></description><param-name>optlevel</param-name><param-value>0</param-value></init-param><!-- jsgi应用作为cj模块的模块id,可以直接对应到应用(模块)文件名称。模块查找方式根据cj模块(require)标准进行。 --><init-param><param-name>app-module</param-name><param-value>main</param-value></init-param><!-- 应用名称,在jsgi内部其实就是jsgi入口Function的名称(其实按照jsgi标准jsgi应用其实首先是这个Function。)。该函数由cj模块exports导出即可。 --><init-param><param-name>app-name</param-name><param-value>app</param-value></init-param><!-- ringo home位置,用于ringo导入资源等。 --><init-param><param-name>ringo-home</param-name><param-value>/WEB-INF</param-value></init-param><!-- 应用级模块位置。jsgi应用本身也是一种特定规范的模块,基于cj模块标准。 --><init-param><param-name>module-path</param-name><param-value>WEB-INF/app</param-value></init-param><init-param><param-name>production</param-name><param-value>false</param-value></init-param><init-param><param-name>verbose</param-name><param-value>false</param-value></init-param><init-param><param-name>legacy-mode</param-name><param-value>false</param-value></init-param></servlet><servlet-mapping><servlet-name>ringo</servlet-name><url-pattern>/rjs/*</url-pattern></servlet-mapping>
这个配置我写的比官方的复杂的多。其实官方的文档中没有描述其实这个servlet有很多参数可配置。其中有一些非常重要。我是阅读代码时才知道的。

3.创建web注册时配置的应用:WEB-INF/app/main.js

export("app");function app(request){print("do requset...");    return {        status: 200,        headers: {"Content-Type": "text/plain"},        body: ["Hello World"]    };};

4.启动服务器调试
结果看到内容。

可以尝试修改js中代码调试一写行为。

注意点
ringo-home目录其实是指定ringo软件本身的目录默认在web目录的WEB-INF。其实如果已经导入module的jar包,ringo-home下没有module目录会自动读取jar。如果存在module目录,则ringo将不会去读jar中的默认module文件。
默认:ringo-home为WEB-INF目录,内部engine初始化时使用的应用目录其实是web的应用目录对应的文件系统,context.getRealPath('/');