分类目录归档:程序生活

Program Life – Web

[Flex]Flex的component和container的children的life cycle

详细大家在用Flex的时候都遇到这么一个问题,new出来的component不能直接对其内部的组件进行操作,经常会提示null的错误。当然我们自己在写Script组件的时候,可以把children的创建自己放在constructor里面。这样就不会出现这种问题。但当我们在做mxml组件的时候,这个问题就非常明显了。我们必须遵循Flex的component life cycle。通常的做法是放在property里面,例如

[code]<?xml version="1.0" encoding="utf-8"?>

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">

<mx:Script>

<![CDATA[

private var title:String;

private var bNameChanged:Boolean;

public function set Title(value):void

{

if(title != value)

{

title = value;

bNameChanged = true;

this.invalidateProperties();

}

}

override protected function commitProperties():void

{

super.commitProperties();

if(bNameChanged)

{

bNameChanged = false;

lblName.text = title;

}

}

]]>

</mx:Script>

<mx:Label id="lblName" />

</mx:Canvas>[/code]

然而,你在用一些Container的时候,还是会遇到null的问题,这又是怎么回事呢?例如,你放两个上面的组件在一个TabNavigate里面。

[code]<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*" >

<mx:TabNavigator>

<local:TestComponent id="test1" Title="test 1" />

<local:TestComponent id="test2" Title="test 2" />

</mx:TabNavigator>

</mx:Application>[/code]
试试,保证

Error #1009: 无法访问空对象引用的属性或方法。

这个时候,我开始抱怨了,为什么Flex为什么自己不遵守自己的游戏规则,这里TabNavigator的children还没有创建就会调用,commiteProperties 或者 updateDisplayList方法。这应该是Flex的一个Bug.

现在要解决这个问题就只有让TabNavigator在创建children的时候就要把所有的children都创建。这个时候我们就要关注Container.createPolicy属性了。Container内部的children不是在createChild里面创建的,至于其children的创建时机,就好好看看

ContainerCreationPolicy,而且Container内部的children(即通过mxml加的children)和createChildren里创建的chidren可以理解为不同的类型。

在上面的例子里面的TabNavigator加上 createPolicy = “ALL”所有的文件就解决了。

如果有什么问题,请大家指正.

转自:http://www.cnblogs.com/tionase/archive/2007/04/02/696852.aspx

对 Adobe Flex的 十大误解

转自:http://www.niuc.net/post/141/

首先说明的是,这篇文章不是我原创,而是来自infoq.com上的Jon Rose写的一篇文章,原贴:这里,不过我说的内容根据我的经验有很大部分是与原来不同的.
       对 ADOBE FLEX 的十大误解,在silverlight,ajax的竞争下,很多人都会怀疑,甚至疑问用FLEX吗?FLEX不好,为什么?因为:

1,用户需要重新或者新增安装插件来运行FLEX
     其实,目前在电脑平台上,用的最多的插件应该是Flash Player吧,虽然运行FLEX 需要 9 以上版本,不过按照ADOBE官方的调查,目前电脑平台上,已经有94%的用户安装了Flash Player,而且基本都是 9 或者9以上的版本,所以你基本不用担心用户没办法运行你开发的FLEX程序.
     但是AIR程序呢?OK,这需要等到明年也就是2008,才会正式推出1.0版本的RUNTIME.容量大约为9兆左右,看起来很大,不过值得幸运的是,在用户安装AIR程序时,程序会自动检测下载AIR RUNTIME程序,只要安装一次,以后再运行AIR程序就无需再次安装.

  2,Flash Player 过于封闭
    Flash Player的核心Tamarin Virtual Machine(猴子虚拟机?),目前已经在Mozilla下成为了开源项目,当然作为商业产品,ADOBE还没大方到全部开源这个地步,不过毕竟也算开了点,具体的开源信息可以到osflash.org上查询.根据我的调查,目前已经有几个项目是针对开源了的核心而开发的,
      无论是FLEX还是AIR目前基本是同一步骤向开源方向前进.

  3,Flash 只是在设计动画,视频播放等乱七八糟的方向有长处
    去每个网站,我们都避免不了该死的FLASH广告,有的更加可恶的是还是视频播放,还关不掉。久而久之,Flash就在大众落下了个花蝴蝶的形象.
      FLASH:这不是我的错啊
    我:别急别急,听我细细道来.
      有短必有长,比如动画播放,不就是为增加Flash player的占有率立下了汗马功劳?而且严格上来说,Flash CS3的确是为设计师所准备的,而FLEX却是为程序员所准备的,而两者如此的靠近,就是为了设计师与程序员能够更加完美的合作.而且目前国内开发FLEX的,还有很多是有FLASH基础的.毕竟优秀的设计是会给你的程序加很大分的.更何况FLEX涉及的范围实在太广.

4,FLEX不是开发商业程序的好选择,那只是业余产品
    在几年前,FLASH的代码写法在正统的程序员眼里,那是可笑的。不过随着AS3.0的发布,FLASH,FLEX开发越来越向正统开发方式靠近.那到底是不是开发商业程序的好选择呢?那就看些例子吧.我想这方面,ADOBE应该会有很多程序推荐的.比如这个消息:Oracle Chooses Flex

5,FLEX太贵了.
     这个,这个,在盗版横行的我们这个地方,好象不是个问题.我还听说过这么一个故事:某家外企,来了个德国FLEX开发工程师,牛啊,人家说了用的是正版的.结果要求他把序列号拿出来共享下,结果是满大街都一样的破解注册码.

6,FLEX需要单独的专用服务器
   FLEX可以运行在任何的:web server, application server, and database server.FLEX更应该说是前台程序,我说FLEX涉及的范围太广就是这个问题,你一不小心,很容易迷失在开发服务器端上,因为都能用.比如我喜欢PHP,大部分会用到AMF.

7,FLEX太难学了
   其实FLEX很简单,我想应该是最简单的程序语言了吧.唯一难点是在于他的丰富性.要把持住自己专注一点是比较难的.如果你学过C,C  ,甚至是大学里的编程课程,那学FLEX就太简单了。

8,用FLEX,我的整个大程序需要重新构建
   再次说明FLEX是前台程序,他的后台基本不需要改变,如果你用JAVA或者其他再加EJBs, Spring, POJOs等后台程序开发了一个程序,你无须修后台程序,直接用FLEX就可以调用以上的后台程序.

9 ,FLEX缺少后退键这个功能
   在开发FLASH 网站最需要解答的这个问题,谁也不希望回不到上一页看过的内容,而是重新加载了网站,不过FLEX3目前已经有后退键这个功能.

10 , 我可以用AJAX,SILVERLIGHT做出FLEX可以做出的任何东西.
    理论上来讲,任何技术都是相通的,没有说你做的了,我却做不了。不同的只是花的时间,成本不同而已.你选择AJAX也好,SILVERLIGHT也好,只不过路不同。别忘了,用FLEX也可以做出AJAX,SILVERLIGHT能做出的任何东西.不过FLEX还能用java开发.从FLEX 2以来,多少AJAX开发者投入到FLEX的怀抱啊.SilverLight?哦,这个雷声大雨点小,给我看个耳目一新的DEMO吧.

      磕磕绊绊的翻译总算写完了,下面是个人观点:我们国内的FLEX开发离世界级开发落后了很多,我想很大部分在于ADOBE根本不重视中国市场,当然这也是有客观原因的,毕竟盗版过多,满大街的FLASH产品,基本都是破解,甚至盗窃他人的成果.急功进利是最大的问题,试问国内从2000年到现在出现了多少优秀的FLASH开发工程师呢?最多的应该是动画设计师吧.
      那为什么很多大网站支持silverlight呢?因为:在这里MS很大方,ADOBE不鸟你,我想换谁,都会愿意支持MS,也就是silverlight的.

Flex HTTPService如何给后台传递参数【转载】

最近看一些文档,总结了一些给后台传递参数的方法,列举如下:

方法1:采用URLVariables对象
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
     layout="absolute" fontSize="12"
    >
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.rpc.events.ResultEvent;
            //对提交给后台的参数进行UTF-8的编码处理
            private function httpEncoding(param:String):String{
                return encodeURIComponent(param);
            }
            private function httpEncoding0(param:String):String{
                return param;//encodeURI(param);
            }
            private function doRequest():void{
                btn_do.enabled=false;
                var url:String = "http://localhost:8600/grid.jsp";
                //以下那样写后台会乱码,不管是否做URI编码转换
                //url += "?user="+httpEncoding0("用户名");
                //url += "&psw="+httpEncoding0("密码");
                //trace(url);
                srv.url = url;
                //srv.send();
                //以下这样写正常
                var params:URLVariables = new URLVariables();
                //这个user,psw就是传入后台的参数user,jsp就用 request.getParameter("user")来取
                params.user = httpEncoding("用户名");
                params.psw = httpEncoding("密码");
                srv.send(params);           
            }
            private function resultHandler(event:ResultEvent):void{
                Alert.show("与后台交互结束,前台开始取得的数据…","提示信息");
                btn_do.enabled=true;
            }
        ]]>
    </mx:Script>
    <mx:HTTPService id="srv" result="resultHandler(event);"/>
    <mx:Panel title="测试与jsp后台交互" layout="absolute" width="100%" height="90%">
        <mx:Button id="btn_do" label="取得数据" click="doRequest();"/>
        <mx:Spacer height="1"/>
        <mx:DataGrid dataProvider="{srv.lastResult.catalog.product}" width="100%" height="100%" y="28"/>   
    </mx:Panel>
</mx:Application>
方法2:采用,同时也演示了mx:State的用法,[来自网上]

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:states>
        <mx:State name="Logged In">
            <mx:SetProperty target="{panel1}" name="width" value="95%"/>
            <mx:SetProperty target="{panel1}" name="height" value="95%"/>
            <mx:RemoveChild target="{password}"/>
            <mx:RemoveChild target="{username}"/>
            <mx:RemoveChild target="{label1}"/>
            <mx:RemoveChild target="{Submit}"/>
            <mx:RemoveChild target="{label2}"/>
            <mx:SetProperty target="{panel1}" name="title" value="Members Section"/>
            <mx:AddChild relativeTo="{panel1}" position="lastChild">
                <mx:Label x="10" y="10" text="Welcome to the Members Section!"/>
            </mx:AddChild>
            <mx:AddChild relativeTo="{panel1}" position="lastChild">
                <mx:Label x="10" y="36" text="Here you can do great things, like join the forums @ Viper Creations!"/>
            </mx:AddChild>
            <mx:AddChild relativeTo="{panel1}" position="lastChild">
                <mx:Label x="10" y="62" text="Label"/>
            </mx:AddChild>
        </mx:State>
    </mx:states>
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.ResultEvent;
           
        ]]>
    </mx:Script>
    <mx:Script>
   

<![CDATA[

private function checkLogin(evt:ResultEvent):void
{

    if(evt.result.loginsuccess == "yes")

    {

    currentState = "Logged In";

    }

    if(evt.result.loginsuccess == "no")

    {
       
        mx.controls.Alert.show('Invalid username/password');

    }       
}

]]>

</mx:Script>
    <mx:HTTPService id="login_user" result="checkLogin(event)" showBusyCursor="true" method="POST" url="http://www.vipercreations.com/site_admin/login.php" useProxy="false">
        <mx:request xmlns="">
            <username>
                {username.text}
            </username>
            <password>
                {password.text}
            </password>
        </mx:request>
    </mx:HTTPService>
   
    <mx:Panel resizeEffect="Resize" width="250" height="200" layout="absolute" title="Login System" horizontalCenter="0" verticalCenter="-2" id="panel1">
        <mx:Label x="10" y="10" text="Username:" id="label1"/>
        <mx:TextInput x="10" y="36" id="username"/>
        <mx:Label x="10" y="66" text="Password:" id="label2"/>
        <mx:TextInput x="10" y="92" id="password" displayAsPassword="true"/>
        <mx:Button x="10" y="122" label="Submit" id="Submit" click="login_user.send();"/>
    </mx:Panel>
   
</mx:Application>

jsp中文乱码终极解决方法

一 找出问题的根源
    乱码可能出现的地方:1 jsp页面中
                        2 jsp页面之间相互传参的参数
                        3 与数据库中数据的存取
    基本归纳为以上几种。

二 寻找解决方案
    1 出现在jsp页面中,是由于没有设置jsp页面的中文字符编码。
    2 出现在jsp页面之间相互传参,是由于参数没有设置正确的字符编码。
    3 以上2个问题解决了,那么存到数据库中,自然就不存在乱码。除非你对存入到数据库里的数据再次进行编码。
三解决方法:
1的解决方法
[code]<% @ page contentType = " text/html;charset=gb2312 " %> [/code]
加上这句解决jsp页面中的中文乱码显示,tomcat编译完后向客户端输出的html文件不是采

用中文编码,所以会导致乱码产生。

2的解决方法
2.1
[code]<% request.setCharacterEncoding( " gb2312 " ); %> [/code]
加上这句解决jsp页面中的中文参数传递乱码。
因为浏览器默认使用的编码是“UTF-8”发送请求参数。
我们把它改为”gb2312″就ok了。

2.2 [code]String(request.getParameter("name").getBytes("ISO8859_1"),"GB2312");[/code]
这句的意思是,把传来的参数全部编码转换成gb2312,这样做的缺点是每次传来一个参数

都要这样写,很麻烦。

同样可通过设置server.xml配置文件来实现。

[code]< Connector
port ="8080"                 maxHttpHeaderSize ="8192"
                maxThreads ="150" minSpareThreads ="25" maxSpareThreads ="75"
                enableLookups ="false" redirectPort ="8443" acceptCount ="100"
                connectionTimeout ="20000" disableUploadTimeout ="true"   URIEncoding ="gb2312" /> [/code]
但是这样就应用到整个webapp中去了。

另:
[code]<% @page pageEncoding = " gb2312 " %>[/code]
此句是为了让jsp编译器能正确地解码含有中文字符的jsp页面。

其它方法还可以修改web.xml文件,配置一个过滤器。其原理都一样,只是换种方式而已。
有的书上专门写了一个函数来解决乱码,实际上对比一下就知道那种解决方法的好与坏。
回过头来一看,解决乱码也不过如此。
ok,实际就加上这3句搞定问题。

[code]<% @page pageEncoding = " gb2312 " %>
<% @ page contentType = " text/html;charset=gb2312 " %>
<% request.setCharacterEncoding( " gb2312 " ); %> [/code]
请大家有什么想法,以及有什么不对的地方请各位说明,写在留言上,大家一起讨论。

补充:添加一个过滤器SetCharacterEncodingFilter.java
[code]import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class SetCharacterEncodingFilter implements Filter {
  protected String encoding = null;

  protected FilterConfig filterConfig = null;

  public void init(FilterConfig filterConfig) throws ServletException {
    this.filterConfig = filterConfig;
    this.encoding = filterConfig.getInitParameter("encoding");
  }

  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {
    request.setCharacterEncoding("UTF-8");
    chain.doFilter(request, response);
  }

  public void destroy() {
    this.encoding = null;
    this.filterConfig = null;
  }

  protected String selectEncoding(ServletRequest request) {
    return (this.encoding);
  }
}[/code]
在web.xml添加
  
[code]
    <!– 过滤器 –>
    <filter>
        <filter-name>Set Character Encoding</filter-name>
        <filter-class>cn.ldsea.base.SetCharacterEncodingFilter</filter-class>
        <init-param>
             <param-name>encoding</param-name>
             <param-value>UTF-8</param-value>
        </init-param>
     </filter>

     <filter-mapping>
        <filter-name>Set Character Encoding</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>  
[/code]

(转载)应用HttpClient来对付各种顽固的WEB服务器

此文也是较早之前写的文章!

一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等。所访问的这些页面有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需要认证以及是一些通过加密方式传输,例如HTTPS。目前我们使用的浏览器处理这些情况都不会构成问题。不过你可能在某些时候需要通过程序来访问这样的一些页面,比如从别人的网页中“偷”一些数据;利用某些站点提供的页面来完成某种功能,例如说我们想知道某个手机号码的归属地而我们自己又没有这样的数据,因此只好借助其他公司已有的网站来完成这个功能,这个时候我们需要向网页提交手机号码并从返回的页面中解析出我们想要的数据来。如果对方仅仅是一个很简单的页面,那我们的程序会很简单,本文也就没有必要大张旗鼓的在这里浪费口舌。但是考虑到一些服务授权的问题,很多公司提供的页面往往并不是可以通过一个简单的URL就可以访问的,而必须经过注册然后登录后方可使用提供服务的页面,这个时候就涉及到COOKIE问题的处理。我们知道目前流行的动态网页技术例如ASP、JSP无不是通过COOKIE来处理会话信息的。为了使我们的程序能使用别人所提供的服务页面,就要求程序首先登录后再访问服务页面,这过程就需要自行处理cookie,想想当你用java.net.HttpURLConnection来完成这些功能时是多么恐怖的事情啊!况且这仅仅是我们所说的顽固的WEB服务器中的一个很常见的“顽固”!再有如通过HTTP来上传文件呢?不需要头疼,这些问题有了“它”就很容易解决了!
 
       我们不可能列举所有可能的顽固,我们会针对几种最常见的问题进行处理。当然了,正如前面说到的,如果我们自己使用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情,因此在开始之前我们先要介绍一下一个开放源码的项目,这个项目就是Apache开源组织中的httpclient,它隶属于Jakarta的commons项目,目前的版本是2.0RC2。commons下本来已经有一个net的子项目,但是又把httpclient单独提出来,可见http服务器的访问绝非易事。
 
       Commons-httpclient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。通过它可以让原来很头疼的事情现在轻松的解决,例如你不再管是HTTP或者HTTPS的通讯方式,告诉它你想使用HTTPS方式,剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时经常碰到的几个问题进行分别介绍如何使用httpclient来解决它们,为了让读者更快的熟悉这个项目我们最开始先给出一个简单的例子来读取一个网页的内容,然后循序渐进解决掉前进中的所有问题。
 
1.  读取网页(HTTP/HTTPS)内容
 
下面是我们给出的一个简单的例子用来访问某个页面

[code]/*
* Created on 2003-12-14 by Liudong
*/
package http.demo;
 
import java.io.IOException;
 
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/**
* 最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面
* @author Liudong
*/
public class SimpleClient {
 
    public static void main(String[] args) throws IOException
    {
       HttpClient client = new HttpClient();
       //设置代理服务器地址和端口       //client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);
        //使用GET方法,如果服务器需要通过HTTPS连接,那只需要将下面URL中的http换成https
       HttpMethod method = new GetMethod("http://java.sun.com");
        //使用POST方法
       //HttpMethod method = new PostMethod("http://java.sun.com");
       client.executeMethod(method);
       //打印服务器返回的状态
       System.out.println(method.getStatusLine());
       //打印返回的信息
       System.out.println(method.getResponseBodyAsString());
       //释放连接
       method.releaseConnection();
    }
}
  [/code]
 
在这个例子中首先创建一个HTTP客户端(HttpClient)的实例,然后选择提交的方法是GET或者POST,最后在HttpClient实例上执行提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。其实用一行代码也就可以搞定整个请求的过程,非常的简单!
 
 
2.  以GET或者POST方式向网页提交参数
 
其实前面一个最简单的示例中我们已经介绍了如何使用GET或者POST方式来请求一个页面,本小节与之不同的是多了提交时设定页面所需的参数,我们知道如果是GET的请求方式,那么所有参数都直接放到页面的URL后面用问号与页面地址隔开,每个参数用&隔开,例如:http://java.sun.com?name=liudong&mobile=123456,但是当使用POST方法时就会稍微有一点点麻烦。本小节的例子演示向如何查询手机号码所在的城市,代码如下:
 
 

[code]/*
* Created on 2003-12-7 by Liudong
*/
package http.demo;
 
import java.io.IOException;
 
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/**
* 提交参数演示
* 该程序连接到一个用于查询手机号码所属地的页面
* 以便查询号码段1330227所在的省份以及城市
* @author Liudong
*/
public class SimpleHttpClient {
 
    public static void main(String[] args) throws IOException
    {
       HttpClient client = new HttpClient();
       client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");
 
       HttpMethod method = getPostMethod();//使用POST方式提交数据
       client.executeMethod(method);
       //打印服务器返回的状态
       System.out.println(method.getStatusLine());
        //打印结果页面
       String response =
           new String(method.getResponseBodyAsString().getBytes("8859_1"));
       //打印返回的信息
       System.out.println(response);
       method.releaseConnection();
    }
    /**
     * 使用GET方式提交数据
     * @return
     */
    private static HttpMethod getGetMethod(){
       return new GetMethod("/simcard.php?simcard=1330227");
    }
    /**
     * 使用POST方式提交数据
     * @return
     */
    private static HttpMethod getPostMethod(){
       PostMethod post = new PostMethod("/simcard.php");
       NameValuePair simcard = new NameValuePair("simcard",                                                      "1330227");
       post.setRequestBody(new NameValuePair[] { simcard});
       return post;
    }
}[/code] 

 
在上面的例子中页面http://www.imobile.com.cn/simcard.php需要一个参数是simcard,这个参数值为手机号码段,即手机号码的前七位,服务器会返回提交的手机号码对应的省份、城市以及其他详细信息。GET的提交方法只需要在URL后加入参数信息,而POST则需要通过NameValuePair类来设置参数名称和它所对应的值
 
3.  处理页面重定向
 
在JSP/Servlet编程中response.sendRedirect方法就是使用HTTP协议中的重定向机制。它与JSP中的的区别在于后者是在服务器中实现页面的跳转,也就是说应用容器加载了所要跳转的页面的内容并返回给客户端;而前者是返回一个状态码,这些状态码的可能值见下表,然后客户端读取需要跳转到的页面的URL并重新加载新的页面。就是这样一个过程,所以我们编程的时候就要通过HttpMethod.getStatusCode()方法判断返回值是否为下表中的某个值来判断是否需要跳转。如果已经确认需要进行页面跳转了,那么可以通过读取HTTP头中的location属性来获取新的地址。
 
状态码 对应HttpServletResponse的常量 详细描述
301 SC_MOVED_PERMANENTLY 页面已经永久移到另外一个新地址
302 SC_MOVED_TEMPORARILY 页面暂时移动到另外一个新的地址
303 SC_SEE_OTHER 客户端请求的地址必须通过另外的URL来访问
307 SC_TEMPORARY_REDIRECT 同SC_MOVED_TEMPORARILY

 
下面的代码片段演示如何处理页面的重定向
 
      
[code] client.executeMethod(post);
        System.out.println(post.getStatusLine().toString());
        post.releaseConnection();
        
        //检查是否重定向
        int statuscode = post.getStatusCode();
        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||
            (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||
            (statuscode == HttpStatus.SC_SEE_OTHER) ||
(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
//读取新的URL地址
            Header header = post.getResponseHeader("location");
            if (header != null) {
                String newuri = header.getValue();
                if ((newuri == null) || (newuri.equals("")))
                    newuri = "/";
                GetMethod redirect = new GetMethod(newuri);
                client.executeMethod(redirect);
                System.out.println("Redirect:"+ redirect.getStatusLine().toString());
                redirect.releaseConnection();
            } else
                System.out.println("Invalid redirect");
        } [/code] 
我们可以自行编写两个JSP页面,其中一个页面用response.sendRedirect方法重定向到另外一个页面用来测试上面的例子。
 
4.  模拟输入用户名和口令进行登录
 
本小节应该说是HTTP客户端编程中最常碰见的问题,很多网站的内容都只是对注册用户可见的,这种情况下就必须要求使用正确的用户名和口令登录成功后,方可浏览到想要的页面。因为HTTP协议是无状态的,也就是连接的有效期只限于当前请求,请求内容结束后连接就关闭了。在这种情况下为了保存用户的登录信息必须使用到Cookie机制。以JSP/Servlet为例,当浏览器请求一个JSP或者是Servlet的页面时,应用服务器会返回一个参数,名为jsessionid(因不同应用服务器而异),值是一个较长的唯一字符串的Cookie,这个字符串值也就是当前访问该站点的会话标识。浏览器在每访问该站点的其他页面时候都要带上jsessionid这样的Cookie信息,应用服务器根据读取这个会话标识来获取对应的会话信息。
 
对于需要用户登录的网站,一般在用户登录成功后会将用户资料保存在服务器的会话中,这样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息,然后就可以判断用户资料是否存在于会话信息中,如果存在则允许访问页面,否则跳转到登录页面中要求用户输入帐号和口令进行登录。这就是一般使用JSP开发网站在处理用户登录的比较通用的方法。
 
这样一来,对于HTTP的客户端来讲,如果要访问一个受保护的页面时就必须模拟浏览器所做的工作,首先就是请求登录页面,然后读取Cookie值;再次请求登录页面并加入登录页所需的每个参数;最后就是请求最终所需的页面。当然在除第一次请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前请求是否已经通过验证。说了这么多,可是如果你使用httpclient的话,你甚至连一行代码都无需增加,你只需要先传递登录信息执行登录过程,然后直接访问想要的页面,跟访问一个普通的页面没有任何区别,因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实现了这样一个访问的过程。
 

[code]/*
* Created on 2003-12-7 by Liudong
*/
package http.demo;
 
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.*;
import org.apache.commons.httpclient.methods.*;
 
/**
* 用来演示登录表单的示例
* @author Liudong
*/
public class FormLoginDemo {
 
    static final String LOGON_SITE = "localhost";
    static final int    LOGON_PORT = 8080;
    
    public static void main(String[] args) throws Exception{
       HttpClient client = new HttpClient();
       client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT);
      
       //模拟登录页面login.jsp->main.jsp
       PostMethod post = new PostMethod("/main.jsp");
       NameValuePair name = new NameValuePair("name", "ld");      
       NameValuePair pass = new NameValuePair("password", "ld");      
       post.setRequestBody(new NameValuePair[]{name,pass});
       int status = client.executeMethod(post);
       System.out.println(post.getResponseBodyAsString());
       post.releaseConnection();  
      
       //查看cookie信息
       CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
       Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/", false, client.getState().getCookies());
       if (cookies.length == 0) {
           System.out.println("None");    
       } else {
           for (int i = 0; i < cookies.length; i++) {
              System.out.println(cookies[i].toString());    
           }
       }
       //访问所需的页面main2.jsp
       GetMethod get = new GetMethod("/main2.jsp");
       client.executeMethod(get);
       System.out.println(get.getResponseBodyAsString());
       get.releaseConnection();
    }
}
 

 
 
5.  提交XML格式参数
 
提交XML格式的参数很简单,仅仅是一个提交时候的ContentType问题,下面的例子演示从文件文件中读取XML信息并提交给服务器的过程,该过程可以用来测试Web服务。
import java.io.File;
import java.io.FileInputStream;
 
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
 
/**
* 用来演示提交XML格式数据的例子
*/
public class PostXMLClient {
 
    public static void main(String[] args) throws Exception {
        File input = new File(“test.xml”);
        PostMethod post = new PostMethod(“http://localhost:8080/httpclient/xml.jsp”);
        // 设置请求的内容直接从文件中读取
        post.setRequestBody(new FileInputStream(input));
        
        if (input.length() < Integer.MAX_VALUE)
            post.setRequestContentLength(input.length());
        else            post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);
        
        // 指定请求内容的类型
        post.setRequestHeader("Content-type", "text/xml; charset=GBK");
        
        HttpClient httpclient = new HttpClient();
        int result = httpclient.executeMethod(post);
        System.out.println("Response status code: " + result);
        System.out.println("Response body: ");
        System.out.println(post.getResponseBodyAsString());
        post.releaseConnection();
    }
} [/code]
 
6.  通过HTTP上传文件
 
httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可,下面的代码片段演示如何使用这个类。
 

[code]MultipartPostMethod filePost = new MultipartPostMethod(targetURL);
filePost.addParameter("fileName", targetFilePath);
HttpClient client = new HttpClient();
//由于要上传的文件可能比较大,因此在此设置最大的连接超时时间
client.getHttpConnectionManager().         getParams().setConnectionTimeout(5000);
int status = client.executeMethod(filePost); [/code]
 
上面代码中,targetFilePath即为要上传的文件所在的路径。
 
7.  访问启用认证的页面
 
我们经常会碰到这样的页面,当访问它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,这种用户认证的方式不同于我们在前面介绍的基于表单的用户身份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括:基本、摘要以及NTLM认证。其中基本认证最简单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式,而NTLM则是微软公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证还要安全的一种方式。
 
下面例子是从httpclient的CVS服务器中下载的,它简单演示如何访问一个认证保护的页面:

[code]import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.methods.GetMethod;
 
public class BasicAuthenticationExample {
    public BasicAuthenticationExample() {
    }
    public static void main(String[] args) throws Exception {
        HttpClient client = new HttpClient();
        client.getState().setCredentials(
            "www.verisign.com",
            "realm",
            new UsernamePasswordCredentials("username", "password")
        );
        GetMethod get = new GetMethod("https://www.verisign.com/products/index.html");
        get.setDoAuthentication( true );
        int status = client.executeMethod( get );
        System.out.println(status+"\n"+ get.getResponseBodyAsString());
        get.releaseConnection();
    }
} [/code]
 
8.  多线程模式下使用httpclient
 
多线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问,为了保证多线程工作环境下不产生冲突,httpclient使用了一个多线程连接管理器的类:MultiThreadedHttpConnectionManager,要使用这个类很简单,只需要在构造HttpClient实例的时候传入即可,代码如下:
    
[code]MultiThreadedHttpConnectionManager connectionManager =
           new MultiThreadedHttpConnectionManager();
    HttpClient client = new HttpClient(connectionManager); [/code]
 
以后尽管访问client实例即可。

QQ机器人for 校内网 饭否网

[b][color=#FF0000][size=5]已失效,停止更新……[/size][/color][/b]
[color=#0000FF][size=5]用了LumaQQ的库,写一个QQ机器人,配合以前写的海蓝工具源码,实现了用QQ机器人来更改校内网状态,写日志,其实还可以实现更多功能,比如发邮件,群里发帖以前是可以的,现在不行了,群里发帖需要验证码,那个验证码以我现在的水平,我是破不了,呵呵

大家想测试的话,可以加304353193这个QQ为好友[/size][/color]

[img][attach]55[/attach][/img]

[img][attach]56[/attach][/img]

[color=#0000FF][size=5]更新内容:可以发布消息到饭否网[/size][/color]

[img][attach]57[/attach][/img]

[img][attach]58[/attach][/img]

[转]要成为Java高手需要注意的25个学习目标

1、你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF、J2EEDP)以及综合模式。你应该了解UML,尤其是class,object,interaction以及statediagrams。

2、你需要学习Java语言的基础知识以及它的核心类库(collections,serialization,streams, networking,multithreading,reflection,event,handling,NIO,localization以及其 他)。

3、你应该了解JVM,classloaders,classreflect以及垃圾回收的基本工作机制等。你应该有能力反编译一个类文件并且明白一些基本的汇编指令。

4、如果你将要写客户端程序,你需要学习Web的小应用程序(applet),必须掌握GUI设计的思想和方法,以及桌面程序的SWING, AWT,SWT。你还应该对UI部件的JavaBEAN组件模式有所了解。JavaBEANS也被应用在JSP中以把业务逻辑从表现层中分离出来。

5、你需要学习Java数据库技术,并且会使用至少一种persistence/ORM构架,例如Hibernate,JDO,CocoBase,TopLink,InsideLiberator(国产JDO红工厂软件)或者iBatis。

6、你还应该了解对象关系的阻抗失配的含义,以及它是如何影响业务对象的与关系型数据库的交互,和它的运行结果,还需要掌握不同的数据库产品运用,比如Oracle,Mysql,MS SQL Server。

7、你需要学习Servlets,JSP,以及JSTL(StandardTagLibraries)和可以选择的第三方TagLibraries。

8、你需要熟悉主流的网页框架,例如JSF,Struts,Tapestry,Cocoon,WebWork,以及他们下面的涉及模式,如MVC/MODEL2。

9、你需要学习如何使用及管理Web服务器,例如tomcat,resin,Jrun,并且知道如何在其基础上扩展和维护Web程序。

10、你需要学习分布式对象以及远程API,例如RMI和RMI/IIOP。

11、你需要掌握各种流行中间件技术标准和与Java结合实现,比如Tuxedo、CROBA,当然也包括JavaEE本身。

12、你需要学习最少一种的XMLAPI,例如JAXP(JavaAPIforXMLProcessing),JDOM(JavaforXMLDocumentObjectModel),DOM4J,或JAXR(JavaAPIforXMLRegistries)。

13、你应该学习如何利用Java的API和工具来构建WebService。例如JAX-RPC(JavaAPIforXML/RPC), SAAJ(SOAPwithAttachmentsAPIforJava),JAXB(JavaArchitectureforXMLBinding), JAXM(JavaAPIforXMLMessaging),JAXR(JavaAPIforXMLRegistries),或者JWSDP (JavaWebServicesDeveloperPack)。

14、你需要学习一门轻量级应用程序框架,例如Spring,PicoContainer,Avalon,以及它们的IoC/DI风格(setter,constructor,interfaceinjection)。

15、你需要熟悉不同的J2EE技术,例如JNDI(JavaNamingandDirectoryInterface),JMS (JavaMessageService),JTA/JTS(JavaTransactionAPI/JavaTransactionService), JMX(JavaManagementeXtensions),以及JavaMail。

16、你需要学习企业级JavaBeans(EJB)以及它们的不同组件模式:Stateless/StatefulSessionBeans, EntityBeans(包含Bean-ManagedPersistence[BMP]或者Container-ManagedPersistence [CMP]和它的EJB-QL),或者Message-DrivenBeans(MDB)。

17、你需要学习如何管理与配置一个J2EE应用程序服务器,如WebLogic,JBoss等,并且利用它的附加服务,例如簇类,连接池以及分布式处理支援。你还需要了解如何在它上面封装和配置应用程序并且能够监控、调整它的性能。

18、你需要熟悉面向方面的程序设计以及面向属性的程序设计(这两个都被很容易混淆的缩写为AOP),以及他们的主流Java规格和执行,例如AspectJ和AspectWerkz。

19、你需要熟悉对不同有用的API和framework等来为你服务。例如Log4J(logging/tracing),Quartz (scheduling),JGroups(networkgroupcommunication),JCache (distributedcaching),?Lucene(full-textsearch),JakartaCommons等等。

20、你应该熟练掌握一种JavaIDE例如sunOne,netBeans,IntelliJIDEA或者Eclipse。(有些人更喜欢VI或EMACS来编写文件。随便你用什么了。

21、Java(精确的说是有些配置)是冗长的,它需要很多的人工代码(例如EJB),所以你需要熟悉代码生成工具,例如XDoclet。

22、你需要熟悉一种单元测试体系(JNunit),并且学习不同的生成、部署工具(Ant,Maven)。

23、你需要熟悉一些在Java开发中经常用到的软件工程过程。例如RUP(RationalUnifiedProcess)andAgilemethodologies。

24、你还需要紧跟Java发展的步伐,比如现在可以深入的学习Webwork 2.0。

25、你必须要对实际项目的开发流程有所了解,至少要有两个有实际应用价值的项目,而不是练习项目!因为现在企业看重的是你有没有实际的开发经验,真正开发经验的体现就是你做的项目,也就是有实际应用的项目!

注:以上内容来自网络,本人不承担任何连带责任

文章转自:http://developer.51cto.com/art/200804/68871.htm

把握现在,掌控未来:2008 Java开发展望

[color=#0000FF][size=4]2007 充满了激荡人心的事件,动态语言的不断升温,JVM在开源社区不断发展以及Java社区的重要贡献者,Google的崛起等。问题是,这些预示了来年什么 呢?安德鲁•格勒弗(Andrew Glover)准备了一些答案给那些打破砂锅问到底的Java开发者――现在,什么在2008接踵而至。

法国诗人保尔•瓦雷里曾经伤心地写下“困扰我们这个时代的是,未来,并不像过去看上去的那样”。然而,对于我们这些生活在Java平台崛起推动的互联网时代的人来说,瓦雷里多年前留下的这些诗句是永恒的。

过去的十多年,我们见证了Java Applet的兴起和没落,见证了EJB头顶上光环的不断暗淡,见证了JSF,Spring和Struts的异军突起(暂且不谈Struts渐渐显露的颓 势),见证了Java已经重新定义成为一种语言和一个平台。Java平台已经衍生出三个分支(标准版本,企业版本,微型版本),JDK也开放给了开源社 区。Java语言扩充了,包含了注解,范型,枚举类型,高级集合类型,还有更多。它也开始与动态语言,如Groovy,JRuby和Rhino等,共享 Java运行时(JRE)。事实上,如果稍稍留神一下,我们在过去的几年里注视着Java不断地从一种语言演变成为一个真正的平台。

在最近的十年里,我们知道Java已经不仅仅局限于一种语言或者一个平台了:它是一个社区,一个经济生态系统,一个鲜活的实体,而且这个实体已经发展成熟,成为了丰富的应用程序,或大或小公司的真正的生命线。

因此,尽管流言不少,我还是坚持认为Java在2008会持续红火。与其拿起卦子掐算未来,我们不如回顾一下过去的一年的趋势以及发生的重大事件。这些事件汇集起来,它们会告诉我们2008将发生什么。

遍地开花

2007 年犹如过山车一样,非常引人注目。人们对动态语言的不断关注, JVM在开源社区不断发展以及Java社区的重要贡献者,Google的崛起。更多的是,单元测试,持续化集成和其他敏捷开发技术得到了更广泛的接受,这 些都表明Java开发者开始认识到我们的技艺是一门有责任要求的行业。我们终于开始重视代码的质量和寿命,将其与推向市场的速度,或者是在企业的即时应用 放到同等重要的地位上来。

每个人都说,2007年有一些绝对的胜利,但是同时也有一些失望和争论,这给Java社区产生了超出预期更多的阻碍。留心一下以下这些体现过去一年的重大因素。

动态语言的成熟

随着1.0以及随后的1.5版本的发布,Groovy在2007的发展达到了一个关键的里程碑。走过过去5年或者多年的历程,Groovy没有替代Java,相反定位成了Java运行时(JRE)的补充语言。

Groovy的大卖点是简练的语法,简化了日常的开发工作。例如,打开和读取一个文件在Java语言是典型的冗长结构:

try {BufferedReader in = new BufferedReader(new FileReader(path)); String line; while((line = in.readLine()) != null){System.out.println(line); }in.close(); }catch(IOException e){System.err.println(“Exception reading”); }

但是同样的代码,Groovy可以写的更加敏捷:

new File(path).eachLine{ line ->println line}

根本上,Groovy像其他动态语言一样,可以让你扔掉异常处理,类型和分号,还可以使得代码更加简练,而代码简练最终使得代码的可读性更强(是的,上面那个File对象是一个Java java.io.File对象)。

把网撒开

然而,Groovy并不是2007年动态语言阵营的唯一参与者。2006年发布的Java 6版本引入了一个与动态语言交互的标准API,很多Java开发者在去年临近年底才开始体验。对该API进行旗舰式集成的是Rhino。但是,看起来在 Java7版本发布时还会有更多集成进来。

最早进行集成的语言之一不容置疑是JRuby,1.0版本的发布和令人咋舌的比Ruby本身运行速度还快的实现,使得它备受瞩目。像Groovy一 样,由于可以使用更加宽松的语法,加入了一些特殊机制的JRuby(它可以使 RubyJVM里运行,且与正常的Java对象交互)使Java开发更加简单。例如,使用Ruby可以增强标准的对象,象用Ruby的String操作会 更加容易。在标准的Java里,检查一个String实例是否为空值可能要做象如下方法的一样的操作(这是一个Apache commons-lang的 isBlank实现)。

public static boolean isBlank(String str) {int strLen; if (str == null || (strLen = str.length()) == 0) {return true; }for (int i = 0; i < strLen; i++) {if ((Character.isWhitespace(str.charAt(i)) == false)) {return false; }}return true; }
在Java 里,String是一个final类,所以你无法为了让String类型支持一个象isBlank的方法而扩展它。后果是,你不得不依赖第三方类库,象 common-lang。有了Ruby,你就可以在Ruby的String上另外定义一个blank方法,如:

class Stringdef blank?empty? || strip.empty?endend

实际上,Ruby式的动态允许运行时添加额外的行为到核心类库或任意对象(象给String增加一个blank?方法)。更进一步,JRuby可以进行反作用对核心Java对象增加方法。因此,稍一施法就可以给Java String类添加一个blank方法。

开放Java核心

07年Java的开源意味Java平台的发展不再由Sun核心工程师们说了算了:现在它的前途由我们掌握了。对Java类库,Javac,甚至JVM本身都采取GPL协议,OpenJDK保证将会开创一个创新的周期。实际上,我们已经看到了。

在2007 年十月,一个名为Multi-Language VM的项目在OpenJDK旗下开展了。这个项目旨在通过修改Java的底层架构,实现“以JVM特性为原型,高效支持Java之外的语言”。很明显,这 项目结合了07年最令人振奋的两个发展潮流,也就是围绕在动态语言的热衷和OpenJDK,这宣称我们处在了一个Java核心创新的时代。

Sun 的开放当然不是从OpenJDk开始的,而是Glassfish,作为Sun支持的开源应用服务器,它在2007自始至终获得了社区更多的追捧。最近,我 们无法忽略Sun对MySQL AB的收购,MySQL背后的公司是MySQL AB,而MySQL似乎是当今最流行的开源数据库。

所有这些发展都表明Java的鼻祖采取了一种受开源软件很大影响的商业模式。这意味我们在2008或者更远将看到Java平台更多的开放。当然,这会对Java生态系统的商业方面产生深远影响。相比最近Oracle以70十亿美金收购BEA,这似乎很绿色,很健康。

Google flexes

移动Java领域曾经变的不景气,但是临近2007年尾时,却因Google的Android平台的发布而重焕青春。Android的目标是为新一 代移动设备引入应用软件,且运行在由Google主导的开源操作系统之上。虽然Android是一个完整的平台(很像Java),但是构建Android 应用程序的SDK却是建立在Java之上。

此外,Android的Java与J2ME的Java截然不同。实际上,在JVM层面,Android的JVM就已相当独特了。除了运行专门为 Android而设计,高度优化的字节码格式的代码,它不可以运行标准Java字节码。移动设备上运行不同实现的Java意味这我们将可以看到一些有趣的 应用程序――当然,这也仅进一步说明了Java的无处不在。

2007 年Google在Java世界移动领域之外也进展的很顺利。但是,备受关注的是Guice的发布,Guice是一个基于Java 5注解和范型的依赖注入开源框架。虽然IOC市场上的佼佼者还是Spring,因其摒弃XML文件,提倡使用注解和Guice本身的Module类型,注 定了Guice在公开发布时就是一个先行者。

考虑到Google对第二代IOC框架的影响和Google AdWrods本身的基础架构都是依赖Guice的,Guice在来年很有可能将得到更多的关注。

敏捷成为主流――测试时代到来了

敏捷(agile)这个名称对大家来说并不新鲜,单元测试与持续化集成也不陌生。不过,2007年似乎是这些实践更加成为主流的年份。你不会碰到一 个会议里没有一到两个关注在敏捷上的演示的。再哆嗦几句,瞥一眼2008年度Jolt Award大奖关于综合性和技术性书籍(从2007年甄选的)的最终名单,就可以看出关于单元测试和持续化集成的书籍占有一席之地。然而,更重要的是,不 管是享有盛誉的,还是刚刚发展的框架都已经开始宣称它们的架构是多么容易地进行测试了。似乎,开发人员的测试时代终于到来了。

Java成长之痛

Java在不断的成长,不断的扩充,然而它在逐渐变化成为一个平台,而不仅仅是一种语言。不知是好还是坏,独具特性的东西一直在不断的添加进来,以后还将会有,社区会接受特性吗?

然而,一些特性就没有其他特性那样受欢迎了。举个例子来说,注解就很受欢迎――象JUnit4, TestNG, Spring和Google的Guice这些框架,由于对注解的创新的使用,就得到了不少开发人员的青睐。相反的是,到目前为止,人们对范型(在Java 5中引入)并没有保持对其自始至终的热情。

闭包(Closure)未见踪影

如果范型不足以使编程的前景变的灰暗,有人可能会发现当前围绕关于在Java 7 foggy中加入闭包和局部函数提议的争论。虽然我绝不会否认它们是有用的组成部分,只是,将它们增加到Java语言的语义中,概念的复杂性增加只会降低它们的有用性。

例如,在一个闭包的典型参考实现中,找到如下代码,它定义了一个简单的支持整数加法的闭包:

{Integer,Integer=>Integer} plus1 = {Integer x, Integer y => x+y};
非常有趣的是,由于Java天生的对语义要求,语句变的拖沓冗余――用Groovy来重写同样功能,却很容易。例如

plus1 = { x, y -> x+y }

注意到,在Groovy的例子中,类型的缺失无疑使得代码的意图一目了然。当然,Ruby版本也会同样简明扼要。

显然,象动态语言普遍受到欢迎此类的外部力量在不断地影响Java。如果想使用闭包,你完全不必等待Java自带的闭包――Groovy和JRuby对其的支持就已经很优雅。

真正的并发

Java7 值得期待的其他事情是java.util.concurrent包的发布,这个包致力于通过充分利用底层硬件来达到真正的并发。虽然Java已经支持多线 程,但是通过对并行性的进一步重视,硬件资源将变的越来越健壮。最终,Java语言也发展的可以应付这些要求。

由JSR 166专家组领导的Java 7将很有可能包含一些新特性,包括名为join-fork的细粒度的并行计算框架。好消息是,看起来这些新特性是崭新的类(和API),与生俱来就不符合句法规则。

奔向RIA

07年,特别是Sun在2007年JavaOne上让JavaFx对公众面世后,RIA(Rich Internet Application)继续让Java Web应用程序开发人员产生莫大的兴趣。JavaFX产品家族现在由JavaFX Script和JavaFX Mobile组成。

由于开发类Ajax应用的JavaScript无处不在,对 JavaFx的反应显得见仁见智。看起来JavaFX将会加剧本来就已经四分五裂的移动环境之间的裂缝。很多人感觉JavaFX的公告有点操之过急,还有 一些人怀疑它究竟是不是一个雾件。不管怎样,Sun进入RIA领域传达了一个长期战略的消息,这会使Java的前景更加光明。

结束语

有个非洲谚语说“明天属于那些今天为它准备的人”。因此,Java的未来(至少来年)已经孕育了一段时间了。2008年的大事的很大部分将不仅由 JVM本身促成,而且也会随着JRuby和Groovy不断受欢迎,最终得到更多厂商的采纳而形成。由于Google Android的出击和Sun JavaFX Mobile的发布,使用Java开发用户移动应用的前景也好像比以前更加容易到达了。大部分人的注意力将被多核系统的出现吸引过去,期待Java 7 java.util.concurrent包对其的回应。最后,围绕它的开源的Java和商业模型也会不断的成长。

作者简介

Andrew Glover是Stelligent Incorporated的总裁,Stelligent Incorporated是一家帮助开发团队加速软件开发的咨询公司。他的blog通常是thediscoblog.com和testearly.com。[/size][/color]

用java实现汉诺塔游戏

用递归算法完成汉诺塔游戏的基本实现,代码是用Java写的

[code]public class Hanoi {

  /**
   * @param args
   */
  public static String x = "柱子1";

  public static String y = "柱子2";

  public static String z = "柱子3";

  public Hanoi() {

  }

  // 将针x上由小到大编号为1至n的n个棋子移动到z柱子上,y为辅助
  // 移动操作move(x,n,z)可定义为将编号为n的柱子从x移动到z
  public void hanoi(int n, String x, String y, String z) {
    if (n == 1)
      move(x, 1, z);
    else {
      hanoi(n – 1, x, z, y);
      move(x, n, z);
      hanoi(n – 1, y, x, z);
    }
  }

  public static void main(String[] args) {
    Hanoi game = new Hanoi();
    game.hanoi(5, x, y, z);

  }

  public void move(String x, int n, String z) {
    System.out.println("将编号为" + n + "的棋子从" + x + "移到" + z);
  }

}[/code]

The Result:
[color=#0000FF]将编号为1的棋子从柱子1移到柱子3
将编号为2的棋子从柱子1移到柱子2
将编号为1的棋子从柱子3移到柱子2
将编号为3的棋子从柱子1移到柱子3
将编号为1的棋子从柱子2移到柱子1
将编号为2的棋子从柱子2移到柱子3
将编号为1的棋子从柱子1移到柱子3
将编号为4的棋子从柱子1移到柱子2
将编号为1的棋子从柱子3移到柱子2
将编号为2的棋子从柱子3移到柱子1
将编号为1的棋子从柱子2移到柱子1
将编号为3的棋子从柱子3移到柱子2
将编号为1的棋子从柱子1移到柱子3
将编号为2的棋子从柱子1移到柱子2
将编号为1的棋子从柱子3移到柱子2
将编号为5的棋子从柱子1移到柱子3
将编号为1的棋子从柱子2移到柱子1
将编号为2的棋子从柱子2移到柱子3
将编号为1的棋子从柱子1移到柱子3
将编号为3的棋子从柱子2移到柱子1
将编号为1的棋子从柱子3移到柱子2
将编号为2的棋子从柱子3移到柱子1
将编号为1的棋子从柱子2移到柱子1
将编号为4的棋子从柱子2移到柱子3
将编号为1的棋子从柱子1移到柱子3
将编号为2的棋子从柱子1移到柱子2
将编号为1的棋子从柱子3移到柱子2
将编号为3的棋子从柱子1移到柱子3
将编号为1的棋子从柱子2移到柱子1
将编号为2的棋子从柱子2移到柱子3
将编号为1的棋子从柱子1移到柱子3[/color]