yvgoodman 发表于 2015-11-14 15:08:53

AIR 迷你教程 — 在AIR 2.0 程序中嵌入TOMCAT(NativeProcess 实例)

  AIR 2.0 有很多令人期待和振奋的功能,使得AIR向成熟的桌面应用程序开发环境又进了一大步。上一篇文章里介绍了ServerSocket的用法,这篇教程中将向大家介绍NativeProcess,在AIR2.0中我们可以使用程序默认的打开方式直接打开一个外部的应用程序 (file.openWithDefaultApplication())
或者 通过今天要讲的启动进程方式运行一个程序。
  AIR与本地应用程序的交互是AIR 2.0的一个重要更新,这个功能的实现可以帮助我们做到在AIR 1.5时代很难完成的事情,比如我在项目中就需要操作一些硬件,但AIR不能直接操作端口,所以只能借助其他的小程序来实现,现在我们就可以很容易的操作这些小程序以达到操作硬件的目的,而Flex (AIR)与JAVA的结合很早就已经开始了,但由于早期AIR的局限性,想要把JAVA直接部署在客户端还是比较麻烦的事情,但是从AIR2.0开始我们不用担心了。现在我们用很简单的方式就可以在AIR程序中集成TOMCAT, 一次性的将后台与AIR部署到客户端。
  程序的原版(Flash Builder 4版)同样是从http://coenraets.org/获得,有兴趣的朋友可以关注这个博客。我的例子仍然使用FLEX 3.
  Demo过程


[*]下载安装 AIR 2.0 beta runtime.
[*]下载AIRAppWithEmbeddedTomcat..exe 或者 AIRAppWithEmbeddedTomcat.dmg (NativeProcess 必须在程序发布为相应平台的应用程序后才可以使用,发布的方法这里就不介绍了,可以参看http://help.adobe.com/en_US/FlashPlatform/develop/air/building_apps/WS789ea67d3e73a8b22388411123785d839c-8000.html)
[*]安装运行AIRAppWithEmbeddedTomcat.exe, 修改JAVA_HOME,如果默认的路径不对
[*]点击 “启动” 可以开启TOMCAT(端口是8080)。在JSP实例和RemoteObject实例中可以看见加载JSP页面和使用RemoteObject获取数据的测试。
  
  控制台
  

  JSP 加载测试
  
  RemoteObject 测试
  
  源代码


<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<!--www.flextheworld.com-->
<mx:WindowedApplication applicationComplete=&quot;init()&quot; xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;vertical&quot; height=&quot;600&quot; width=&quot;800&quot; >
<mx:Script>
<![CDATA[
import mx.controls.Alert;
//用于启动和停止Tomcat的进程
private var startTomcatProcess:NativeProcess;
private var stopTomcatProcess:NativeProcess;
private var tomcatHomeDir:File;
public function init():void
{
if (!NativeProcess.isSupported)
{
Alert.show(&quot;不支持进程控制,请先将程序发布为当前操作系统应用程序&quot;);
}
//如果tomcat不存在,重新复制到app store文件夹
tomcatHomeDir = File.applicationStorageDirectory.resolvePath(&quot;tomcat&quot;);
if (!tomcatHomeDir.exists)
{
var tomcatOriginalDir:File = File.applicationDirectory.resolvePath(&quot;tomcat&quot;);
trace(&quot;Copying tomcat to appStorageDirectory...&quot;);
tomcatOriginalDir.copyTo(tomcatHomeDir);
var f:File;
f.openWithDefaultApplication()
}
tomcatHome.text = tomcatHomeDir.nativePath;            
// 读取保存的配置(第一次运行以后生成)
var xml:XML = readConfig();
if (xml != null)
{
javaHome.text = xml.javaHome;
return;
}
// 如果第一次使用,设置默认Path
if (Capabilities.os.toLowerCase().indexOf(&quot;win&quot;) > -1)
{
// 默认的JAVA_HOME (windows)
javaHome.text = &quot;C:\\Program Files\\Java\\jdk1.6.0&quot;;
}
else if (Capabilities.os.toLowerCase().indexOf(&quot;mac&quot;) > -1)
{
// 默认的JAVA_HOME (Mac)
javaHome.text = &quot;/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0&quot;;
}
}
public function startTomcat():void
{
// 将本次的JAVA_HOMR写入配置文件
writeConfig();
log.text = &quot;Starting Tomcat...&quot; + File.lineEnding;
startTomcatProcess = new NativeProcess();
execute(startTomcatProcess, &quot;start&quot;);
}
public function stopTomcat():void
{
log.text = &quot;Stopping Tomcat...&quot; + File.lineEnding;
stopTomcatProcess = new NativeProcess();
execute(startTomcatProcess, &quot;stop&quot;);
}
public function execute(process:NativeProcess, arg:String):void
{
// 先获取JVM
var file:File = new File(javaHome.text);
if (Capabilities.os.toLowerCase().indexOf(&quot;win&quot;) > -1)
{
file = file.resolvePath(&quot;bin/javaw.exe&quot;);
}
else
{
file = file.resolvePath(&quot;Home/bin/java&quot;);
}
// 启动TOMCAT
try
{
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
nativeProcessStartupInfo.workingDirectory = tomcatHomeDir.resolvePath(&quot;bin&quot;);
var processArgs:Vector.<String> = new Vector.<String>();
processArgs = &quot;-Dcatalina.home=&quot;+tomcatHomeDir.nativePath;
processArgs = &quot;-classpath&quot;;
processArgs = tomcatHomeDir.resolvePath(&quot;bin/bootstrap.jar&quot;).nativePath;
processArgs = &quot;org.apache.catalina.startup.Bootstrap&quot;;
processArgs = arg;
nativeProcessStartupInfo.arguments = processArgs;
startTomcatProcess = new NativeProcess();
startTomcatProcess.start(nativeProcessStartupInfo);
startTomcatProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA,
outputDataHandler);
startTomcatProcess.addEventListener(ProgressEvent.STANDARD_ERROR_DATA,
errorOutputDataHandler);
}
catch (e:Error)
{
Alert.show(e.message, &quot;Error&quot;);
}
}
public function outputDataHandler(event:ProgressEvent):void
{
var process:NativeProcess = event.target as NativeProcess;
var data:String = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable);
log.text += data;
}
public function errorOutputDataHandler(event:ProgressEvent):void
{
var process:NativeProcess = event.target as NativeProcess;
var data:String = process.standardError.readUTFBytes(startTomcatProcess.standardError.bytesAvailable);
log.text += data;
}
private function readConfig():XML
{
var file:File = File.applicationStorageDirectory.resolvePath(&quot;config.xml&quot;);
if (file.exists)
{
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var xml:XML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
fileStream.close();
return xml;
}
else
{
return null;
}
}
private function writeConfig():void
{
var xml:String = '<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>' + File.lineEnding;
xml += &quot;<config>&quot; + File.lineEnding;
xml += &quot;<javaHome>&quot; + javaHome.text + &quot;</javaHome>&quot; + File.lineEnding;
xml += &quot;<tomcatHome>&quot; + tomcatHome.text + &quot;</tomcatHome>&quot; + File.lineEnding;
xml += &quot;</config>&quot; + File.lineEnding;
var file:File = File.applicationStorageDirectory.resolvePath(&quot;config.xml&quot;);
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeUTFBytes(xml);
fileStream.close();
}
]]>
</mx:Script>
<mx:RemoteObject id=&quot;srv&quot; destination=&quot;contacts&quot; endpoint=&quot;http://localhost:8080/messagebroker/amf&quot; />
<mx:TabNavigator width=&quot;100%&quot; height=&quot;100%&quot;>
<mx:VBox width=&quot;100%&quot; height=&quot;100%&quot; label=&quot;控制台&quot; paddingLeft=&quot;8&quot; paddingRight=&quot;8&quot; paddingBottom=&quot;8&quot;>
<mx:Form width=&quot;100%&quot;>
<mx:FormItem label=&quot;Java Home&quot; width=&quot;100%&quot;>
<mx:TextInput id=&quot;javaHome&quot; width=&quot;100%&quot;/>
</mx:FormItem>
<mx:FormItem label=&quot;Tomcat Home (嵌入的TOMCAT)&quot; width=&quot;100%&quot;>
<mx:TextInput id=&quot;tomcatHome&quot; width=&quot;100%&quot; enabled=&quot;false&quot;/>
</mx:FormItem>
</mx:Form>
<mx:HBox>
<mx:Button label=&quot;启动&quot; click=&quot;startTomcat()&quot;/>
<mx:Button label=&quot;停止&quot; click=&quot;stopTomcat()&quot;/>
<mx:Button label=&quot;清除信息&quot; click=&quot;log.text=''&quot;/>
</mx:HBox>
<mx:TextArea id=&quot;log&quot; width=&quot;100%&quot; height=&quot;100%&quot;/>
</mx:VBox>
<mx:VBox label=&quot;嵌入的JSP实例&quot; paddingLeft=&quot;8&quot; paddingRight=&quot;8&quot; paddingBottom=&quot;8&quot;>
<mx:HTML id=&quot;html&quot; width=&quot;100%&quot; height=&quot;100%&quot;/>
<mx:Button label=&quot;读取JSP&quot; click=&quot;html.location='http://localhost:8080'&quot;/>
</mx:VBox>
<mx:VBox label=&quot;嵌入的RemoteObject实例&quot; paddingLeft=&quot;8&quot; paddingRight=&quot;8&quot; paddingBottom=&quot;8&quot;>
<mx:DataGrid width=&quot;100%&quot; height=&quot;100%&quot; dataProvider=&quot;{srv.findAll.lastResult}&quot;>
<mx:columns>
<mx:DataGridColumn dataField=&quot;id&quot; headerText=&quot;Id&quot;/>
<mx:DataGridColumn dataField=&quot;firstName&quot; headerText=&quot;First Name&quot;/>
<mx:DataGridColumn dataField=&quot;lastName&quot; headerText=&quot;Last Name&quot;/>
<mx:DataGridColumn dataField=&quot;city&quot; headerText=&quot;City&quot;/>
</mx:columns>
</mx:DataGrid>
<mx:Button label=&quot;获取数据&quot; click=&quot;srv.findAll()&quot;/>
</mx:VBox>
</mx:TabNavigator>
</mx:WindowedApplication>
  下载
  

源代码:
AIRAppWithEmbeddedTomcat.zip (653)
  windows demo:
AIRAppWithEmbeddedTomcat.exe (542)
  Mac Demo:
AIRAppWithEmbeddedTomcat.dmg (413)
页: [1]
查看完整版本: AIR 迷你教程 — 在AIR 2.0 程序中嵌入TOMCAT(NativeProcess 实例)