java6出来以后,其一大特色就是对脚本语言的支持。以前只是粗略看了一下,没感觉到有什么具体的用处。最近又对java的特有脚本语言javaFX了解一下,感觉挺有意思。

**一.以下是几个相关网址: **
   1.sun javafx 官方网站:.www.sun.com/software/javafx/script/
   2.openjfx 网站:  openjfx.dev.java.net/
   3.JavaFX: First Steps – “Hello OnJava” App  www.oreillynet.com/onjava/blog/2007/05/javafx_first_steps_hello_onjav_1.html
   4.The JavaFX Script Programming Language Reference (Chinese version)

hello world 式的程序,很简单,稍看一下文档就明白了。
二.我比较喜欢这个语言的下面几个特征:
 
     这个语言融合了javascript,php,actionscript,sql 等许多脚本语言的特征。

    1.数组操作很有特色
         var nums = [0..3];
         ..  是范围表达式,上面的语句相当于  var nums == [0,1,2,3];
         数组支持类似于sql语句一样的查询表达式。
        var nums = select n*n from n in [1..100];
        结果便是从1到100每个数字的平方组成的数组。

     2.字符串
        javaFX中的字符串支持嵌入表达式

 

 

var name = 'Joe';
 var s = "Hello {name}";
System.out.println(s);

 

      程序在输出结果的时候会自动把字符串中的表达式 {} 算出来,替换成结果 。这段程序的输出结果是 : Hello Joe
       这个特点和php很相似。用在来做结果输出模板时很有用,不必用自己创造标签语法,输出的时候又得用正则分析,替换。

    3.类与对象
       对象声明可以用一种类似于json的语法进行。

 

class Person {
 attribute name: String;
 attribute parent: Person inverse Person.children;
 attribute children: Person* inverse Person.parent;
 function getFamilyIncome(): Number;
 function getNumberOfChildren(): Number;
 operation marry(spouse: Person);
 }

var chris = Person {
name: "Chris"
children:
[Person {
name: "Dee"
},
Person {
name: "Candice"
}]
};

 

 

   4.很有特色的反射操作
      javaFX的反射很奇妙,我都在想,为什么java的反射也不做成这样。

  import java.lang.System;

     System.out.println(1.class.Name) // prints "Number"
     System.out.println("Hello".class.Name); // prints "String" 

 

方便吧?
**
三.在web中的尝试。**
      看了说明,好像javaFX出现的目标是简化Swing的界面开发编程。一方面javaFX还没有一个好的所见即所得的ide支持,另外本人对web方面的编程比较感兴趣。所以进行了一个小实验。
     我的思路是用一个servlet拦截所有对fx的请求,根据requestURI,获得javafx文件的绝对路径,然后在servelt中调用java6的脚本引擎,解释执行。
 FXServlet.java

import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;

public class FXServlet extends HttpServlet {

private String realPath;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

this.doWork(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

this.doWork(request, response);
}

public void doWork(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
System.out.println("begin ....");
 try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ScriptEngineManager manager = new ScriptEngineManager(loader);
ScriptEngine engine = manager.getEngineByExtension("fx");

Bindings bindings = engine.createBindings();
//将request和response两个对象传递给脚本引擎。
bindings.put("REQUEST:javax.servlet.http.HttpServletRequest",request);
bindings.put("RESPONSE:javax.servlet.http.HttpServletResponse",response);

ScriptContext context = new SimpleScriptContext();
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
engine.setContext(context);
String uri = request.getRequestURI();
String contextPath = request.getContextPath();
//将requestURI中的contextPath替换掉
if(contextPath!=null&&contextPath.trim().length()>0){
uri = uri.replaceAll(contextPath,"");
}
//根据requestURI取得fx文件的绝对地址我们把fx文件放在站点的 WEB-INF下的 jfx目录下。
String filePath = this.realPath   "WEB-INF"  File.separator  "jfx"   uri;
File jfxFile =new File(filePath);

if(!jfxFile.exists()){
response.sendError(404);
}else{
InputStreamReader reader = new InputStreamReader(new FileInputStream(jfxFile));
engine.eval(reader);
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("... end");
}

public void init() throws ServletException {
this.realPath = this.getServletContext().getRealPath("/");
}

}

web.xml

       FXServlet
       net.teamhot.jfxweb.FXServlet
    

    
      FXServlet
      *.fx

 

Hello.fx

import java.lang.System;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.PrintWriter;

 //接受从java中传递过来的参数
 var request:HttpServletRequest = REQUEST;
 var response:HttpServletResponse = RESPONSE;

var name = request.getParameter("name");
var out:PrintWriter = response.getWriter();

var template = "Hello World!{if name ==null then 'guest' else name}";

out.print(template);

 

运行:http://localhost:8080/jfx/Hello.fx
结果:Hello World!guest 运行:http://localhost:8080/jfx/Hello.fx?name=jolestar
结果:Hello World!jolestar

注意:本程序需要tomcat在jdk6环境下运行,如果还是提示找不到javax.script.ScriptEngine,请将jdk6 lib 下面的rt.jar中的javax.script包抽取出来,重新打包后放到 tomcat  common lib 下面。 这个程序没有考虑效率问题。其实这样的事情应该由容器完成,本人只是做了个小小的实验。