<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Mikel</title>
    <description>要么好好活着，要么赶紧去死吧！</description>
    <link>http://mikel.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Google可以搜索Flash了</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/214448" style="color:red;">http://mikel.javaeye.com/blog/214448</a>&nbsp;
          发表时间: 2008年07月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          google现在已经可以搜索文件类型为SWF的文件了，不过还是有问题，就是只能搜索Flash中的text文本，如果将text打散成图形的就搜索不到，不过这样也不错了，毕竟比搜不到好<br /><br />感兴趣的可以在搜索内容中输入：filetype：swf 试试，可以看到搜到的都是swf格式的文件<br /><br />http://www.google.com/search?hl=en&newwindow=1&q=filetype%3Aswf+&btnG=Search
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/214448#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 14 Jul 2008 08:37:59 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/214448</link>
        <guid>http://mikel.javaeye.com/blog/214448</guid>
      </item>
      <item>
        <title>Flash Player10 发布</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/193513" style="color:red;">http://mikel.javaeye.com/blog/193513</a>&nbsp;
          发表时间: 2008年05月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          新版本增加：<br />1、3D效果。<br />2、自定义滤镜和效果。<br />3、高级文本显示。<br />4、增强的Draw API。<br />5、增强的执行效率。<br />更多内容请看：http://labs.adobe.com/technologies/flashplayer10/releasenotes.html<br />具体请看：http://labs.adobe.com/downloads/flashplayer10.html<br />Demo演示：http://labs.adobe.com/technologies/flashplayer10/demos/
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/193513#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 16 May 2008 08:33:02 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/193513</link>
        <guid>http://mikel.javaeye.com/blog/193513</guid>
      </item>
      <item>
        <title>面向生命(Life oriented , LO)编程</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/190452" style="color:red;">http://mikel.javaeye.com/blog/190452</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          序言：<br /><br />软件是个生命体！<br /><br />万事万物皆变化！<br /><br />为什么我会提出"面向生命(Life oriented)"编程的思想，因为我们一直以来以建筑学的角度来审视软件工程，将软件定义为一种无生命的产品，而事实是外界的需求的无时无刻都在变化要求我们做出来的软件也随之变化，你难道想让一所盖好的房子会每时每刻根据外界的环境变化吗?而有生命的植物和动物则可以，会依据环境的变化而变化，一株草会根据压在上方的石头而改变自身的生长形态而曲折生长，软件应该也会为适应变化而调整自身的结构和功能来避免被变化的环境所淘汰！没错这是个适者生存的世界，软件也一样。<br /><br />还有一个原因就是软件和人一样是有生、老、病、死的，诞生的时候具有面向对象思想中人类的基本属性和行为，但是还很弱，就像婴儿一样，但是面向对象的思想将世界万物都抽象成类，类的实例创建了对象，但是根本没有发现一类的对象之间是存在差异的，难道你看到过世界上长的完全一模一样的人吗？没有，因为每个人都是鲜活的生命体，尽管具有人类的共同属性和行为，但是每个人都有自己的性格、学习能力、、、、、、、，同时每个人的成长历程是根据环境的不同而不同，也就是适应变化，刚生下来的婴儿是最原始的对象，然后通过人类具有的基本行为嗅觉、听觉、视觉、味觉、触觉、学习能力来获得信息不断完善对世界的认识，从而形成不同的性格，也逐渐成长起来从需要外界服务，到能够对外界提供服务，而每个人接受的知识和自己的能力决定了最终他能够为外界提供哪种服务，随着时间周期和自身的消耗慢慢老化，直至死亡，软件也是如此，开始我们只是依据目前的静止的需求将其创建出来，可我们错就错在用一种静止的眼光去看待软件，其实它是在我们的不断提供信息的过程中，不断成长，同时从我们提供的信息中它在学习强化了自身的功能，并能够提供给我们更多功能，也就是目前各大网站提供的对外接口服务，其实yahoo或google开始这些网站系统是没有能力提供这些服务的，为什么是因为它们没有足够支持这些服务的信息，就好比它们开始只是婴儿还需要我们提供信息给它，让它成长一样，当它在我们不断的信息营养下成长成为一个巨人的时候，它们反过来能够为我们做更多以往我们都没有想过能做的事，这就是一个软件生命体，而不是我们传统意义上的建筑，建筑的功能是有限的而生命体的功能是无限的，因此你硬要将一个不变的软件去适应不断变化的环境那是种错误！因此，我们需要一种全新的思想去指导我们去设计软件那就是“面向生命”！<br /><br />第一章：什么是面向生命编程<br /><br />   面向生命编程是以面向对象为基础，将对象赋予生命特质的一种编程思想。
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/190452#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 08:44:52 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/190452</link>
        <guid>http://mikel.javaeye.com/blog/190452</guid>
      </item>
      <item>
        <title>QuickBase快速开发应用程序</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/185865" style="color:red;">http://mikel.javaeye.com/blog/185865</a>&nbsp;
          发表时间: 2008年04月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          只是通过web在线进行表结构的设置和界面参数的设置，然后用Flex Builder中安装的插件调用web服务器提供的编程接口，类似coghead.com 不由的惊叹，原来应用如此轻松！<br /><br />对这种模式我觉得很有前途！<br /><br />演示：http://quickbase.intuit.com/partners/developer-program/<br />step1:Create the QuickBase<br /><a href="http://www.screencast.com/t/RoiEXoqNap" target="_blank"><img src="http://quickbase.intuit.com/images/developer_program/step1_video.gif" /></a><br />step2:Add the Flex UI for Customers<br /><a href="http://www.screencast.com/t/MTa3erTVgaV" target="_blank"><img src="http://quickbase.intuit.com/images/developer_program/step2_video.gif" /></a><br />step3:Connect to QuickBooks Data and Build Support Rep experience<br /><a href="http://www.screencast.com/t/ZZLg8a2eQ" target="_blank"><img src="http://quickbase.intuit.com/images/developer_program/step3_video.gif" /></a>
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/185865#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 23 Apr 2008 13:30:29 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/185865</link>
        <guid>http://mikel.javaeye.com/blog/185865</guid>
      </item>
      <item>
        <title>Response.End()用法</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/182457" style="color:red;">http://mikel.javaeye.com/blog/182457</a>&nbsp;
          发表时间: 2008年04月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          ASP开发中可能有时候会用大段的if... else 的判断，不过如果是动态Response.write的内容，你想更方便阅读代码，可以用Response.End()来终端ASP的执行，也就类似于Break的用法，举个例子：<br /><pre name="code" class="java">
  if (userid="")or(password="") then
  	Response.Write("&lt;script lanuage=javascript>alert('UserName or Password is Empty！');location.href='../default.asp';&lt;/script>")

	Response.End() ‘这里进行了中断
  end if

  下面是不为空进行读取数据库的操作，省略了n行代码

</pre><br /><br />这样当传入的用户名或密码为空时,自动write提示信息信息，然后Response.End()中断程序，从而达到if 。。。else的作用。<br /><br />另外使用Response.End的时候，就是我们日常调试程序的时候，比如<br /><br />相输出拼接的SQL语句，而不想执行下面的代码，那么可以这么做<br /><pre name="code" class="java">

sql="select * from userinfo "

response.Write(sql)

response.End()

rs.open sql ,conn,1,1 '这句是不会执行的
</pre><br /><br />如果怕加入Response.End()的地方过多而正式发布时候不好注释掉的化，可以用个函数将其封装起来，如下面代码：<br /><pre name="code" class="java">

sub debug()
  Response.End()
end sub
</pre><br /><br />上面的代码修改如下：<br /><pre name="code" class="java">

sql="select * from userinfo "

response.Write(sql)

debug()

rs.open sql ,conn,1,1 '这句是不会执行的

</pre><br /><br />这样当进行正式发布时，将函数debug中的语句注释掉，就可以起到调试的作用，不过这个也有个问题就是，如果你使用太多的debug()，可能在调试的时候程序会不能按照需要进行中断，可能有时候你不希望这些地方中断执行，那么我们来进一步重构debug()函数，如下：<br /><pre name="code" class="java">
sub debug(isBreak)
  'isBreak是boolean值的参数，如果设置为true的时候则进行中断，否则，不进行中断处理
  if isBreak then
     Response.End()
  end
end sub
</pre><br /><br />使用时候代码如下：<br /><pre name="code" class="java">
sql="select * from userinfo "

response.Write(sql)

debug(false)

rs.open sql ,conn,1,1 '这句是会执行的

rs.close()

sql="select * from product "

response.write(sql)

debug(true)

rs.open sql,conn,1,1 '这句不会执行

</pre><br /><br />好了，这样基本上可以满足我们控制中断的需求了，不过只是简单的进行了分析，其实还很不完善，调试需求可能还有很多，需要满足，还需要进一步重构。其实程序开发就是一个重构重构再重构的过程，要不怎么会出来那么多的设计模式，都是前人从实际开发重构过程总结出来的经验，值得大家借鉴。
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/182457#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 14 Apr 2008 08:32:53 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/182457</link>
        <guid>http://mikel.javaeye.com/blog/182457</guid>
      </item>
      <item>
        <title>SpringSource宣布将被微软收购</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/178526" style="color:red;">http://mikel.javaeye.com/blog/178526</a>&nbsp;
          发表时间: 2008年04月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          InfoQ的地址还有在线视频：<br />http://www.infoq.com/cn/news/2008/04/microsoft-springsource-purchase<br /><br />作者 Ryan Slobojan译者 Jason Lai（赖翥翔） 发布于 2008年4月1日 上午12时20分 <br /><br />社区 Architecture, .NET, Java 主题 Web框架, .NET框架, 购并, 企业架构 标签 Spring Dynamic Modules, Windows, 微软, Spring.NET, Spring Web Flow, ASP.NET, Windows7, 收购, OSGi, Spring框架, Microsoft Office, Visual Studio <br />SpringSource（译注：原Interface21，Spring框架背后的公司）的CEO Rod Johnson发表了一则令人震惊的声明，他宣称SpringSource已经同意接受微软收购的请求。InfoQ就此事对Johnson进行独家采访，深入了解此次购并计划，以及这次购并将给Spring和.NET框架的未来带来什么。<br /><br /> <br />Johnson在一开始阐述了这次购并案的主要条款——由于SpringSource是一家私人公司，关于这次交易的完整细节在此不做透露。尽管如此，据了解，购并价格已经赶超Sun在一月份对MySQL十亿美元的收购价格。此外，Johnson还表示，这次购并将引起SpringSource核心关注领域的变化——SpringSource将把焦点放在壮大Spring产品线中基于.NET的部分，并且基于.NET版本的Spring Web Flow还将作为ASP.NET Web开发API的基础。<br /><br />Johnson向InfoQ透露，微软和SpringSource开发团队之间的整合战役已经打响：<br /><br />Johnson、Bill Gates和Ray Ozzie已经就如何使用Spring框架简化和模块化微软的多数代码，解决微软在产品发布总是跳票的历史问题展开讨论； <br />Spring IDE团队的Christian Dupuis也开始与Visual Studio团队合作，致力于将这两套代码整合起来； <br />Juergen Hoeller与Office团队合作，进行和即将发布的Office套件2009版之间整合点的研究； <br />Costin Leau开始探索如何为.NET创建OSGi运行时容器； <br />Adrian Colyer也开始了与S. Somasegar的合作，为微软的开发者部门制定未来的方向和战略。 <br />Johnson还指出，Spring框架会被纳入Windows操作系统当中，这样一来，用户即可通过相关联的Spring Beans完成对多数设置和应用程序的配置。当被问及是否下一个版本的Windows（Windows 7）是否会被称作“SpringHorn”时，Johnson拒绝发表评论——不过，他确实难掩Spring被纳入每个Windows安装版本这个前景的兴奋心情。<br /><br />Spring.NET项目的创始人和领导人Mark Pollack补充道：<br /><br />Anders Hejlsberg、Erik Meijer还有我进行了几次精彩的谈话，讨论Spring.NET能从哪些方面提升.NET应用程序的开发过程，并且我们希望能在.NET框架的4.0发布版中加入许多已有的Spring API。AOP和Aspect命名空间很可能被加到System命名空间中，而DAO和Data命名空间也将扩充现有的ADO.NET API。
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/178526#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Apr 2008 18:03:17 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/178526</link>
        <guid>http://mikel.javaeye.com/blog/178526</guid>
      </item>
      <item>
        <title>Flex测试工具RIATest发布Beta版</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/172860" style="color:red;">http://mikel.javaeye.com/blog/172860</a>&nbsp;
          发表时间: 2008年03月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Flex测试工具RIATest发布Beta版<br /><br />作者 Moxie Zhang译者 郭晓刚 发布于 2008年3月12日 上午12时40分<br /><br />社区<br />    Java<br />主题<br />    RIA<br /><br />RIATest是一个Flex自动化GUI测试工具，它刚刚公开发布了Beta版。InfoQ为此采访了RIATest的创造者Tigran Najaryan。<br /><br />Najaryan首先谈到了创造RIATest的目的：<br /><br />    RIATest 是一个用来对Adobe Flex 3程序进行自动化GUI测试的工具。创造RIATest的目的是为了给商业和专业开发者提供一个简单、干净的测试自动化方案，帮助他们保证产品的质量。我们在定价上非常激进，一心把测试自动化带给更多的Flex用户，而这些用户以前都负担不起其它的Flex测试自动化方案。<br /><br />说到RIATest如何工作的时候，Najaryan解释说：<br /><br />     从技术上看，RIATest由两部分组成：Agent和IDE（或者命令行执行器）。Agent呆在浏览器一方，直接与被测程序打交道。Agent提供了组件查看器（Component Inspector），让你检查和监视被测程序的GUI组件及其属性。Agent还通过TCP连接与IDE相连。Agent与IDE在回放期间（IDE向 Agent发送指令并接收结果）以及录制期间（Agent把录下的动作通知给IDE）都经由这个TCP连接相互沟通。<br /><br />    测试脚本是用RIAScript语言写的。RIAScript是一个简化版的ActionScript（另有些微扩展）——因此熟悉ActionScript的开发者很容易学会编写RIATest的测试脚本。<br /><br />RIATest是用什么开发的？Najaryan回答说：<br /><br />    RIATest从一开始就是作为Flex 3测试自动化工具来设计的，它使用了Flex的测试自动化框架。RIATest IDE是用C++和wxWidgets库写的。RIATest Agent是用Flex 3开发的。<br /><br />由于现在已经可以见到不少Flex测试工具，所以InfoQ请Najaryan将RIATest与其它工具比如FlexUnit作一下比较：<br /><br />    RIATest作为一个自动化GUI测试工具，与单元测试等其他测试手段是相辅相成的。必须通过多种自动化测试手段才能得到最高质量的保证，自动化GUI测试和单元测试都包括在内。<br /><br />谈到如何测试连通性，如HTTP请求和SOAP连接：<br /><br />    RIATest内建了按照指定条件自动或手动进行同步的功能，因此即使程序需要与远程数据源通信，RIATest也能完全胜任自动化测试的工作。QA工程师可以通过“'waitfor'”操作让测试脚本与被测程序的组件状态同步。<br /><br />最后，Najaryan给出了一段测试脚本的例子：<br /><br />RIATest Script<br />查看英文原文：<a href="http://www.infoq.com/news/2008/03/riatest-beta-released" target="_blank">RIATest for Flex Released Beta Product</a>
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/172860#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 17 Mar 2008 10:33:39 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/172860</link>
        <guid>http://mikel.javaeye.com/blog/172860</guid>
      </item>
      <item>
        <title>从标签时代到富客户端：从Web 1.0到Flex</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/170524" style="color:red;">http://mikel.javaeye.com/blog/170524</a>&nbsp;
          发表时间: 2008年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          从标签时代到富客户端：从Web 1.0到Flex<br /><br />作者 James Ward & Shashank Tiwari译者 韩锴 发布于 2008年3月6日 下午8时4分<br /><br />社区<br />    Java<br />主题<br />    RIA,<br />    Web 2.0,<br />    Web框架<br /><br />简介<br /><br />iPhone的成功明白无误地说明了一个事实：用户希望在他们的软件体验中感受到更多的交互。更多的交互可以让用户更好地利用程序的特性，提高他们的效率。这就是为什么“交互”不仅仅在个人信息管理程序中、而且在企业级业务程序中也是非常关键的。良好交互性的最大受益者是各种涉及到数据可视化的企业应用程序，因为更高的效率直接转化为了更好的决策，也立即会变为商业利润。 Dashboard是最典型的数据可视化应用程序。最具讽刺意味的是，今天大多数Dashboard在创建高效的用户体验的过程中，缺少交互性。因此我们决定一点点地美化一个典型的Web 1.0的Dashboard，给它增加更多的交互和丰富的功能。我们不会从头开始创建完整的应用程序，这未免是在重复发明车轮。相反，我们会重新设计界面，并把它整合到现有的服务器端架构中。通过这次学习，我们会完成一个简单但有意义的转 换。<br />相关厂商内容<br /><br />通过Oracle SQL、Linux和Ruby解决与数据集相关的问题<br /><br />基于浪潮Loushang统一平台的电力行业解决方案<br /><br />《IDC：SOA中国路线图》技术分析报告下载<br /><br />我们在练习中使用的Dashboard是开源的Pentaho BI套件的一部分。数据和视图来自于Pentaho BI发行 版中的示例应用程序。<br /><br />尽管我们的示例程序是一个Dashboard应用程序，但是其中的概念可以用于任何需要从Web 1.0迁移到 RIA的项目中。我们选用的RIA工具集是Adobe Flex。我们在此讨论的内容，全部是基于Flex框架、Flash VM以及相关支持库的。<br /><br />如果你想亲自动手完成本文介绍的内容，应该安装下面的软件：<br /><br />    * 免费的Flex SDK, Flash Player 9 （安装在浏览器中）以及Flex Builder 3 Public Beta 2（可选的）<br />    * Pentaho 1.6 Demo Bundle<br /><br /><br />记住首先要启动Pentaho服务器、登录到Dashboard，然后才能运行Flex界面。Flex界面假设你已经登录并通过验证了。源代码还假设服务器会监听8080端口、等待HTTP请求。如果你的Pentaho HTTP服务器需要监听其他的端口，请修改源代码。为了方便那些希望跳过安装Pentaho服务器这步骤的人，下载的 Pentaho源代码绑定包中还包含一个伪数据集版本的Flex界面。<br /><br />现在已经万事俱备了，下面可以仔细研究我们的示例程序了。<br />看看我的Pentaho Dashboard<br /><br />首先是免责声明——这篇文章能够仅仅提供了一点浅尝辄止的体验。尽管不是必须的，不 过如果你希望在深入学习本文前先了解一些背景知识的话，可以到learn.adobe.com或者flex.org去看看。这篇文章也没有打算讲述创建可维护的代码构架的最佳 实践，或者用户界面的设计实践。比如，尽管使用Ely Greenfield的Chart drill down组件 [demo]可以改进用户体验，但是它 也会让你付出更多的努力才能设置并运行示例程序，因此我们在示例中并没有选用它。我们希望为那些只想简单了解一下代码的人，提供一种单纯的复制与粘贴的体验。如果混入了第三方的组件或者一个实实在在的MVC架构，将会令这个体验变得复杂。如果你想进一步深入挖掘这些主题，可以在网上或者Adobe Developer Connection上找到大量的相关文章。<br />为了让你能够对我们即将创建的东西有一个了解，我们先来看看最终 的效果。查看Demo。<br /><br /> <br /><br />而Pentaho Dashboard最初的样子却是这样的：<br /><br />正如前文提到的，我们使用Flex创建新的Dashboard。这个基于Flex的Dashboard是用声明式的MXML语言和过程式的ActionScript语言编写的，并利用免费的Flex SDK编译为SWF文件。SWF文件是Flash Player VM上的字节码。你可以在浏览器中运行SWF文件，或者通过Adobe整合运行时（AIR）将它转化为一个桌面应用程序。让我们先来看看创建新的Dashboard的源代码。<br /><br />&lt;?xml version="1.0" encoding="utf-8"?><br />   &lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"   creationComplete="initApp()" layout="horizontal"><br />    &lt;mx:Script><br /> &lt;![CDATA[<br /> // import classes used in ActionScript and not   used in the MXML<br /> // ActionScript is code generated from MXML by the free Flex SDK's   mxmlc compiler<br /> // The generated ActionScript can be viewed if you pass mxmlc the -  compiler.keep-generated-actionscript argument<br /> import mx.charts.HitData;<br /> import   mx.collections.ArrayCollection;<br /> import mx.rpc.events.ResultEvent;<br /><br /> //   Bindable is a metadata / annotation which generates event code so that the variable<br /> //   can be used in an MXML Binding Expression, ie. dataProvider="{territoryRevenue}  "<br /> [Bindable] public var territoryRevenue:ArrayCollection;<br /> [Bindable] public   var productlineRevenue:Object;<br /> [Bindable] public var topTenCustomersRevenue:Object;<br /><br />  // Variables in ActionScript have namespaces like in Java.  You can use the   typical public,<br /> // private, and protected namespaces as well as create your own   namespaces<br /> // Object types are specified with a colon character and are optional but   recommended.<br /> private var _selectedTerritory:String = "*";<br /> private var   _selectedProductLine:String = "*";<br /><br /> // the initApp function is called   when the Application's creationComplete event is fired (see the mx:Application tag above<br /> private function initApp():void<br /> {<br /> // initializes our data caches<br />   productlineRevenue = new Object();<br /> topTenCustomersRevenue = new Object();<br /><br />   // initiates the request to the server to get the Sales by Territory data<br /> // tSrv is   defined in MXML below.  It could also have been defined in ActionScript but would have been   slightly more verbose tSrv.send();<br /><br /> // Since the Sales by Product Line and Top   Ten Customer Sales depend on the selected territory<br /> // we make a call to the functions   that will fetch the data based on the selected territory (or pull it from cache)<br /> // in   this case the selected territory is "*" or our indicator for all.  When the users   selects a new territory<br /> // these methods will be called again but the selected   territory will be different<br /> updateProductLineRevenue();<br />   updateTopTenCustomersRevenue();<br /> }<br /><br /> // Setter method that causes the data   stores for the Sales by Product Line and Top Ten Customer Sales<br /> // to be updated and   the charts to be updated accordingly<br /> public function set selectedTerritory  (territory:String):void<br /> {<br /> // update the private backing variable<br />   _selectedTerritory = territory;<br /><br /> updateProductLineRevenue();<br />   updateTopTenCustomersRevenue();<br /> }<br /><br /> // Getter method that returns the   selected Territory<br /> // This method has the Bindable metadata / annotation on it so that   the selectedTerritory property can<br /> // be used in a binding expression<br /> [Bindable]   public function get selectedTerritory():String<br /> {<br /> return _selectedTerritory;<br /> }<br /><br /> // Setter method similar to selectedTerritory but for the selected product   line<br /> public function set selectedProductLine(productLine:String):void<br /> {<br />   _selectedProductLine = productLine;<br /><br /> updateTopTenCustomersRevenue();<br /> }<br /><br /> [Bindable] public function get selectedProductLine():String<br /> {<br /> return   _selectedProductLine;<br /> }<br /><br /> // If the data is in cache then just directly   update the chart based on the selected territory.<br /> // If the data is not in cache then   assemble the name value pairs that are needed by the<br /> // web service request, then make   the request.<br /> private function updateProductLineRevenue():void<br /> {<br /> if   (productlineRevenue[_selectedTerritory] == undefined)<br /> {<br /> productlineRevenue  [_selectedTerritory] = new ArrayCollection();<br /><br /> var p:Object = new Object();<br /><br /> if (_selectedTerritory != "*")<br /> {<br /> p.territory =   _selectedTerritory;<br /> }<br /><br /> plSrv.send(p);<br /> }<br /> else<br /> {<br />   plPie.dataProvider = productlineRevenue[_selectedTerritory];<br /> }<br /> }<br /><br /> //   Similar to updateProductLineRevenue except that both the selected territory and<br /> // the   selected product line determine the data set.<br /> private function   updateTopTenCustomersRevenue():void<br /> {<br /> if (topTenCustomersRevenue  [_selectedTerritory + '_' + _selectedProductLine] == undefined)<br /> {<br />   topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine] = new   ArrayCollection();<br /><br /> var p:Object = new Object();<br /><br /> if   (_selectedTerritory != "*")<br /> {<br /> p.territory = _selectedTerritory;<br />   }<br /><br /> if (_selectedProductLine != "*")<br /> {<br /> p.productline =   _selectedProductLine;<br /> }<br /><br /> ttcSrv.send(p);<br /> }<br /> else<br /> {<br />   ttcBar.dataProvider = topTenCustomersRevenue[_selectedTerritory + '_' +   _selectedProductLine];<br /> }<br /> }<br /><br /> // This function handles a response from   the server to get the Sales by territory.  It reorganizes that data<br /> // into a format   that the chart wants it in.  The tPie chart notices changes to the underlying   ArrayCollection<br /> // that happen inside the for each loop.  When it sees changes it   updates it's view of the data.<br /> private function handleTResult  (event:ResultEvent):void<br /> {<br /> territoryRevenue = new ArrayCollection();<br />   tPie.dataProvider = territoryRevenue;<br /><br /> var hdr:ArrayCollection =   event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-HDR-ROW']['COLUMN-HDR-  ITEM'];<br /> for each (var pl:Object in   event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])<br /> {<br /> var   spl:Object = new Object();<br /> spl[hdr[0]] = pl['DATA-ITEM'][0];<br /> spl[hdr[1]] = pl  ['DATA-ITEM'][1];<br /> territoryRevenue.addItem(spl);<br /> }<br /> }<br /><br /> //   Similar to handleTResult except that it handles the data for Sales by Product Line<br />   private function handlePLResult(event:ResultEvent):void<br /> {<br /> var   hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-  HDR-ROW']['COLUMN-HDR-ITEM'];<br /> <br /> for each (var pl:Object in   event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])<br /> {<br /> var   spl:Object = new Object();<br /> spl[hdr[0]] = pl['DATA-ITEM'][0];<br /> spl[hdr[1]] = pl  ['DATA-ITEM'][1];<br /> productlineRevenue[_selectedTerritory].addItem(spl);<br /> }<br /><br /> plPie.dataProvider = productlineRevenue[_selectedTerritory];<br /> }<br /><br /> //   Similar to handleTResult except that it handles the data for Top Ten Customer Sales<br />   private function handleTTCResult(event:ResultEvent):void<br /> {<br /> var   hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['ROW-HDR-  ROW'];<br /> var pl:ArrayCollection =   event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'];<br /><br /> for   (var i:int = 0; i &lt; pl.length; i++)<br /> {<br /> var spl:Object = new Object();<br />   spl.name = hdr[i]['ROW-HDR-ITEM'][0];<br /> spl.sales = pl[i]['DATA-ITEM'];<br />   topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine].addItemAt(spl,0);<br /> }<br /><br /> ttcBar.dataProvider = topTenCustomersRevenue[_selectedTerritory + '_' +   _selectedProductLine];<br /> }<br /><br /> // This function is called to format the   dataToolTips on the tPie chart.<br /> private function formatTPieDataTip  (hitdata:HitData):String<br /> {<br /> return "&lt;b>" + hitdata.item.TERRITORY   + "&lt;/b>&lt;br>" + cf.format(hitdata.item.SOLD_PRICE);<br /> }<br /> ]]  ><br /> &lt;/mx:Script><br /><br /> &lt;!-- These HTTP Services communicate via HTTP   to a server --><br /> &lt;mx:HTTPService id="tSrv"   url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel-  wheels/homeDashboard&action=Sales_by_Territory.xaction" result="handleTResult  (event)"/><br />  &lt;mx:HTTPService id="plSrv"   url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel-  wheels/homeDashboard&action=Sales_by_Productline.xaction"   result="handlePLResult(event)"/><br />  &lt;mx:HTTPService   id="ttcSrv" url="http://localhost:8080/pentaho/ServiceAction?  solution=samples&path=steel-wheels/homeDashboard&action=topnmdxquery.xaction"   result="handleTTCResult(event)"/><br />  &lt;!-- Non-visual component to format   currency's correctly.  Used in the formatTPieDataTip function --><br />   &lt;mx:CurrencyFormatter id="cf" precision="0"/><br /><br /> &lt;!--   Effects used to make the charts more interactive --><br /> &lt;mx:SeriesInterpolate   id="plEffect"/><br /> &lt;mx:SeriesSlide id="ttcSlide"   direction="right"/><br /><br /> &lt;!-- Stacked vertical layout container --  ><br /> &lt;mx:VBox height="100%" width="40%"><br /> &lt;!-- Nice   box with optional drop shadows, title bars, and control bars --><br /> &lt;mx:Panel   width="100%" height="100%" title="Revenue By Territory"><br /> &lt;!-- Pie Chart --><br /> &lt;mx:PieChart id="tPie" width="100%"   height="100%" showDataTips="true"   dataTipFunction="formatTPieDataTip"><br /> &lt;!-- Sets the itemClick property   on the PieChart to the embedded ActionScript code.  We could have also called a function   defined above. --><br /> &lt;mx:itemClick><br /> // calls the appropriate setter   method<br /> selectedTerritory = event.hitData.item.TERRITORY;<br /><br /> // tells the pie   chart to explode the pie wedge the user click on<br /> var explodeData:Array = [];<br />   explodeData[territoryRevenue.getItemIndex(event.hitData.item)] = 0.15;<br /> tPie.series  [0].perWedgeExplodeRadius = explodeData;<br /> &lt;/mx:itemClick><br /> &lt;!-- Sets the   series property on the Pie Chart. --><br /> &lt;mx:series><br /> &lt;!-- The Pie   Series defines how the Pie Chart displays it's data. --><br /> &lt;mx:PieSeries   nameField="TERRITORY" field="SOLD_PRICE"   labelPosition="insideWithCallout" labelField="TERRITORY"/><br />   &lt;/mx:series><br /> &lt;/mx:PieChart><br /> &lt;/mx:Panel><br /><br /> &lt;!-- A   Binding Expression in the title bar of the Panel uses the Bindable getter for the   selectedTerritory property --><br /> &lt;mx:Panel width="100%"   height="100%" title="Revenue By Product Line (Territory =   {selectedTerritory})"><br /> &lt;mx:PieChart id="plPie" width="100%  " height="100%" showDataTips="true"><br />   &lt;mx:itemClick><br /> selectedProductLine = event.hitData.item.PRODUCTLINE;<br /><br />   var explodeData:Array = [];<br /> explodeData[productlineRevenue  [_selectedTerritory].getItemIndex(event.hitData.item)] = 0.15;<br /> plPie.series  [0].perWedgeExplodeRadius = explodeData;<br /> &lt;/mx:itemClick><br />   &lt;mx:series><br /> &lt;!-- The showDataEffect on the Series uses Binding to (re)use an   effect defined above --><br /> &lt;mx:PieSeries nameField="PRODUCTLINE"   field="REVENUE" labelPosition="insideWithCallout" showDataEffect="  {plEffect}" labelField="PRODUCTLINE"/><br /> &lt;/mx:series><br />   &lt;/mx:PieChart><br /> &lt;/mx:Panel><br /> &lt;/mx:VBox><br />  &lt;mx:Panel   width="100%" height="100%" title="Top 10 Customers (Territory =   {selectedTerritory} | Product Line = {selectedProductLine})"><br /> &lt;mx:BarChart   id="ttcBar" width="100%" height="100%"   showDataTips="true"><br /> &lt;mx:series><br /> &lt;mx:BarSeries   xField="sales" showDataEffect="{ttcSlide}"/><br />   &lt;/mx:series><br /> &lt;mx:verticalAxis><br /> &lt;mx:CategoryAxis   categoryField="name"/><br /> &lt;/mx:verticalAxis><br />   &lt;/mx:BarChart><br /> &lt;/mx:Panel><br /><br /> &lt;/mx:Application><br /><br />下载并查看源代码。注意应用程序有两个版本。一个是使用伪数据集的 pentaho_dashboard_demo.mxml，另一个是会连接到真实的Pentaho服务器以获取数据的 pentaho_dashboard.mxml。<br />迁移过程<br /><br />向RIA迁移的过程的第一步是设计一个新界面。同时你还需要明确如何向应用程序暴露出数据和服务。 Pentaho已经为我们暴露出了数据和服务，所以留下来最难的部分是把数据解析为Flex Charting组件所期望的格式。最终你可以将后端的服务与新的界面挂接到一起。让我们来深入每一步的细节。<br />设计新的接口<br /><br />创建新RIA接口的最佳思考方式是什么？不是考虑如何使现有的接口更丰富，而是要以用户希望如何查看以及与数据交互为出发点，重新进行思考。在这个过程中，设计师会发挥很大的作用。如果可能，尽可能地发挥他们的创造性。作为开发者，你可以先创建一个原型。为了提高效率，你需要创建一个模拟数据集。你可以在Sales_by_Productline.xaction、Sales_by_Territory.xaction和 topnmdxquery.xaction文 件中找到我们使用的数据集。在例子中，我把模拟数据集做成与Pentaho暴露出来的Web Services很相似 。尽管这不是必须的，但它简化了挂接到真正的服务上所需的工作。 有了模拟数据集，我们可以在设计 上进行更快的迭代了。<br /><br />我们所做的设计看上去与原来的Dashboard几乎一样。如果有一位设计师帮助我们（实际上并没有），我们可以拿出更有创造性的产品。尽管如此，我们这些开发者还是能够创建出有更多交互的Dashboard。我们其实可以设计出更复杂的界面来，但是在这个例子中，还是希望保持代码易于阅读和理解。<br /><br />创建UI的代码相当直接。下面的MXML代码就能创建一个PieChart：<br /><br />&lt;mx:PieChart width="100%" height="100%"><br />      &lt;mx:series><br />       &lt;mx:PieSeries nameField="TERRITORY"   field="SOLD_PRICE" labelPosition="insideWithCallout"   labelField="TERRITORY"/><br />    &lt;/mx:series><br />   &lt;/mx:PieChart><br /><br />为了增加交互性，你可以添加一个itemClick事件处理器：<br /><br />&lt;mx:itemClick><br /> selectedTerritory = event.hitData.item.TERRITORY;<br /><br />  var explodeData:Array = [];<br /> explodeData[territoryRevenue.getItemIndex  (event.hitData.item)] = 0.15;<br /> tPie.series[0].perWedgeExplodeRadius = explodeData;<br /> &lt;/mx:itemClick><br /><br />当我们设置selectedTerritory时（就像在itemClick事件处理器中所做的），会引起一些其他的动作 。这个例子中，我们希望刷新数据集，这个数据集与相应的饼图绑定到一起了：<br /><br />public function set selectedTerritory(territory:String):void<br /> {<br />    _selectedTerritory = territory;<br /><br />   updateProductLineRevenue();<br />    updateTopTenCustomersRevenue();<br /> }<br /><br />我们也可以很简单地为数据集已改变的Chart增加一个平滑的转化。第一件要做到事情就是添加一个我 们打算使用的效果的实例<br /><br />&lt;mx:SeriesInterpolate id="plEffect"/><br /><br />我们还需要把showDataEffect绑定到效果的实例上，这样，当数据发生变化后，就可以通知饼状图使 用这个效果了<br /><br />&lt;mx:PieSeries nameField="PRODUCTLINE" field="REVENUE"   labelPosition="insideWithCallout" showDataEffect="{plEffect}"   labelField="PRODUCTLINE"/><br /><br />我们也可能想增加一个鼠标悬浮时的提示：<br /><br />&lt;mx:PieChart id="tPie" width="100%" height="100%"   showDataTips="true" dataTipFunction="formatTPieDataTip"><br /><br />dataTipFunction被命名为formatTPieDataTip，后者返回一个自定义的字符串：<br /><br />private function formatTPieDataTip(hitdata:HitData):String<br /> {<br />     return   "&lt;b>" + hitdata.item.TERRITORY + "&lt;b>&lt;br>" +   cf.format(hitdata.item.SOLD_PRICE);<br /> }<br /><br />我们可以指定很多其他的风格来自定义应用程序的感观（look and feel）。开发者可以将风格内联在 属性中，也可以定义在外部的CSS文件中。<br />暴露后端<br /><br />使用Pentaho，我们可以很容易地发现Web Service并与之交互。Web Service给我们提供了用于 Dashboard的数据。可以返回按照区域分布的销售版图的URL是（在本地运行时）： 这里。<br /><br />有些URL会携带参数，来确定返回什么数据集。例如，“十大客户”的Web Service可以带 有两个参数，区域和产品类型，它们共同决定了应该返回哪些信息。<br />将前端挂接到后端<br /><br />要想把前端挂接到后端，你首先要创建一个HTTPService（如果使用的是SOAP，则创建WebService）：<br /><br />&lt;mx:HTTPService id="tSrv"   url="http://localhost:8080/pentaho/ServiceAction?solution=<br />samples&path=steel  -wheels/homeDashboard&action=Sales_by_Territory.xaction"<br />result="handleTResult(event)"/><br /><br />result属性指定了响应从服务器返回后要执行的代码。在这个例子中，我们只要调用一个名为 handleTResult的方法，并传递一个Event类型的参数就可以了。这个方法负责把我们接收到的数据转换为 Charts所需的样式。无论我们在使用Charts还是其他诸如DataGrid之类的组件，都需要一些简单的处理。在这个例子中，我们要对数据做一些处理然后再把它交给Chart。<br /><br />private function handleTResult(event:ResultEvent):void<br /> {<br />   territoryRevenue   = new ArrayCollection();<br />   tPie.dataProvider = territoryRevenue;<br /><br />    var   hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-  HDR-ROW']['COLUMN-HDR-ITEM'];<br /><br />   for each (var pl:Object in   event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])<br />  {<br />     var spl:Object = new Object();<br />   spl[hdr[0]] = pl['DATA-ITEM'][0];<br />   spl[hdr[1]]   = pl['DATA-ITEM'][1];\\\\\\\\<br />   territoryRevenue.addItem(spl);<br />  }<br /> }<br /><br />在这个例子里，所有的代码都放到一个文件中了。在实际的项目中，我们会按照模型、视图和控制器的架构将它拆分到不同的文件中。我们在其他的时间里详细讨论如何使用正确的设计模式来构建大型的应用程序。至此，我们就完成了这个示范的应用程序。从现在开始到本文结束，我们将通过Adobe Flex讨论 RIA的一些有趣的方面。<br />这个示例的精彩之处为何？<br /><br />这个简单的示例证明了对于传统的Web应用程序来说，丰富的、带有更多交互的用户界面是多么重要。这个程序的美妙之处，是它为现有的程序提供一个很棒的界面，却不需要进行大量的重构。这种便利一部分要归因于Pentaho暴露出了它的服务器端调用，另一部分归因于Flex能够平稳地消化掉这些服务的能力 ，这得利于Flex的组件和数据绑定模型。<br /><br />这里示例同样示范了如何谨慎地选择、匹配各种技术。一个优秀的、健壮的Java服务器程序可以有效 地被挂接到一个富Flex界面，从而创造出令人眩目的程序。这是一个很有前景的方向，这个示例希望能将 这种理念带入现实。<br /><br />应用程序的另一方面是，我们通过真实的、可运行的代码能够看到，使用ActionScript和MXML构建 Flex应用程序是多么容易。对于大多数熟悉Java和XML语法的人来说，ActionScript和MXML看起来是相当 亲切的。不是吗？<br />现在还差什么？如何弥补这一缺口？<br /><br />这个示例并不是产品级的软件。它更关注于一个简单的原型。但是，如果花些时间将Pentaho Web Service调用抽象为一个ActionScript库，这可能是迈向健壮程序的第一步。有一些开源项目已经开始着手构建这样的库了。示例程序也在向这个方向靠拢，并且使用了很少的一些面向对象的构造。应用MVC架构模式，面向接口编程，恰当地使用继承和多态，就能创建出可维护的、干净的应用程序。在示例程序中，我们只是简单复制了旧程序的外观。在理想的情况下，我们应该根据交互性需求创建出全新的界面，然 后将可视化组件和Web Service组件绑定到一起。为了创建出满足生产环境要求的应用程序，我们应该投 入时间和精力。<br />进一步阅读<br /><br />这个示例仅仅是富互联网应用程序的冰山一角。 比如我们可做的改进之一就是把图表做成可以逐层深 入（drill down）细节的，并加上更有意义的过渡效果。Ely Greenfield建了一个很漂亮的演示，他详细 说明了如何用Flex Charts实现drill down效果，请移步他的博客 。我们使用的是Flex 2构建示例程序，不过在Flex 3中，Chart 组件还包含了一些新的特性。你可以在这里或者这里读到更多的信息。如果你想学习Flex编程，可以查看 flex.org和learn.adobe.com 。<br />关于作者<br /><br />James Ward是Adobe公司的Flex技术布道者，也是Adobe的JCP代表，负责JSR 286、299和301。就像他最爱的爬山一样，他也热爱编程，认为它提供了无穷尽的新发现。他在爬山的过程中到过很多地方。同样，技术也带给他很多冒险经历，其中包括：九十年代早期是pascal和汇编；九十年代中期是Perl、HTML和 JavaScript；Java及其大量框架都是始于九十年代后期。现在他的主要工作是利用Flex构建好看的前端，而后端还是基于Java。在来到Adobe之前，他曾经创建过一个服务门户。你可以在他的博客上了解更多信 息：www.jamesward.org。<br /><br />Shashank Tiwari是Saven Technologies首席技术官。Saven Techologires位于芝加哥，为银行和金融服务公司提供服务。 Shashank是一位经验丰富的开发者、作家和演说家，在是JSR 274, 283, 299, 301和312专家组的成员。他对大量语言都感兴趣，包括Java、ActionScript、Ptyhon、Perl、PHP、G++、Groovy、JavaScript、 Ruby和Matlab。他也是OReilly网络的知名作者。最近他在忙于使用Flex和Java构建Web 2.0应用程序。更 多信息可以访问：www.shanky.org。<br /><br />查看英文原文：<a href="http://www.infoq.com/articles/web-flex-port;jsessionid=5ED636F8B16A6F6887AEE53E54E888E7" target="_blank">From Tags to Riches: Going from Web 1.0 to Flex</a>
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/170524#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Mar 2008 14:09:50 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/170524</link>
        <guid>http://mikel.javaeye.com/blog/170524</guid>
      </item>
      <item>
        <title>Javascript遍历XML</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/170513" style="color:red;">http://mikel.javaeye.com/blog/170513</a>&nbsp;
          发表时间: 2008年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          XML文档：<br /><pre name="code" class="java">
&lt;company>
	&lt;person>
		&lt;name>mikel&lt;/name>
		&lt;code>11231&lt;/code>
		&lt;sex>man&lt;/sex>
	&lt;/person>
	&lt;person>
		&lt;name>fifi&lt;/name>
		&lt;code>11221&lt;/code>
		&lt;sex>women&lt;/sex>
	&lt;/person>	
&lt;/company>
</pre><br />javascript代码<br /><pre name="code" class="java">
	function initialize(){
		
		AjaxUpdater.Update("GET","services/sample.xml",onResponse);
	}
	function onResponse(){
		
		if(Ajax.checkReadyState('loading')==200)
		{
			
			var persons=Ajax.getResponse().getElementsByTagName('person');
			//alert(Ajax.getResponse().getElementsByTagName("person")[1].childNodes[1].nodeValue);
			for(var i=0;i&lt;persons.length;i++)
			{
				//取person的子节点
				var items=Ajax.getResponse().getElementsByTagName('person')[i].childNodes;
				//遍历
				for(var k=0;k&lt;items.length;k++)
				{
					//注意FireFox中会出现多个名为#text的节点，IE中则不会，所以加入了这句判断
					if(persons[i].childNodes[k].nodeName!="#text"){
					document.getElementById("body").innerHTML+=
					Ajax.getResponse().getElementsByTagName('person')[i].childNodes[k].firstChild.nodeValue+'&lt;br/>';
					}
				}
				
			}
			
		}
	}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/170513#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Mar 2008 13:50:06 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/170513</link>
        <guid>http://mikel.javaeye.com/blog/170513</guid>
      </item>
      <item>
        <title>Adobe开源项目站</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/165922" style="color:red;">http://mikel.javaeye.com/blog/165922</a>&nbsp;
          发表时间: 2008年02月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          推荐大家去Adobe的开源项目网站<br /><br />http://opensource.adobe.com/wiki/display/site/Projects<br /><br />这里有很多及时的新闻和开源项目信息
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/165922#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 28 Feb 2008 17:47:08 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/165922</link>
        <guid>http://mikel.javaeye.com/blog/165922</guid>
      </item>
      <item>
        <title>flexBuilder3发布列</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/164682" style="color:red;">http://mikel.javaeye.com/blog/164682</a>&nbsp;
          发表时间: 2008年02月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          可以确定了，2月25日，也就是今天FLEX3 终于发布了！！<br /><img src="http://www.uncool.cn/blogs/attachment/1203697573_0.jpg" />
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/164682#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Feb 2008 10:31:02 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/164682</link>
        <guid>http://mikel.javaeye.com/blog/164682</guid>
      </item>
      <item>
        <title>[转]变量作用域的问题</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/151927" style="color:red;">http://mikel.javaeye.com/blog/151927</a>&nbsp;
          发表时间: 2007年12月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          变量作用域的问题：<br />public String getAnswer()<br /> {  String myAnswer;<br />  try<br />  {   <br />   BufferedReader bfReader=new BufferedReader(new InputStreamReader(System.in));<br />      myAnswer=new String(bfReader.readLine().toString());<br />   System.out.println("你输入的是："+myAnswer);    <br />  }<br />  catch(Exception e){}<br />  return myAnswer;  <br /> }<br />}<br /><br />这个方法总是报错，按以前的思路，myAnawer应已赋值了，怎会是还没赋值？<br /><br />原来，这就是变量的作用域的问题，我把它改为：<br /><br /> public String getAnswer()<br /> { <br />  String myAnswer=new String(""); //注意这里<br /> /*总结：定义在某个区域内的变量，必须在这个区域中NEW,象本方法，就不能用<br />  String myAnswer;然后再下一层括号中NEW*/<br />  try<br />  {   <br />   BufferedReader bfReader=new BufferedReader(new InputStreamReader(System.in));<br />   myAnswer=bfReader.readLine().toString();<br />   //System.out.println("你输入的是："+myAnswer);    <br />  }  <br />  catch(Exception e){}<br />  //System.out.println(myAnswer); <br />  return myAnswer;<br /> }<br /><br />因为变量的作用域不能跳出它分配空间的那一对大括号 。<br /><br />当然，也可以把String myAnswer跳出方法体，直接作为类中的一个变量，那么在方法中也可以直接使用这个变量。如<br /><br />String myAnswer;<br /> public String getAnswer2()<br />  {  <br />   try<br />   {   <br />    BufferedReader bfReader=new BufferedReader(new InputStreamReader(System.in));<br />       myAnswer=new String(bfReader.readLine().toString());<br />    System.out.println("你输入的是："+myAnswer);    <br />   }<br />   catch(Exception e){}<br />   return myAnswer;  <br />  <br /> }
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/151927#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Dec 2007 10:25:40 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/151927</link>
        <guid>http://mikel.javaeye.com/blog/151927</guid>
      </item>
      <item>
        <title>满江红翻译的Seam2.0CR的文档</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/151922" style="color:red;">http://mikel.javaeye.com/blog/151922</a>&nbsp;
          发表时间: 2007年12月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          新年新气象，满江红发布了中文文档<br /><br />http://www.redsaga.com/opendoc/Seam2.0/html/
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/151922#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Dec 2007 09:36:11 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/151922</link>
        <guid>http://mikel.javaeye.com/blog/151922</guid>
      </item>
      <item>
        <title>Flash的历史[转]</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/151708" style="color:red;">http://mikel.javaeye.com/blog/151708</a>&nbsp;
          发表时间: 2007年12月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          出自：http://www.uncool.cn/blogs/read.php?156<br />对一个开发FLASH的人来说，这点FLASH历史还是应该需要知道的:<br />     在1996年,一家叫FutureWave的小软件公司发布了一个FutureSplash 的动态变化小程序.这就是FLASH的前身,在 FutureSplash 开发出来的时候,是为Netscape开发的全新网页浏览插件.具有讽刺意味的是, 这家FutureWave的公司本来打算是想把这技术卖给Adobe, 但是在那个时候,Adobe根本不感兴趣. 而Macromedia却对此非常感兴趣, 就这样在1996的12月, 在拥有了FutureWave这家公司的技术后, Macromedia 把FutureSplash 重新命名为:Flash Player 1.0.   而在2005年4月ADOBE却以34亿美元收购了Macromedia,真是折腾.<br />     以下是FLASH PLAYER的发展史:<br />1997 - FutureSplash重新命名为Macromedia Flash 1.0.并且发布.<br /><br />1997 - Flash 2 加入了按钮,库,声音文件和色彩动态变化支持.<br /><br />1998 - Flash 3 加入了新的动态和透明度支持.<br /><br />1999 - Flash 4 加入了MP3流媒体支持和动画动态支持(我就是在那个时候接触的,学动画,泡MM.估计很多人都是).<br /><br />1999 - Flash Player安装量第一次达到了一百万.<br /><br />2000 - Flash 5 历史性的加了代码语言: ActionScript 1.<br /><br />2000 - Flash Player安装在同类型插件中,已经超过了百分之92的占有率.<br /><br />2002 - Flash Player 6 加入了Flash remoting, Web services, 视频, 共享库和组件.<br /><br />2003 - Flash Player 7  ActionScript 升级为2.0,并且加大了对声音和视频的支持.<br /><br />2005 - Flash Player 8 加入了滤镜效果, GIF和PNG的图片支持, bitmap支持, 新的视频编码(On2 VP6), 文件的上传下载,和FlashType.<br /><br />2006 - Flash Player 9 发布,并且重新引入开发语言,也就是ActionScript 3,更加正规的编程方式,对XML 的全新支持等.<br /><br />2007年11月 - Flash Player 9插件安装到达了3.2亿<br /><br />      总的来说,2006年是FLASH PLAYER 最重要的一年，特别是AS3发布后，意味着FLASH不再是小打小闹,在随后带来的FLEX2,更是以一种全新的姿态来面对未来的市场.从2006年开始,ADOBE就着手打造的大型舰队,基本就已经全面到位,你可以细数一下,Adobe软件涉及的行业和范围.那么你就可以知道,在SILVER和 FLEX的比拼中，FLEX不是一个人在战斗.<br />     2007年,可以说FLEX年,其发展的势头更是凶猛,在12月发布的FLASH PLAYER 9 r115版本更是支持了全新的视频格式和声音编码,在马上要到来的2008年,1月FLEX 3就正式发布.FLASH PLAYER 10也整装待发.
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/151708#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 29 Dec 2007 10:34:03 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/151708</link>
        <guid>http://mikel.javaeye.com/blog/151708</guid>
      </item>
      <item>
        <title>Android 文档的阅读顺序！[转]</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/150798" style="color:red;">http://mikel.javaeye.com/blog/150798</a>&nbsp;
          发表时间: 2007年12月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Android 文档的阅读顺序！<br /><br />因为看了看Android Blog, 在最新的文章里面介绍了几篇文章，其中一篇是&lt;&lt;以开发者的眼光来看Android SDK>>，作者在其中分析了的关于DOC的阅读顺序引起了我的兴趣，确实，那么多的文档，应该怎么看呢？哪些是必须先弄明白的？哪些应该先知道个大概，今后引用的时候再细细阅读？现在简要的介绍一下原作者的观点，希望能帮上你的忙。<br /><br />1. 首先当然是要知道，什么是Android？<br />2. 读一下Anatomy of an Android Application 能够知道一个Android application 中到底都有些什么东西<br />3.  接着可以读一下 Development Tools 文档<br />4.  然后可以看一下关于什么周期的文章 Lifecycle of an Android Application<br />5. 现在可以动手了，玩玩hello world 吧，Hello Android<br />6. 回去读一下 Installing the SDK文档，再这篇文章的后半部分讲了很多关于Debug的功能和技巧<br />7. 开始Notepad Application 的制作和学习吧，如果你真正弄懂了关于这个应用程序的4个练习，你已经从菜鸟开始转向高手喽。<br />8. Developing Android Applications 花了很多时间来介绍更多的细节，包括如何实现UI，数据存储和读取，安全问题等<br />9. 最后，你现在可以自由的漫步在links中了，找你感兴趣的读读吧。
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/150798#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Dec 2007 21:55:43 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/150798</link>
        <guid>http://mikel.javaeye.com/blog/150798</guid>
      </item>
      <item>
        <title>[转]什么是JNDI</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/150736" style="color:red;">http://mikel.javaeye.com/blog/150736</a>&nbsp;
          发表时间: 2007年12月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          JNDI全称 Java Naming and Directory Interface<br />JNDI 是Java平台的一个标准扩展，提供了一组接口、类和关于命名空间的概念。如同其它很多Java技术一样，JDNI是provider-based的技术，暴露了一个API和一个服务供应接口（SPI）。这意味着任何基于名字的技术都能通过JNDI而提供服务，只要JNDI支持这项技术。JNDI目前所支持的技术包括LDAP、CORBA Common Object Service（COS）名字服务、RMI、NDS、DNS、Windows注册表等等。很多J2EE技术，包括EJB都依靠JNDI来组织和定位实体。<br /> JDNI通过绑定的概念将对象和名称联系起来。在一个文件系统中，文件名被绑定给文件。在DNS中，一个IP地址绑定一个URL。在目录服务中，一个对象名被绑定给一个对象实体。<br /> JNDI 中的一组绑定作为上下文来引用。每个上下文暴露的一组操作是一致的。例如，每个上下文提供了一个查找操作，返回指定名字的相应对象。每个上下文都提供了绑定和撤除绑定名字到某个对象的操作。JNDI使用通用的方式来暴露命名空间，即使用分层上下文以及使用相同命名语法的子上下文。<br />  jndi的用途：<br /> 1。你可以用jndi来得到object类的属性<br />如：Attribute attr =directory.getAttributes(personName).get("email");<br />  String email = (String)attr.get();<br /> 2。你可以用jndi来搜索对象<br />如：foxes = directory.search("o=Wiz,c=US", "sn=Fox", controls);<br />查找谁的名字叫Fox在wiz部门的员工？<br /> 3。你可以用jndi通过naming/directory服务查询像printers和databases的对象<br />如：查询  Printer<br />Printer printer = (Printer)namespace.lookup(printerName);<br />printer.print(document);<br /> 4。你可以用jndi列表出命名空间的特殊级别的内容<br />如：<br />  NamingEnumeration list = namespace.list("o=Widget, c=US");<br />while (list.hasMore()) {<br />  NameClassPair entry = (NameClassPair)list.next();<br />  display(entry.getName(), entry.getClassName());<br />}<br />以上根据jndi文档翻译的<br />地址：<br />http://java.sun.com/products/jndi/overview.html<br />tomcat数据库连接池配置中的<br />java:comp/env代表你的JVM的环境,comp=computer env=environment<br /> <br /> <br />JNDI(The Java Naming and Directory Interface，Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来，使得我们可以用名称访问对象。目录服务是一种命名服务，在这种服务里，对象不但有名称，还有属性。<br />命名或目录服务使你可以集中存储共有信息，这一点在网络应用中是重要的，因为这使得这样的应用更协调、更容易管理。例如，可以将打印机设置存储在目录服务中，以便被与打印机有关的应用使用<br /> <br />JNDI概述<br />我们大家每天都不知不觉地使用了命名服务。例如，当你在web浏览器输入URL,http://java.sun.com时，DNS(Domain Name System,域名系统)将这个符号URL名转换成通讯标识（IP地址）。命名系统中的对象可以是DNS记录中的名称、应用服务器中的EJB组件 (Enterprise JavaBeans Component)、LDAP(Lightweight Directory Access Protocol)中的用户Profile。<br />目录服务是命名服务的自然扩展。两者之间的关键差别是目录服务中对象可以有属性（例如，用户有 email地址），而命名服务中对象没有属性。因此，在目录服务中，你可以根据属性搜索对象。JNDI允许你访问文件系统中的文件，定位远程RMI注册的对象，访问象LDAP这样的目录服务，定位网络上的EJB组件。<br />对于象LDAP 客户端、应用launcher、类浏览器、网络管理实用程序，甚至地址薄这样的应用来说，JNDI是一个很好的选择。<br />JNDI架构<br />JNDI架构提供了一组标准的独立于命名系统的API,这些API构建在与命名系统有关的驱动之上。这一层有助于将应用与实际数据源分离，因此不管应用<br />访问的是LDAP、RMI、DNS、还是其他的目录服务。换句话说，JNDI独立于目录服务的具体实现，只要你有目录的服务提供接口（或驱动），你就可以使用目录。<br /> <br /> <br />JNDI 是一组API，它用命名/目录服务增强了网络应用。本文中的示例说明了用JNDI开发基于目录的应用是多么容易。它也说明了如何用同样的API访问不同的命名/目录服务。开发者不必学习不同的API。在某些情况下，例如，在RMI和CORBA应用中，JNDI允许你部署时才选择命名服务。<br />JNDI未来将增加的功能包括：与标准的Java SASL API(JSR-28，http://jcp.org/aboutJava/communityprocess/review/jsr028/) 的集成、支持国际化域名、支持安全DNS。<br />为了开始使用JNDI和LDAP，下载Sun ONE目录服务器试用版（http://wwws.sun.com/software/products/directory_srvr/home_directory.html），这个服务器支持多种语言、多种平台。<br /> <br /><br />Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1413171
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/150736#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Dec 2007 16:06:06 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/150736</link>
        <guid>http://mikel.javaeye.com/blog/150736</guid>
      </item>
      <item>
        <title>[转]继续Protected</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/150726" style="color:red;">http://mikel.javaeye.com/blog/150726</a>&nbsp;
          发表时间: 2007年12月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1. protected 访问控制符能被用于方法和成员变量。<br />    2. 声明为protected的方法和成员变量能被同一个包里的所有类所访问，就像默认修饰符package一样。<br />    3. 能被该类的子类所访问，子类可以和父类不在一个包中。<br />    这样，当你想让一个类中的某个方法或成员变量在包中都可见，而且其子类也能访问（子类有可能和父类不在同一个包中）但又不想让所有类都可以访问该类时，就可以用protected修饰符。<br />    可访问性：<br />    public > protected > package >private<br />    注意：<br />    4. but a subclass in another package can access the protected members in the super-class via only the references of subclass or its subclasses. a subclass in the same package doesn’t have this restriction. this ensures that classes from other packages are accessing only the members that are part of their inheritance hierarchy.<br /><br />   <br />    下面的例子可以说明上述几点：（特别注意第4点）<br />    我们将创建一个父类bird.java，放在birdpack包中，父类中有一个protected int的成员变量nfeathers;<br />    再分别创建4个bird类的子类duck1.java,duck2.java,duck3.java,swan.java，放在duckpack包中，通过在每个子类中调用nfeathers的不同方法说明上述几点<br /><br /><br />下面的程序并不用于运行，因为访问控制在编译期间就要确定，我们只需编译下述文件，看是否能通过。在编译下述文件前，先想想能不能编译通过？<br /><br />//bird.java------------------------------<br />package birdpack;<br /><br />public class bird{<br /> protected int nfeathers;<br /> <br />}<br /><br />//duck1.java-----------------------------<br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class duck1 extends bird{<br /> public void setn(int duck1n){<br />  //在子类中直接访问父类中的protected变量<br />  nfeathers=duck1n;<br /> }<br />}<br />//duck2.java------------------------------ <br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class duck2 extends bird{<br /><br /> public void construct(int newduck2){<br />  duck2 d2 = new duck2();<br />  //在子类中通过子类的对象访问父类中的protected变量<br />  d2.nfeathers=newduck2;<br /> }<br />}<br /><br />//duck3.java------------------------------<br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class duck3 extends bird{<br /><br /> public void construct(int newduck3){<br />  bird b = new bird();<br />  //子类中用父类对象反而不能访问父类中的protected变量<br />  b.nfeathers=newduck3;<br /> }<br />}<br /><br />//swan.java--------------------------------<br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class swan extends bird{<br /><br /> public void construct(int swan){<br />  duck1 d1 = new duck1();<br />  //子类中用另外一个子类的对象也不能访问父类中的protected变量<br />  d1.nfeathers=swan;<br /> }<br />}<br /><br />编译上述几个文件，后2个不能通过。编译器提示：<br />" nfeathers has protected access in birdpack.bird"。<br /><br />//bird.java------------------------------<br />package birdpack;<br /><br />public class bird{<br /> protected int nfeathers;<br /> <br />}<br /><br />//duck1.java-----------------------------<br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class duck1 extends bird{<br /> public void setn(int duck1n){<br />  //在子类中直接访问父类中的protected变量<br />  nfeathers=duck1n;<br /> }<br />}<br />//duck2.java------------------------------ <br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class duck2 extends bird{<br /><br /> public void construct(int newduck2){<br />  duck2 d2 = new duck2();<br />  //在子类中通过子类的对象访问父类中的protected变量<br />  d2.nfeathers=newduck2;<br /> }<br />}<br /><br />//duck3.java------------------------------<br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class duck3 extends bird{<br /><br /> public void construct(int newduck3){<br />  bird b = new bird();<br />  //子类中用父类对象反而不能访问父类中的protected变量<br />  b.nfeathers=newduck3;<br /> }<br />}<br /><br />//swan.java--------------------------------<br />package duckpack;<br /><br />import birdpack.bird;<br /><br />public class swan extends bird{<br /><br /> public void construct(int swan){<br />  duck1 d1 = new duck1();<br />  //子类中用另外一个子类的对象也不能访问父类中的protected变量<br />  d1.nfeathers=swan;<br /> }<br />}<br /><br />编译上述几个文件，后2个不能通过。编译器提示：<br />" nfeathers has protected access in birdpack.bird"。<br /><br />第4点说明，就算在子类中，也只能通过子类（或子类的子类）的引用来访问父类中的protected方法和成员变量。<br />在duck3和swan两个子类中，直接通过父类和另一个子类来访问父类中的protected方法和成员变量就不行。<br /><br />附：编译技巧<br />当编译含有包声明的源文件时，使用 -d 选项会带来很多方便，它能保证编译后的class文件存放在正确的目录路径下。<br />我们可以把上述5个文件都放在protectedtest目录下，然后用 -d 选项去编译：<br />javac -d . bird.java<br />javac -d . duck1.java<br />.....<br />其中.表示以当前目录创建包结构的目录层次。编译成功后，会在protectedtest下生成2个目录：birdpack和duckpack，里面是生成的class文件。<br /> <br /><br /><br />文章整理：站长天空 网址：http://www.z6688.com/
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/150726#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Dec 2007 15:52:42 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/150726</link>
        <guid>http://mikel.javaeye.com/blog/150726</guid>
      </item>
      <item>
        <title>[转]避免使用Protected</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/150722" style="color:red;">http://mikel.javaeye.com/blog/150722</a>&nbsp;
          发表时间: 2007年12月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          数据成员几乎总是一个实现细节。即使是在&lt;code>&lt;complex>&lt;/code> 这样的数字库中，通过将数据成员声明为 protected 或 public 来暴露数据是一个避免麻烦的办法。下面我将解释为什么 protected 类型的数据成员像 public 类型的数据成员一样糟糕。<br /><br />Protected 类型数据成员的问题<br /><br />当基类的实现发生变化时，能够访问基类 protected 类型数据成员的派生类也需要修改。这叫做耦合，耦合是面向对象的设计方法绝对需要避免的东西。<br /><br />具体的例子<br /><br />类complex 一般表示为一对浮点数据成员和一些额外的成员函数。它看上去似乎试图放弃传统的 get() 和 set() 成员函数，而赋予对这些成员的直接访问权。<br /><br />template &lt;class T> class complex<br />{<br />protected: //exposing data members to derived classes<br />T real;<br />T imaginary;<br />//..<br />};<br /><br />这看上去像是一个故意的例子；然而，在 Standard Library 中确实存在具有 protected 类型数据成员的类。你可能会感到奇怪这么简单的类的设计会如何改变。一种方式是其他人可能使用一个数组代替了它的两个数据成员，如下所示：<br /><br />template &lt;class T> class complex<br />{<br />protected:<br />T val[2];<br />//..<br />};<br /><br />或者也有可能是一些人将这两个成员包装为一个tuple类型或者包装成一个对（pair）。在这两种情况下，派生类也需要修改。你可能会争论说这些成员是受保护的，而不是公有的；因此，设计变化就只会影响派生类。问题是 protected 类型的数据成员引诱程序员滥用继承来获得对数据成员的直接访问。<br /><br />结束语<br /><br />你应该避免使用 protected 类型的数据成员，因为他们会造成对封装的一个错误的理解。相反，将数据成员声明为 private 类型并定义相应的成员函数来访问它们是必要的。通过使用这种方法，基类设计上的变化就不会影响其它类。此外，它也不会引诱程序员使用继承获得对数据成员的直接访问。最重要的是，基类的所有者可以自由地改变基类的实现，同时又保持原有接口不变，而不至引起检查所有的代码。<br />Danny Kalev是一个具有14年经验的系统分析家、软件工程师，尤其擅长C++ 和面向对象设计。
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/150722#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Dec 2007 15:47:25 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/150722</link>
        <guid>http://mikel.javaeye.com/blog/150722</guid>
      </item>
      <item>
        <title>JBoss设置为Windows服务</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/150143" style="color:red;">http://mikel.javaeye.com/blog/150143</a>&nbsp;
          发表时间: 2007年12月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这里将用到JavaService.exe 这个程序将JBoss启动做成Windows的系统服务。<br /><br />第一步： 复制 JavaService.exe 文件到%JBOSS_HOME%\bin目录下；<br />	如果没有JavaService.exe 可以在http://javaservice.objectweb.org/ 网站上下载；<br /><br />第二步： 设置环境变量：<br />	将JAVA_HOME设置成jdk的目录，例如：<br />		C:\jdk1.5.0_07<br />	将JBOSS_HOME设置成JBOSS的目录，例如：<br />		D:\JBoss4.0.5<br /><br />注意：在环境变量中目录不能有空格，否则会造成服务无法启动。<br /><br />第三步： 通过Windows的运行“cmd”或者“command”打开dos运行窗口；进入“%JBOSS_HOME%\bin”路径；<br /><br />第四步： 在将下面表格中的命令复制到dos窗口下回车运行：<br />JavaService.exe -install JBoss %Java_Home%\jre\bin\server\jvm.dll -Djava.class.path="%JBOSS_HOME%\bin\run.jar;%JAVA_HOME%\lib\tools.jar" –Xms256M –Xmx512M -start org.jboss.Main -stop org.jboss.Main -method systemExit -out "%JBOSS_HOME%\server\default\log\server.log" -err "%JBOSS_HOME%\server\default\log\boot.log" -current "%JBOSS_HOME%\bin" -overwrite -startup 6<br /><br />运行后，将会提示：“The JBoss automatic service war successfully installed”，提示服务安装完成，可以在Windows的服务管理列表中找到名称为“JBoss”的服务。输入：“net start JBoss”启动服务，服务启动可能需要一定时间，打开新的IE浏览器在地址栏输入：http://localhost:8080 会有提示页面，表示服务启动成功。<br /><br />如何卸载服务：<br />	在dos命令窗口输入：“JavaService.exe –uninstall 服务名称”<br />JBossService.exe -install JBoss<br />　　{JDK_HOME}\jre\bin\{hotspot|server|classic}\jvm.dll<br />　　-Djava.class.path={JDK_HOME}\lib\tools.jar;{JBOSS_BIN}\run.jar<br />　　-start org.jboss.Main<br />　　-stop org.jboss.Main -method systemExit<br />　　-out {JBOSS_BIN}\stdout.log<br />　　-err {JBOSS_BIN}\stderr.log<br />　　-current {JBOSS_BIN}<br />　　-depends mysql<br />　　-manual<br /><br />另外此方法也使用于其他的服务，需要在第四步时更改相应的参数。
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/150143#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 22 Dec 2007 15:38:23 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/150143</link>
        <guid>http://mikel.javaeye.com/blog/150143</guid>
      </item>
      <item>
        <title>Grails让我吃惊</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/149930" style="color:red;">http://mikel.javaeye.com/blog/149930</a>&nbsp;
          发表时间: 2007年12月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          gmail收到InfoQ的期刊，看到关于Grails的介绍新闻，并且SpringSide开发组翻译了Start with Grails 的文档可以下载，好奇于是下载下来reading。。。，真JB牛X，没一会儿就搞定了一个简单RaceTack的基本操作，突然有种久违的感觉，因为经历过用java开发企业级应用的痛苦的人都知道，J2EE不是那么容易做到，控制不好会死人的，特别是需求一直在变，客户一直在催的情况下，你想做好那只有不停的改，最终做出的东西乱七八糟，根本没法用，自信被打击的成立负数，这grails真的让问题傻瓜化了，现在项目注重对不再是什么先进技术，要得就是时间，No Time No Money！！继续Grails了
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/149930#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 21 Dec 2007 12:44:17 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/149930</link>
        <guid>http://mikel.javaeye.com/blog/149930</guid>
      </item>
      <item>
        <title>EJB3 QL查询</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/149119" style="color:red;">http://mikel.javaeye.com/blog/149119</a>&nbsp;
          发表时间: 2007年12月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          EJB3 QL查询<br /><br />EJB3的查询语言是一种和SQL非常类似的中间性和对象化查询语言。它可以被编译成不同的底层数据库能接受的SQL，从而屏蔽不同数据库的差异，确保用EJB3 QL查询语言编写的代码可在不同的数据库上运行。比起EJB 2.1的查询语言，EJB3可以运行期构造，支持多态，远远比EJB 2.1的查询更灵活和功能强大。在程序中使用EJB3 QL可以使用大写(SELECT)或者小写(select)，但不要大小写(比如:Select)混合使用。<br />　　　<br />Query接口<br /><br />javax.persistence.Query是EJB3查询操作的接口。进行查询，首先要通过EntityManager 获得Query对象。<br /><br />                <br />    public Query createQuery(String ejbqlString);                 <br />                <br />            <br /><br />下面我们做一个最简单的查询，查询所有的com.redsoft.samples.Order类。<br /><br />                <br />    final Query query = entityManager.createQuery( "select o from Order o"); <br />    final List result = query.getResultList();<br />    final Iterator iterator = result.iterator();<br />    while( iterator.hasNext() ){<br />        //　处理Order<br />    }<br />                <br />            <br /><br />注意"from Order"。"Order"在EJB3查询中称为com.redsoft.samples.Order类的abstract schema Type。查询Entity在EJB3 QL中都是针对Entity的Abstract Schema Type进行查询。在同一个EntityManagerFactory中，不允许同时有两个Abstract Schema Type相同的Entity类。比如不允许同时有com.redsoft.samples.Order和com.redsoft.foo.Order。　　<br /><br />Query返回一个List的集合结果，我们可以用Iterator或者List.get( int )的方法来获得每个符合条件的Entity。Liberator EJB3 Persistence运行环境的Query查询在构造Query的时候的只是把EJB3 QL编译成相应的SQL，但并不执行。只有当应用代码第一次调用Iterator.next(),Iterator.hasNext()或者 List.get( int )方法的时候,编译后的SQL才会被真正的执行。<br /><br />在Liberator EJB3 Persistence运行环境返回的结果集合中，并不保存所有的结果，而只是保持一个指向JDBC ResultSet或者缓存ResultSet的一个行(row)指针。只有当用户确实需要获得Entity实例的时候，才会从ResultSet中获取数据并填充到Entity实例中返回给应用。<br /><br />如果查询结果结合中包含所有符合条件的Entity, Liberator EJB3 Persistence运行环境默认会自动缓存每次查询的结果。这样下次同样的查询操作就无需访问数据库，而直接从缓存中返回结果集合。但如果在下次查询操作之前，有针对被缓存的Entity类进行update/insert/delete操作，则缓存的结果集合会自动被清空，这样下次查询就会从数据库获得数据， 确保查询总是获得正确的结果，避免缓存脏数据。<br /><br />有时候查询会返回海量的数据。Liberator EJB3运行环境采用了自适应的弱引用POJO管理机制，可以处理海量的数据。在我们的测试中和客户的环境可以处千万级别的数据量。但在处理大数据量的时候，注意关闭对集合结果的缓存。<br /><br />                <br />    <br />    // 假设返回的结果数量巨大<br />    final Query query = entityManager.createQuery( "select o from Order o");<br />    <br />    // 关闭对查询结果的缓存<br />    query.setHint( Constants.QUERY_RESULT_CACHE, "false");<br />    final List result = query.getResultList();<br />    final Iterator iterator = result.iterator();<br />    <br />    // 这里我们可以处理海量的数据<br />    while( iterator.hasNext() ){<br />        //　处理Order<br />    }<br />                <br />            <br /><br />　　<br />简单查询<br />下面是一个简单查询的例子，可以看到和SQL的使用方法很类似。<br /><br />                <br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = 1");<br />    <br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = 1 and o.confirm = 'true' ");<br />    <br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = 1 or o.customer = 'foo' ");<br />    <br />    <br />    // address是Order类上的一个对象变量属性，Address有一个streetNumber的属性<br />    final Query query = entityManager.createQuery( "select o from Order o where o.address.streetNumber >= 123" );<br /><br />              <br />    <br /><br />注意条件语句中查询的是Entity的属性，属性的名字需要和Entity中的属性变量名字一致。<br />使用参数查询<br /><br />参数查询也和SQL中的参数查询类似。EJB3 QL支持两种方式的参数定义方式: 命名参数和位置参数。在同一个查询中只允许使用一种参数定义方式。<br />命名参数:<br /><br />                <br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = :myId");<br />    <br />    // 设置查询中的参数<br />    query.setParameter( "myId", 2 );<br />    <br />    <br />    // 可以使用多个参数<br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = :myId and o.customer = :customerName" );<br />        <br />    // 设置查询中的参数<br />    query.setParameter( "myId", 2 );<br />    query.setParameter( "customerName", "foo" );<br />              <br />    <br /><br />注意不允许在同一个查询中使用两个相同名字的命名参数。<br /><br />位置参数：<br /><br />                <br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = ?1");<br />    <br />    // 设置查询中的参数<br />    query.setParameter( 1, 2 );// 1表示第一个参数，2是参数的值<br />    <br />    //或者<br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = ?1").setParameter( 1, 2 );<br />        <br />    <br />    // 可以使用多个参数<br />    final Query query = entityManager.createQuery( "select o from Order o where o.id = ?1 and o.customer = ?2" );<br />        <br />    // 设置查询中的参数<br />    query.setParameter( 1, 2 );<br />    query.setParameter( 2, "foo" );<br />              <br />    <br /><br />如果在未来需要在不同的EJB3 运行环境中运行，请使用位置参数，保证应用是可移植的。<br />排序(order by)<br />下面是一个简单查询的例子，可以看到和SQL的使用方法很类似。"ASC"和"DESC"分别为升序和降序，如果不显式注明，EJB3 QL中默认为asc升序。<br /><br />                <br />    // 不注明的话，默认为asc为升序,               <br />    final Query query = entityManager.createQuery( "select o from Order o order by o.id");<br />    <br />    final Query query = entityManager.createQuery( "select o from Order o order by o.address.streetNumber desc");// desc为降序<br />    <br />    final Query query = entityManager.createQuery( "select o from Order o order by o.id, o.address.streetNumber");<br />            <br />    <br /><br />查询部分属性<br />在前面的例子中，都是对针对Entity类的查询，返回的也是被查询的Entity类的实体。EJB3 QL也允许我们直接查询返回我们需要的属性，而不是返回整个Entity。在一些Entity中属性特别多的情况，这样的查询可以提高性能。<br /><br />                <br />    // 直接查询我们感兴趣的属性(列）<br />    final Query query = entityManager.createQuery( "select o.id, o.customerName, o.address.streetNumber from Order o order by o.id");<br />    <br />    // 集合中的不再是Order,而是一个Object[]对象数组<br />    final List result = query.getResultList();<br />    <br />    // 第一个行<br />    Object[] row = result.get( 0 );<br />    <br />    // 数组中的第一个值是id<br />    int id = Integer.parseInt( row[0].toString() );<br />    String customerName = row[1].toString();<br />    String streetNumber = Integer.parseInt( row[2].toString() );<br />   <br />            <br />    <br /><br />查询中使用构造器(Constructor)<br />EJB3 QL支持将查询的属性结果直接作为一个java class的构造器参数，并产生实体作为结果返回。<br /><br />                <br />    // 我们把需要的三个属性作为一个class( OrderHolder )的构造器参数，并使用new函数。                <br />    Query query = entityManager.createQuery("select new com.redsoft.ejb3.dummy.OrderHolder (   o.id, o.vender, o.partNumber  )  FROM Order AS o");<br />    <br />    // 集合中的结果是OrderHolder<br />    List result = query.getResultList();<br />            <br />         <br />    <br /><br />该java class不需要是Entity Class。NEW要求java class使用全名。<br />聚合查询(Aggregation)<br /><br />象大部分的SQL一样,EJB3 QL也支持查询中的聚合函数。目前EJB QL支持的聚合函数包括：<br /><br />    * AVG<br />    * SUM<br />    * COUNT<br />    * MAX<br />    * MIN<br /><br />                    <br />                    <br />    final Query query = entityManager.createQuery( "select MAX( o.id ) from Order where o.customerName='foo'");<br />        <br />    // 如果我们知道结果是单个，我们可以用getSingleResult()获得结果<br />    final Object result = query.getSingleResult();<br />        <br />    // 由于Order中id的类型为long,<br />    final Long max = (Long)result;<br />        <br />        <br />    // 在一些数据库中max函数返回的结果的类型不一定于id对应的列的类型相符，更安全的方式可以采用string来转型<br />    fina long max = Long.parseLong( result.toString() );<br />                <br />        <br /><br />聚合函数也可以作为被查询的一个属性返回。<br /><br />                    <br />    <br />    // 返回所有的订单的生产厂商和他们的订单价值总额<br />    final Query query <br />        = entityManager.createQuery( "select o.vender, sum(o.amount) FROM Order o　group by o.vender");");<br />                <br />        <br /><br />和SQL一样，如果聚合函数不是select...from的唯一一个返回列，需要使用"GROUP BY"语句。"GROUP BY"应该包含select语句中除了聚合函数外的所有属性。<br /><br />                    <br />    <br />    // 返回所有的订单的生产厂商的的名字，货物号码和每种货物的订单价值总额<br />    // 注意group by后面必须包含o.vender和o.partNumber<br />    final Query query <br />        = entityManager.createQuery( "select o.vender, o.partNumber, sum(o.amount) FROM Order o　group by o.vender，o.partNumber");<br />                <br />        <br /><br />如果还需要加上查询条件，需要使用"HAVING"条件语句而不是"WHERE"语句。<br /><br />                    <br />    <br />    // 返回所有的订单的生产厂商是"foo"的货物号码和每种货物的订单价值总额<br />    // 这里"having o.vender = 'foo'为条件<br />    final Query query <br />        = entityManager.createQuery( "select o.vender, o.partNumber, sum(o.amount) FROM Order o　<br />            group by o.vender，o.partNumber having o.vender='foo'");<br />        <br />        <br /><br />在"HAVING"语句里可以跟"WHERE"语句一样使用参数。<br /><br />                    <br />    <br />    // 返回所有的订单的生产厂商是"foo"的货物号码和每种货物的订单价值总额<br />    // 这里"having o.vender = 'foo'为条件<br />    final Query query <br />        = entityManager.createQuery( "select o.vender, o.partNumber, sum(o.amount) FROM Order o　<br />            group by o.vender，o.partNumber having o.vender=?1");<br />    query.setParameter( 1, "foo" );<br />    final List result = query.getResultList();<br />        <br />        <br /><br />关联(join)<br /><br />在EJB3 QL中，大部分的情况下，使用对象属性都隐含了关联(join)。例如在以下查询中：<br /><br />                <br />    final Query query = entityManager.createQuery( "select o from Order o<br />         where o.address.streetNumber=2000 order by o.id");<br />   <br />            <br />    <br /><br />当这个句EJB3 QL编译成以下的SQL时就会自动包含了关联,EJB3 QL编译成SQL时关联默认取左关联(left join)。<br /><br />    <br />    select o.id, o.vender, o.partNumber, o.amount, addressTable.id, addressTable.streetNumber <br />        from orderTable as o left join addressTable where addressTable.streetNumber = 2000<br />      <br />    <br /><br />但在一些情况下，我们仍然需要对关联做精确的控制。因此EJB3 QL仍然支持和SQL中类似的关联语法：<br /><br />    * left out join/left join<br />    * inner join<br />    * left join/inner join fetch<br /><br />left join, left out join等义，都是允许符合条件的右边表达式中的Entiies为空。<br /><br />                <br />    // 返回所有地址为2000的Order纪录，不管Order中是否有OrderItem                <br />    final Query query = entityManager.createQuery( "select o from Order o<br />         left join o.orderItems where o.address.streetNumber=2000 order by o.id");<br />   <br />                <br />    <br /><br />由于EJB3 QL默认采用left join。这样的查询和以下的EJB3 QL其实是等价的。<br /><br />                <br />    // 返回所有地址为2000的Order纪录，不管Order中是否有OrderItem                <br />    final Query query = entityManager.createQuery( "select o from Order o<br />          where o.address.streetNumber=2000 order by o.id");<br />   <br />                <br />    <br /><br />需要显式使用left join/left outer join的情况会比较少。<br /><br />inner join要求右边的表达式必须返回Entities。<br /><br />                <br />    // 返回所有地址为2000的Order纪录，Order中必须有OrderItem                <br />    final Query query = entityManager.createQuery( "select o from Order o<br />         inner join o.orderItems where o.address.streetNumber=2000 order by o.id");<br />   <br />                <br />    <br /><br />left/left out/inner join fetch提供了一种灵活的查询加载方式来提高查询的性能。在默认的查询中，Entity中的集合属性默认不会被关联，集合属性默认是缓加载( lazy-load )。<br /><br />                <br />                <br />``` // 默认EJB3 QL编译后不关联集合属性变量(orderItems)对应的表                <br />    final Query query = entityManager.createQuery( "select o from Order o<br />         inner join o.orderItems where o.address.streetNumber=2000 order by o.id");<br />    final List result = query.getResultList();<br />    <br />    // 这时获得Order实体中orderItems( 集合属性变量 )为空<br />    final Order order = (Order)result.get( 0 )<br />    <br />    // 当应用需要时，EJB3 Runtime才会执行一条SQL语句来加载属于当前Order的OrderItems<br />    Collection orderItems = order.getOrderItems();<br />   <br />                <br />    <br /><br />这样的查询性能上有不足的地方。为了查询N个Order，我们需要一条SQL语句获得所有的Order的原始/对象属性， 但需要另外N条语句获得每个Order的orderItems集合属性。为了避免N+1的性能问题，我们可以利用join fetch一次过用一条SQL语句把Order的所有信息查询出来。<br /><br />                <br />    // 返回所有地址为2000的Order纪录，Order中必须有OrderItem                <br />    final Query query = entityManager.createQuery( "select o from Order o<br />         inner join fetch o.orderItems where o.address.streetNumber=2000 order by o.id");<br />   <br />             <br />    <br /><br />由于使用了fetch,这个查询只会产生一条SQL语句，比原来需要N+1条SQL语句在性能上有了极大的提升。<br />比较Entity<br /><br />在查询中使用参数查询时，参数类型除了String, 原始数据类型( int, double等)和它们的对象类型( Integer, Double等),也可以是Entity的实例。<br /><br />                <br />    final Query query = entityManager.createQuery( "select o from Order o where o.address = ?1 order by o.id");<br />    <br />    final Address address = new Address( 2001, "foo street", "foo city", "foo province" );<br />    <br />    // 直接把address对象作为参数。<br />    query.setParameter( 1, address );<br />  <br />             <br />    <br /><br />批量更新(Batch Update)<br /><br />EJB3 QL支持批量更新。<br /><br />                <br />   Query query = managerNew.createQuery("update Order as o set o.vender=:newvender,  o.partNumber='fooPart' where o.vender = 'foo'");<br />   query.setParameter("newvender", "barVender");<br />   <br />   // update的记录数<br />   int result = query.executeUpdate();<br />            <br />    <br /><br />批量删除(Batch Remove)<br /><br />EJB3 QL支持批量删除。<br /><br />                <br />    Query query = managerNew.createQuery("DELETE FROM Order");<br />    int result = query.executeUpdate();<br />                <br />    Query query = managerNew.createQuery("DELETE FROM Order AS o WHERE o.vender='redsoft'");<br />    int result = query.executeUpdate();            <br />    <br />    <br />    <br />    <br /><br />使用操作符NOT<br /><br />                <br />                <br />    // 查询所有vender不等于"foo"的Order                <br />    Query query = managerNew.createQuery("SELECT FROM Order AS o WHERE not(o.vender='foo')");<br />    List result = query.getResultList();<br />                <br />    // 删除所有vender不等于"foo"的Order<br />    Query query = managerNew.createQuery("DELETE FROM Order AS o WHERE not(o.vender='foo')");<br />    int result = query.executeUpdate();            <br />    <br /><br />使用操作符BETWEEN<br /><br />                <br />                <br />    // 查询所有价值amount在５和10之间的(包含5,10)的Order               <br />    Query query = managerNew.createQuery("select o FROM Order AS o left join o.orderItems ot where o.amount BETWEEN 5 AND 10 order by o.vender desc");<br />    List result = query.getResultList();<br />         <br />    <br /><br />使用操作符IN<br /><br />                <br />    // 查询所有vender是"foo1", "foo2"或者"foo3"的Order                <br />    Query query = managerNew.createQuery("select o FROM Order AS o left join o.orderItems ot where o.vender in ( 'foo1', 'foo2', 'foo3' ) order by o.vender desc");<br />    List result = query.getResultList();<br />                        <br />         <br />    <br /><br />使用操作符LIKE<br /><br />                <br />    // 查询所有vender以字符串"foo"开头的Order                <br />    Query query = managerNew.createQuery("select o FROM Order as o where o.vender like 'foo%' order by o.vender desc");<br />    List result = query.getResultList();<br />    <br />    <br />    // 查询所有vender以字符串"foo"结尾的Order                <br />    Query query = managerNew.createQuery("select o FROM Order as o where o.vender like '%foo' order by o.vender desc");<br />    List result = query.getResultList();<br />    <br />    <br />    // 可以结合NOT一起使用，比如查询所有vender不以以字符串"foo"结尾的Order                <br />    Query query = managerNew.createQuery("select o FROM Order as o where o.vender not like '%foo' order by o.vender desc");<br />    List result = query.getResultList();<br />    <br />    // 可以结合escape使用，比如查询所有vender以"foo"开始的Order并忽略'3'字符。<br />    // 如果vender是"foo1", "foo2", "foo3"符合这个条件, 另外"3foo1", "f3oo4"也符合条件。<br />    Query query = managerNew.createQuery("select o FROM Order as o where o.vender like '%foo' escape '3' order by o.vender desc");<br />    List result = query.getResultList();<br />    <br />    <br />                        <br />         <br />    <br /><br />使用操作符IS NULL<br /><br />                <br />    // 查询所有没有地址的Order                <br />    Query query = managerNew.createQuery("select o FROM Order as o where o.address is null");<br />    List result = query.getResultList();<br />    <br />    // 查询所有地址非空的Order <br />    Query query = managerNew.createQuery("select o FROM Order as o where o.address is not null");<br />    List result = query.getResultList();<br />    <br />                        <br />         <br />    <br /><br />使用操作符IS EMPTY<br /><br />IS EMPTY是针对集合属性(Collection)的操作符。可以和NOT一起使用。<br /><br />                <br />    // 查询orderItems集合为空的Order                <br />    Query query = managerNew.createQuery("select o FROM Order o where o.orderItems is empty by o.vender desc");<br />    List result = query.getResultList();<br />    <br />   // 查询orderItems集合非空的Order                <br />    Query query = managerNew.createQuery("select o FROM Order o where o.orderItems is not empty by o.vender desc");<br />    List result = query.getResultList();                     <br />         <br />    <br /><br />使用操作符EXISTS<br /><br />[NOT]EXISTS需要和子查询配合使用。<br /><br />                <br />    Query query = manager.createQuery("select o FROM Order o where exists (select o from Order o where o.partNumber=?1) order by o.vender desc");<br />    query.setParameter(1, "partNumber");<br />    <br />    <br />    Query query = manager.createQuery("select o FROM Order o where o.vender='partNumber' and not exists (select o from Order o where o.partNumber=?1) order by o.vender desc");<br />    query.setParameter(1, "partNumber");<br />         <br />    <br /><br />使用操作符ALL/SOME/ANY<br /><br />                <br />    Query query = managerNew.createQuery("select emp from EmployeeA emp where emp.salary > all ( select m.salary from Manager m where m.department = emp.department)");<br />    List result = query.getResultList();<br />    <br />    Query query = managerNew.createQuery("select emp from EmployeeA emp where emp.salary > any ( select m.salary from Manager m where m.department = emp.department)");<br />    List result = query.getResultList();<br />    <br />    Query query = managerNew.createQuery("select emp from EmployeeA emp where emp.salary > some ( select m.salary from Manager m where m.department = emp.department)");<br />    List result = query.getResultList();<br />         <br />    <br /><br />字符串函数<br /><br />EJB3 QL定义了内置函数方便使用。这些函数的使用方法和SQL中相应的函数方法类似。EJB3 QL中定义的字符串函数包括：<br /><br />    * CONCAT　字符串拼接<br />    * SUBSTRING　字符串截取<br />    * TRIM 去掉空格<br />    * LOWER　转换成小写<br />    * UPPER　装换成大写<br />    * LENGTH 字符串长度<br />    * LOCATE 字符串定位<br /><br />       <br />    // concat将参数中的两个字符串并结成一个字符串,这里firstName是"foo", lastName是"bar"<br />    Query query = entityManager.createQuery("select concat( o.owner.firstName, o.owner.lastName ) FROM Order AS o left outer join o.orderItems as oi where o.owner.firstName='foo'");<br />    List result = query.getResultList();<br />    assertEquals("foobar", result.get(0).toString()); <br />        <br />    // firstName是"fooBar",结果应该返回"oo"<br />    Query query = entityManager.createQuery("select o.vender,substring( o.owner.firstName, 1, 3 ), o.owner.info.age FROM Order AS o left outer join o.orderItems as oi where o.owner.firstName='charles'");<br />    List result = query.getResultList();<br />    Object[] row1 = (Object[]) result.get(0);<br />    assertEquals("oo", row1[1].toString());<br />    <br />    // 获得"ar"在firstName中地起始位置<br />    Query query = managerNew.createQuery("SELECT emp.firstName , emp.salary , locate( emp.firstName, 'ar') FROM EmployeeA as emp where emp.firstName='charles1111'");<br />    List result = query.getResultList();<br />        <br />         <br />    <br /><br />计算函数<br /><br />EJB3 QL中定义的计算函数包括：<br /><br />    * ABS　绝对值<br />    * SQRT 平方根<br />    * MOD 取余数<br />    * SIZE 取集合的数量<br /><br />       <br />    Query query = entityManager.createQuery("select o.vender, size( o.orderItems ) FROM Order o  where o.owner.firstName = 'charles' group by o.vender order by o.vender desc");<br />    List result = query.getResultList();<br />    <br />    // 函数也可以用在条件中<br />    Query query = managerNew.createQuery("select o.vender, sum(o.amount) FROM Order AS o left join o.orderItems ot group by o.vender having size(o.orderItems) = 0 or lower( o.vender ) = 'foo' order by o.vender desc");<br />    List result = query.getResultList();<br /><br />    <br />    // 取余数<br />    Query query = managerNew.createQuery("select mod( o.owner.info.age, 10 ) FROM Order o where exists ( select o from Order o where o.partNumber= :name ) and o.vender='order1' and exists ( select o from Order o where o.amount= :name1 ) order by o.vender desc");<br />        <br />         <br />    <br /><br />子查询<br /><br />子查询可以用于WHERE和HAVING条件语句中。<br /><br />       <br />    Query query = managerNew.createQuery("select emp from EmployeeA as emp where ( select count(m) from Manager as m where m.department = emp.department) > 0 ");<br />    List result = query.getResultList();
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/149119#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 18 Dec 2007 14:18:35 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/149119</link>
        <guid>http://mikel.javaeye.com/blog/149119</guid>
      </item>
      <item>
        <title>Flex Builder2的源码下载【转】</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/148773" style="color:red;">http://mikel.javaeye.com/blog/148773</a>&nbsp;
          发表时间: 2007年12月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转自：http://kb.adobe.com/selfservice/viewContent.do?externalId=4b243413&sliceId=1<br /><br />Flex Builder 2 source code derived from Eclipse<br />Issue<br /><br />Adobe Flex Builder 2 is built on Eclipse 3.1.2, provided by the Eclipse Foundation. Additionally, Adobe Flex Builder 2 contains source code derived from Eclipse code. Both the Eclipse code and the code derived from Eclipse code are made available to the community under the terms of the Eclipse Public License v1.0 that accompanies such code, and is also available at http://www.eclipse.org/legal/epl-v10.html.<br />Solution<br /><br />The ZIP file linked below contains the Eclipse 3.1.2 code as well as Flex Builder code that is derived from Eclipse code. The Eclipse code that was derived for Flex Builder includes editor code, debugger code, workbench code, and editor and debugger icons.<br /><br />Download the Flex Builder 2 source code derived from Eclipse (106MB).<br /><br />The ZIP file linked below contains the Eclipse 3.2.1 Language Pack for Linux as well as the Japanese properties files that Flex Builder derived from the Eclipse Linux Japanese properties files. The properties files were updated to remove accelerator keys that are not used on the Mac platform.<br /><br />Download the Eclipse 3.2.1 Language Pack for Linux as well as the derived Japanese properties files (55MB).
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/148773#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 17 Dec 2007 10:02:05 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/148773</link>
        <guid>http://mikel.javaeye.com/blog/148773</guid>
      </item>
      <item>
        <title>为SUSE Linux操作系统搭建Java开发环境</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/148544" style="color:red;">http://mikel.javaeye.com/blog/148544</a>&nbsp;
          发表时间: 2007年12月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.下载JDK。这个不必说(我下载的是1.6.0_03)<br /><br />2.改变安装文件权限。在终端中用cd命令把当前目录转移到jdk-6u3- linux-i586-rpm.bin所在目录，用ls -l命令查看文件权限，如果是可执行x（eXecute）则不需要更改，否则用命令 chmod 755 jdk-6u3-linux-i586-rpm.bin，使自解压包文件可执行<br /><br />3.安装。在终端输入./jdk-6u3-linux-i586-rpm.bin,按提示一步步执行即可。<br /><br />4.更改环境变量。刚才安装的版本默认在/usr/java/jdk1.6.0_03，我们把它加到环境变量。用cd命令转移到etc目录，输入gedit profile,在profile在后三行<br /><br />#<br /><br /># End of /etc/profile<br /><br />#<br /><br />上面添加如下文本：<br /><br />export JAVA_HOME=/usr/java/jdk1.6.0_03<br /><br />export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar<br /><br />export JRE_HOME=$JAVA_HOME/jre<br /><br />5.重新启动系统，在终端输入java -version,显示内容：<br /><br />java version "1.6.0_03"<br /><br />Java(TM) SE Runtime Environment (build 1.6.0_03-b05)<br /><br />Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)<br /><br />说明环境变量设置成功。 <br /><br />6.安装Jboss 服务器 ，解压Jboss服务器到具体目录中<br /><br />7.在控制台中运行 sh run -b XXXX.XXXX.XXXX.XXXX 其中XXXX为IP地址， Jboss 默认绑定127.0.0.1 因此你需要绑定IP到你本机地址，然后其他用户才能访问
          <br/>
          <span style="color:red;">
            <a href="http://mikel.javaeye.com/blog/148544#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 15 Dec 2007 13:19:05 +0800</pubDate>
        <link>http://mikel.javaeye.com/blog/148544</link>
        <guid>http://mikel.javaeye.com/blog/148544</guid>
      </item>
      <item>
        <title>自定义jsp嵌套标签【转】</title>
        <author>mikel</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://mikel.javaeye.com">mikel</a>&nbsp;
          链接：<a href="http://mikel.javaeye.com/blog/148518" style="color:red;">http://mikel.javaeye.com/blog/148518</a>&nbsp;
          发表时间: 2007年12月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、基本