• JavaFX尝鲜

         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 下面。 这个程序没有考虑效率问题。其实这样的事情应该由容器完成,本人只是做了个小小的实验。

  • 毕业若干事

    毕业了。

    说这句话也不知道应该是一种什么样的心情,高兴?恐慌?迷茫?反正说不出的感觉。所以用了一个句号。标志着自己生命中的一个时代的结束。
         
    毕业前两个月回到学校,先是做论文。本来想自己好好写一下,大学里没怎么上课,最后了总得有个完整的结束吧,我是一向标榜有始有终理论的,开学前几节课得上,期末几节课也要上。于是开始搜集资料,构思。但弄来弄去,发现基本已经没有法学方面的思维了,时间又不够我慢慢恢复法学思维了,于是拼凑了一篇交差。
          了结了论文的事情,基本就闲了。记得大一时候,一个大四的师兄卖课本,让我去他们宿舍取。结果敲门进宿舍,宿舍中间摆一张桌子,然后若干人光着膀子,围在那儿措麻将呢。当时我就想,难道毕业前就成这样了?心里暗想,我毕业时候一定不这样。但到我毕业的时候,我才明白,毕业前的人比较浮躁,由于学校的价值观和社会的价值观有较大出入,再加上工作了,爱情了什么的乱七八糟的事情,心很难静下来做点事情的。
          
    一个同学提议去旅游,好。于是组了个三人帮,远的地方不去了,就到西北转转吧,于是决定去青海湖。坐火车到西宁,第二天到西海镇。说是镇,其实是当地一个藏族自治州的州政府所在地。小镇很漂亮,整个像个公园似的。住宅区也没有围墙,政府门口也没见警卫什么的,所有的建筑都很精致,连马路两旁的花园都用一排排小汉白玉狮子围起来,再加上清爽的空气,立刻让人耳目一新。本来是打算在镇上租自行车的,但那个自行车俱乐部的老板不在,没租成,最后一阵头脑发热,每人买了一辆车。第三天骑车出发,决定绕青海湖一圈。谁知天公不作美,接下来的两天,下雨,刮风,车子也老出问题。终于折腾到鸟岛。在鸟岛宾馆那个镇上呆了一天。早上骑车去鸟岛看了一下鸟,结果人家是建一个碉堡似的房子,四周开几个窟窿,还装着玻璃,然后让你呆在里面看,美其名曰:观鸟室。从鸟岛回来,大家死活不打算骑车了。于是坐车,打道回府。
          
    回到学校,打算给自己找点事情做。于是决定考六级。每天上午背背单词,听听听力。下午研究一下搜索,看到个马可夫模型,弄不懂,查一下,结果说是概率统计学上的。于是下载若干视频,借了若干教程,学习。学了一段时间,感觉概率统计学实在太伟大了,见了同学就给他讲概率统计的伟大之处,但由于我是学文科的,大多数同学都没学过这东西,说了半天没人呼应。
         
    日子就这样一天天过着,突然一天和实习时候的同事打了个电话,问他最近干什么呢?他说玩天龙八部呢,已经都70级了。他鼓动我也玩玩。于是注册了个号,想看看如何。以前没有玩过什么网游,因为我搞不明白杀那些用程序模拟出来的怪物的意思在哪儿?我给自己说,原来你是旁观者,这次要投入进去试试这东西。结果一下真给投入进去了,概率也不管了,六级也不想了,每天就在那儿杀程序模拟出来的怪物,感觉跟真的一样。仿佛现实中的我已经灵魂出窍,灵魂已经附着在网游里的那个角色上了。现实中的我只有在饿的不行时,匆匆忙忙出去吃个饭,一般连觉都舍不得睡。于是学校的食堂每天早上都会出现一个蓬头垢面,拖着拖鞋,两眼呆滞的人在那儿在吃他自己的晚饭。说自己蓬头垢面一点也不夸张,虽然自己也没照过镜子,但同学们见了都惊叹我几天不见怎么变黑了?然后还有个女老师送了我一瓶洗面奶,当然她没好意思说让我去把脸洗洗,只说她的用不完,给我一点。当然这些道理是我后来才悟出来的,当时思维还在游戏里,根本想不到。
        
    就这样,我不知白天黑夜,甚至不知日月星期地玩游戏。突然有两天睡觉的时候,连着做了个梦,都梦见母亲,梦里我哭得一塌糊涂,梦见母亲病了,我背着母亲找大夫,母亲痛得在我背上呻吟,我拼命奔跑,但大夫就是找不到,而背上的母亲却越来越轻,最后竟然没了,于是我在荒芜的大地上大哭,醒来还心有余悸。我查了一下日期,是高考结束的时候了,也就是母亲去世已经四年了。本来每年我都想写些什么,为母亲,也为自己,但每年都没实现,因为我太怕回忆起那段日子了,太怕回忆起母亲被病痛折磨的那种痛苦。于是我还是什么都不想,继续玩游戏。有时候我都想,人要是能生存在网络上多好?没有病痛,死了也只不过去地府转一圈出来继续杀怪.
       
    六级没去考,紧接着就办离校手续了。拿张单子,排队,盖章,绕一圈,都盖完就算手续办完了。记得当年入校是也是一样,连单子上的章子都一样,但比较一下当年的心情和现在的心情,立刻让人感叹不已。然后同学就陆续离校了。第一天在火车站送了一天同学。本来我感觉我这人对离别看的比较通达了,也就是送送而以。但一到那种氛围里,班里的同学们在火车旁边齐声唱歌,女同学比较多愁善感,唱着唱着就哭了,我开始坚持忍者,然后看着火车缓缓启动,逐渐远去,要走的同学在火车窗口还使劲向这边探望,招手,大家在下面呼喊招手,我的眼泪就忍不住了。
        
    送完了同学,就收拾东西回家。回到家里,看到的场景和我预想的差不多,到处是灰尘,仿佛若干年没住过人似的,唉,父亲一个人不好过啊。帮老爸干了一天农活。几年的学上得我基本已经没有吃苦耐力了。尤其从日新月异的大城市到我们那偏远的小村,看到我们那儿接近原始的劳作方式,总有一种极大的落差感。人太常时间不回家,总会变得有点轻飘飘的,因为老会忘记自己的根,自己的本。我感觉自己又扎扎实实站在大地上了,虽然前方的路还有点迷茫。家里呆了几天,然后就坐车又到北京了。

    我的黄金时代结束了。
        
    记得以前写过一篇文章,扎个窟窿看世界。是写从小我就向往外面的世界,想从那个小山沟走出来,即使山的那边还是山,我也要走,我多么想在那个偏僻的世界里扎个窟窿看看外面的世界。我扎开窟窿了么?我走出来了么?外面的世界真的好么?好像这些问题我依然不知道答案。生活不像程序,不能指望它运行一段时间后就给你给出个结果。

  • 配置了一下memcached

    1.memcached是什么?
           memcached is a high-performance,
    distributed memory object caching system, generic in nature, but
    intended for use in speeding up dynamic web applications by alleviating
    database load.
    2.下载地址
         
    3.安装
         跟一般的linux软件安装一样 ./configure 然后 make,make install
         需要一个库 libevent
        下载地址:
         http://www.monkey.org/~provos/libevent/
         安装库后创建个链接
         ln -s /usr/local/lib/libevent-1.3b.so.1 /lib/libevent-1.3b.so.1
    4.启动
         memcached -u nobody -d -m 50 -l 192.168.0.8 -p 10001
        -u 指定用户
        -m 指定缓存使用内存大小,只是测试,就用了50m
        -l 指定ip地址
        -p 指定端口
    5.测试
       memcached是一个数据源,所以与应用是独立的,理论上支持任何语言访问。现在已有的client库可在下面的地址得到:
       http://www.danga.com/memcached/apis.bml
       我们用java测试,jdk为1.6

    java 代码

    import com.danga.MemCached.MemCachedClient;
     import com.danga.MemCached.SockIOPool;
    
     public class MemcacheTest {
    
     // create a static client as most installs only need
     // a single instance
     protected static MemCachedClient mcc = new MemCachedClient();
    
    // set up connection pool once at class load
    static {
    
    // server list and weights
    String[] servers ={"8:10001"};
    
    Integer[] weights = { 3 };
    
    // grab an instance of our connection pool
    SockIOPool pool = SockIOPool.getInstance();
    
    // set the servers and the weights
    pool.setServers( servers );
    pool.setWeights( weights );
    
    // set some basic pool settings
    // 5 initial, 5 min, and 250 max conns
    // and set the max idle time for a conn
    // to 6 hours
    pool.setInitConn( 5 );
    pool.setMinConn( 5 );
    pool.setMaxConn( 250 );
    pool.setMaxIdle( 1000 * 60 * 60 * 6 );
    
    // set the sleep for the maint thread
    // it will wake up every x seconds and
    // maintain the pool size
    pool.setMaintSleep( 30 );
    
    // set some TCP settings
    // disable nagle
    // set the read timeout to 3 secs
    // and don't set a connect timeout
    pool.setNagle( false );
    pool.setSocketTO( 3000 );
    pool.setSocketConnectTO( 0 );
    
    // initialize the connection pool
    pool.initialize();
    
    // lets set some compression on for the client
    // compress anything larger than 64k
    mcc.setCompressEnable( true );
    mcc.setCompressThreshold( 64 * 1024 );
    }
    
    public static void bulidCache(){
    mcc.set( "foo", "This is a test String" );
    TestObj obj = new TestObj();
    obj.setId(new Long(1));
    obj.setName("test");
    mcc.set("testObj", obj);
    }
    
    // from here on down, you can call any of the client calls
    public static void output() {
    //
    String bar = (String) mcc.get( "foo" );
    System.out.println(bar);
    TestObj obj = (TestObj)mcc.get("testObj");
    System.out.println(obj);
    }
    
    public static void main(String[] args){
    bulidCache();
    output();
    }
    
    }
    

     

    import java.io.Serializable;
    
     public class TestObj implements Serializable {
    
     private static final long serialVersionUID = 1L;
     private String name;
    private Long id;
    /**
     *
     */
    public TestObj() {
    }
    public Long getId() {
    return id;
    }
    public void setId(Long id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    
    public String toString(){
    return "id:" this.getId() ";name:" this.getName();
    }
    }
    

     从faq上找了段代码,稍做改动。

    运行,成功输出:

    This is a test String
    com.danga.MemCached.MemCachedClient Sat Jul 14 18:59:46 CST 2007 – deserializing class net.teamhot.memecache.TestObj
    id:1;name:test

    中间两行是日志。
    把buildCache方法注释了,再运行,成功。

    如果是两种语言共享cache,要注意对象的持久化方式。

    6.可能遇到的问题
       如果连接不成功请用telent测试服务器端口是否能连接通。连不通请更改服务器的防火墙设置,或者干脆把防火墙关闭了。

       /etc/init.d/iptables stop

  • 一个基于词库的中文分词程序-ThesaurusAnalyzer

    前一段时间用lucene做一个搜索程序,找了好长时间的中文分词程序,都没找到合适的,最后自己弄了一个.现在共享出来.希望对大家有用.
          分词算法:    基于词库的正向最大匹配算法.
          分词词库用的是网上一个叫 segmenter 的分词程序使用的词库.
          地址:www.mandarintools.com/segmenter.html  

         
    这个segmenter分词程序是把文件按行读取出来,然后把一行假设为一个词,从库中匹配,如果匹配不成功,则去掉一个字,再继续匹配.这样的分词程
    序,其一,不便在lucene中使用,因为lucene的analyzer是通过Tokenizer分词的,而Tokenizer中一般是对字符流进行处
    理,每次next返回一个Token,并不是一次性把内容读取进来,处理后再返回结果.其二,按行读取会有个缺点,就是如果文本中恰好把一个词用换行符隔
    开了,这样这个词也就被切开了,没有被当作一个词处理.
       
         我的程序实现方式:把词库读进内存后构建一个词语树.树的每个节点包含一个字. 比方  中国   中国人  中华民族  中华人民共和国  几个词,构成的树的结构:
      
                     中
               国^    华
          人^        人    民
                       民       族^
                       共
                       和
                       国^

          
    懒得上传图片,所以将就着这样表示了.^表示该节点可以构成一个词.分词的过程类似于输入法的联想功能.读取一个字,然后联想,直到联想到不能为止.如果
    当前可以构成词,便返回一个Token.如果当前不能构成词语,便回溯到最近的可以构成词语的节点,返回.最差的情况就是返回第一个单字.然后从返回结果
    的下一个字重新开始联想.

          lucene自带的几个分词程序中,ChineseAnalyzer是按字分的,与StandardAnalyzer对中文的分词没有大的区别.CJKAnalyzer是按两字切分的,比较武断,并且会产生垃圾Token,影响索引大小.
     
         本分词程序的效果取决与词库.您可以用自己的词库替换程序自带的词库.词库是一个文本文件,名称为word.txt. 每一行一个词语,以#开头表示跳过改行.最后保存为UTF-8的文本.

        程序的缺陷:
            没有加入识别人名和地名的功能

    该分词的一个应用案例:http://www.cyonline.net          这个网站是我给学校做的,用lucene对pdf ,word,excel,html等多种格式的文档进行解析,索引,提供全文搜索,并实现摘要高亮.这个网站在教育网上,公网用户可能访问起来比较慢.     

          附件1为分词程序的jar包

         附件2为分词程序的源码,需要lucene-core.jar,一个比较Analyzer的测试类还需要lucene-analyzers.jar.

    注: 本文最早发表在javaeye上 http://jolestar.iteye.com/blog/58701 源码仓库几经辗转,现在在:https://github.com/jolestar/yaya-analyzer   

  • 瞻仰了一下Gavin King的风采

        收到个红帽子的邮件,说要在北京举行redhat企业版5的发布会,并且hibernate他爹--Gavin King也要来,于是申请了一张邀请函。今天早上起来,便去中山公园。上午讲关于redhat5的东西,下午参加了jboss的分会。

            下午第一场便是Gavin King讲Jboss seam.Gavin King的讲起来个性十足,有cowboy
    的风范。晚上的party上才知道他前两天骑摩托车遇到了点小事故,这还是带伤上阵。Jboss
    seam据我的理解,就是Jboss版的jsf框架。对jsf也有一些了解,有一段时间,想用jsf做一个东西,打印了1000多页的英文文档,研究了半
    个月,oracle的adf框架,apache的myface框架,都有接触,但最后还是放弃了。那东西太麻烦了,也不成熟。本来spring已经就有
    Ioc功能了,为了享受spring带来的许多好处,spring的配置文件麻烦一点还能接受。但jsf也弄了个Ioc,也整一堆bean,配来配去,太
    麻烦,还得和spring沟通。虽然暂时放弃了,但还是一直关注着jsf。前一段时间看到一个开源的jsf框架,frails,吸收了RoR
    的许多特征,消除了烦人的配置文件。感觉不错,不过还没顾上尝试。看Gavin King演示Jboss
    seam,感觉也不错,觉得也有RoR的风格。并且Jboss
    Seam能很好的和EJB,Hibernate以及Jboss的java工作流--jbpm集成。感觉这是个值得期待的东西。

           会议结束后,举行了一个Gavin King的签名售书会,Gavin King的大作--Hibernate
    实战。价格不菲,定价89元,英文版的,中文版还没出来。本来对hibernate已经比较了解了,现在一般看文档就可以了,不过还是买了本,让
    Gavin King签了个名。算是激励自己吧。Gavin
    King生于74年,长我10岁,希望我努力10年后,也能有点成果。同时感觉要好好学一下英语了,平时看书还行,但听说就有点烂了。Gavin
    King的演讲还能听听,毕竟对这方面比较了解并且有代码配合。别的就听不太懂了。尤其出来实习一段时间后,才真正明白学校时间的可贵。不过就剩最后两个
    月了。别的姑且不论,乘这点时间学学英语。

          从中山公园音乐堂出来后,顺便转了一下公园,随意穿行,不觉到了一个挺开阔的庭院里。时已傍晚,夕阳西下,几个孩子在院子里玩滑轮,笑声朗朗。坐在旁边的走廊长椅上,花香草气,扑面而来。闭上眼睛,春日的夕阳真温暖。

         明天该回校了。

  • 用ReflectionFactory实现不调用构造参数创建对象

      那天在sun的论坛上漂着,不经意发现了一篇帖子,大概意思是想构造一个对象,但又不想或不能调用其构造方法.我把代码整理了一下,如下:

     

     

    //Test.java
     import java.io.Serializable;
    
    public class Test implements Serializable {
         private Test() {
             System.out.println("Test");
         }
         public void say()
         {
           System.out.println("Hello!");
         }
    
     }
    

     

     

     

    //Main.java
     import java.lang.reflect.Constructor;
     import java.security.AccessController;
     import sun.reflect.ReflectionFactory;
    
    public class Main {
        private static final ReflectionFactory reflectionFactory = (ReflectionFactory) AccessController
                 .doPrivileged(new ReflectionFactory.GetReflectionFactoryAction());
    
         public static void main(String[] args) throws Exception {
            Constructor constr = reflectionFactory  
                     .newConstructorForSerialization(Test.class, Object.class
                            .getConstructor(new Class[0]));
             Test test = (Test) constr.newInstance(new Object[0]);
            test.say();
        }
     }
    

     

     

       由于Test类的构造方法是private的,因此在Main类中无法调用其构造方法创建对象.用ReflectionFactory可以给Test类动态创建一个构造方法,然后调用这个构造方法的newInstance方法创建对象.运行后我们可以发现,屏幕上打印出了”Hello”,但并没有打印出 “Test”.说明Test的原来的构造方法确实没被调用.     是不是挺有意思的?
        然后用eclipse查看了一下ReflectionFactory类中的方法,发现有许多有意思的方法.如:
    newField,newMethod,等等.但不知道参数具体是什么意思.但在google上,搜了半天,终于还是没有找到sun.reflect这个类库的api,或者相关说明.实在搞不明白,sun搞出来这么个类库,并且和java核心类库放在一起,但没有任何说明,不知道是让谁用的.

subscribe via RSS