﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-世事如棋-文章分类-J2EE 相关</title><link>http://www.blogjava.net/kingwell/category/8835.html</link><description>Aspire to Professionalism</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 07:46:05 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 07:46:05 GMT</pubDate><ttl>60</ttl><item><title>开放源代码的全文检索引擎Lucene(转载） </title><link>http://www.blogjava.net/kingwell/articles/49510.html</link><dc:creator>KingWell</dc:creator><author>KingWell</author><pubDate>Thu, 01 Jun 2006 03:45:00 GMT</pubDate><guid>http://www.blogjava.net/kingwell/articles/49510.html</guid><wfw:comment>http://www.blogjava.net/kingwell/comments/49510.html</wfw:comment><comments>http://www.blogjava.net/kingwell/articles/49510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kingwell/comments/commentRss/49510.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kingwell/services/trackbacks/49510.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 目																				  																				录																																																																前																								       																								...&nbsp;&nbsp;<a href='http://www.blogjava.net/kingwell/articles/49510.html'>阅读全文</a><img src ="http://www.blogjava.net/kingwell/aggbug/49510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kingwell/" target="_blank">KingWell</a> 2006-06-01 11:45 <a href="http://www.blogjava.net/kingwell/articles/49510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是Portlet ?</title><link>http://www.blogjava.net/kingwell/articles/48559.html</link><dc:creator>KingWell</dc:creator><author>KingWell</author><pubDate>Sun, 28 May 2006 01:01:00 GMT</pubDate><guid>http://www.blogjava.net/kingwell/articles/48559.html</guid><wfw:comment>http://www.blogjava.net/kingwell/comments/48559.html</wfw:comment><comments>http://www.blogjava.net/kingwell/articles/48559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kingwell/comments/commentRss/48559.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kingwell/services/trackbacks/48559.html</trackback:ping><description><![CDATA[作者:Sunil Patil;<a href="http://www.matrix.org.cn/user.shtml?username=observer" target="_new">observer</a><br />原文地址:<a href="http://www.onjava.com/pub/a/onjava/2005/09/14/what-is-a-portlet.html" target="_new">http://www.onjava.com/pub/a/onjava/2005/10/19/challenging-java-dominance.html</a><br />中文地址:<a href="http://www.matrix.org.cn/resource/article/44/44029_Portlet.html" target="_new">http://www.matrix.org.cn/resource/article/44/44029_Portlet.html</a><br />关键词： Portlet Java<br /><br /><br /><b>Portlets </b><br />“Portlets是一种Web组件－就像servlets－是专为将合成页面里的内容聚集在一起而设计的。通常请求一个portal页面会引发多个portlets被调用。每个portlet都会生成标记段，并与别的portlets生成的标记段组合在一起嵌入到portal页面的标记内。”（摘自Portlet规范，JSR 168）<br /><br />本文探讨了以下内容：<br /><span style="COLOR: purple">1.        Portal页面的元素 <br />2.        Portal是什么？<br />3.        Portlets是什么？<br />4.        开发“Hello World” Portlet<br />5.        在Pluto上部署HelloWorld Portlet<br />6.        如何创建Portal页面<br />7.        结束语 <br />8.        资源</span><br /><br />　　Portlet规范将portlet定义为一种“基于Java技术的web组件，由处理请求和生成动态内容的portlet容器管理”。这段话听起来是不是有些费解？本文将说明portlets是什么以及能用它们做什么。<br /><br /><br />图1显示了在访问一个portal服务器时浏览器中页面的样子。<br /><br /><img onmouseover="javascript:imgShowTip(this);" style="DISPLAY: inline" onclick="javascript:imgClick(this);" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2005_12_05_021236_BwaZOpizXk.gif" width="600" onload="javascript:imgLoad(this);" border="0" resized="1" /><br />图1 典型的portal服务器的页面（点击查看原图）<br /><br />　　如果仔细查看浏览器里的页面，就会看到页面是由不同的“窗口”组成的。一个窗口用于刷新天气，另一个用于新闻，还有一个用于刷新股价，等等。这里的每一个窗口都代表了一个portlets。如果看得再仔细些，还会发现每个窗口都有一个标题条和一些按钮，包括最小化和最大化按钮。<br /><br />　　在系统里，这些窗口是相互独立开发、各不同的应用。新闻portlet的开发者创建应用并打包成war格式的文件,随后portal服务器的管理员在服务器上部署该war文件并创建页面，接下来每个用户会选择在他的页面里有哪些应用。例如，如果用户对股价不感兴趣而对体育感兴趣，他可以用“体育”窗口替换“股价”窗口。<br /><br />　　Portlet技术需要学习许多新概念，本文不可能全都涵盖，因此本文分为两部分。在第一部分里我们详细说明portals和portlets，并开发一个简单的“Hello World”portlet；在第二部分我们将探讨一些高级主题。<br /><br />　　我们将用Apache的Pluto服务器（Portlet API 1.0规范的参考实现）来测试我们的示例portlets，我们还会花些时间探讨如何安装和使用Pluto服务器。<br /><br /><b><span style="FONT-SIZE: 16px">Portal页面的元素</span></b><br /><br />图2显示了Portal页面的各种元素。<br /><br /><img onmouseover="javascript:imgShowTip(this);" style="DISPLAY: inline" onclick="javascript:imgClick(this);" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2005_12_05_021329_NzXorUBuvR.gif" onload="javascript:imgLoad(this);" border="0" resized="0" /><br />图2 portal页面的元素<br /><br />　　每个portlet页面由一个或多个portlet窗口组成，每个portlet窗口又分为两部分：一个是外观，它决定了portlet窗口的标题条、控制和边界的样式；另一个是portlet段，它由portlet应用填充。<br /><br />　　Portal服务器决定了portal页面的整体观感，像标识、标题条颜色、控制图标等。通过修改几个JSP和css模板文件就可以改变portal的整个观感。我们将在“如何创建portal页面”部分对此做深入讨论。<br /><br /><b><span style="FONT-SIZE: 16px">Portal是什么？</span></b><br /><br />　　在了解portlet之前有必要先了解portal。在Portlet规范里是这样讲的：“portal是一种web应用，通常用来提供个性化、单次登录、聚集各个信息源的内容，并作为信息系统表现层的宿主。聚集是指将来自各个信息源的内容集成到一个web页面里的活动”。<br /><br />　　Portal的功能可以分为三个主要方面：<br />1.        Portlet容器：Portlet容器与servlet容器非常类似，所有的portlet都部署在portlet容器里，portlet容器控制portlet的生命周期并为其提供必要的资源和环境信息。Portlet容器负责初始化和销毁portlets，向portlets传送用户请求并合成响应。<br />2.        内容聚集：Portlet规范中规定portal的主要工作之一是聚集由各种portlet应用生成的内容，我们将在“如何创建Portal页面”部分对此做进一步讨论。<br />3.        公共服务：portlet服务器的一个强项是它所提供的一套公共服务。这些服务并不是portlet规范所要求的，但portal的商业实现版本提供了丰富的公共服务以有别于它们的竞争者。在大部分实现中都有望找到的几个公共服务有：<br />         o 单次登录：只需登录portal服务器一次就可以访问所有其它的应用，这意味着你无需再分别登录每一个应用。例如一旦我登录了我的intranet网站，我就能访问mail应用、IM消息应用和其它的intranet应用，不必再分别登录这些应用。<br />　　Portal服务器会为你分配一个通行证库。你只需要在mail应用里设定一次用户名和密码，这些信息将以加密的方式存储在通行证库中。在你已登录到intranet网站并要访问mail应用的时候，portal服务器会从通行证库中读取你的通行证替你登录到mail服务器上。你对其它应用的访问也将照此处理。<br />          o个性化：个性化服务的基本实现使用户能从两方面个性化她的页面：第一，用户可以根据她的自身喜好决定标题条的颜色和控制图标。第二，用户可以决定在她的页面上有哪些portlets。例如，如果我是个体育迷，我可能会用一个能提供我钟爱球队最新信息的portlet来取代股票和新闻portlets。<br />      　　一些在个性化服务方面领先的商业实现版本允许你建立为用户显示什么样的应用所依据的标准（如收入和兴趣）。在这种情况下，可以设定一些像“对任何收入为X的用户显示馈赠商品的portlet”和“对任何收入为X的用户显示打折商品的portlet”这样的商业规则。<br /><br />　　      此外还有一些公共服务，比如机器翻译，是由portal服务器将portlet生成的内容翻译为用户要求的语言。大部分的商业portal服务器都支持手持设备访问并具有针对不同的浏览终端生成不同内容的能力。<br /><br /><b><span style="FONT-SIZE: 16px">Portlets是什么？</span></b><br /><br />　　与servlets类似，portlets是部署在容器内用来生成动态内容的web组件。从技术角度讲portlet是一个实现了javax.portlet.Portlet接口的类，它被打包成war文件格式部署到portlet容器里。<br /><br />　　Portlets在以下方面与servlets相似：<br />1.        portlets由特定的容器管理。<br />2.        portlets生成动态内容。<br />3.        portlet的生命周期由容器管理。<br />4.        portlets通过请求/响应模式与web客户端交互。<br /><br />　　Portlets在以下方面与servlets相异：<br />1.        portlets只能生成标记段，而不是整个文档。<br />2.        portlets没有可供直接访问的URL地址。不过你还是能够让别人通过URL访问到portlet，你可以把包含该portlet的页面的URL发给他。<br />3.        portlets不能随意地生成内容，这是因为portlet生成的内容最终要成为portal页面的一部分。如果portal服务器要求的是html/text类型，那么所有的portlets都应生成html/text类型的内容。再比方说，如果portal服务器要求的是WML类型，那么所有的portlets都应生成WML类型的内容。<br /><br />　　portlets还提供了一些附加的功能：<br />1.        设置参数的持久化存储：portlets提供了一个PortletPreferences对象用来保存用户的设置参数。这些参数被存入一个持久化数据库，这样服务器重启后数据依然有效。开发者不必关心这些数据存储的具体实现机制。<br />2.        请求处理：portlets提供了更为细粒度的请求处理。对于用户在portlet上动作时向该portlet发出的请求(一种称为活跃期的状态)，或者因用户在其它portlet上动作而引发的刷新页面请求，Portal服务器提供了两种不同的回调方法来处理。<br />3.        Portlet模式：portlets用模式的概念来表示用户在做什么。在使用mail应用的时候，你可能会用它来读信、写信或检查信件――这些都是mail应用的预定功能，Portlets通常以VIEW模式提供这些功能。但还有一些活动，像指定刷新时间或（重新）设置用户名和密码，这些活动允许用户定制应用的行为，因此它们用的是EDIT模式。Mail应用的帮助功能用的是HELP模式。<br /><br />　　如果仔细想想其实这里面并没有什么新东西，它们反而大部分都是普通的业务需求。Portlet规范的作用在于它提供了一个抽象层，这才是它对所有与之相关的人－最终用户、开发者和管理员－的价值所在。<br /><br />　　作为一个开发者，我会将所有与VIEW模式有关的业务逻辑放入doView()方法，将与应用配置有关的业务逻辑放入doEdit()方法，将与帮助有关的逻辑放入doHelp()方法<br /><br />　　这就简化了管理员对portlet应用的访问控制管理，因为他只需改变portlet的访问权限就能决定用户能做什么。例如，如果mail应用的一个用户能够在EDIT模式下设定用户名和密码，那么就可以断定他具有EDIT模式访问权限。<br /><br />　　不妨考虑这样一种情形：我是一个intranet网站的管理员，我的公司买了一个能显示新闻信息的第三方portlet应用，该应用允许用户指定跟踪新闻更新的URL地址，我想借助它为用户显示公司的内部新闻。另一个需求是我不想让用户通过该应用来跟踪任何其它的新闻信息来源。作为管理员，我可以为所有的用户指定一个用于内部新闻更新的URL地址，同时通过改变portlet应用的部署描述符来取消其它人修改该地址的权限。<br /><br />　　由于所有的portlet应用都具有相似的UI界面，因此采用portlets可使网站对最终用户更具吸引力。如果她想阅读任何一个应用的帮助信息，她可以点击帮助按钮；她也知道点击编辑按钮能让她进入应用的配置屏。标准化的用户界面使你的portlet应用更引人。<br /><br />4.        窗口状态：窗口状态决定了portal页面上留给portlet生成内容的空间。如果点击最大化按钮，portlet将占据整个屏幕，成为用户唯一可用的portlet；而在最小化状态，portlet只显示为标题条。作为开发者应当根据可用空间的大小来定做内容。<br /><br />5.        用户信息：通常portlets向发出请求的用户提供个性化的内容，为了能更加行之有效，portlets需要访问用户的属性信息，如姓名、email、电话等。Portlet API为此提供了用户属性的概念，开发者能够用标准的方式访问这些属性，并由管理员负责在这些属性与真实的用户信息数据库（通常是LDAP服务器）之间建立映射关系。<br /><br />　　我们将在本文的第二部分深入讨论这些特点－请求处理、用户信息和portlet模式。<br /><br /><b><span style="FONT-SIZE: 16px">开发"Hello World" Portlet</span></b><br /><br />　　现在我们就来开发一个简单的HelloWorld portlet。<br />1.        创建一个名为HelloWorld的web项目，它与通常的servlet项目类似，有一个/WEB-INF/web.xml文件作为项目的部署描述符。<br /><br />2.        在build path里加入portlet-api-1.0.jar文件，该jar文件是Pluto发行包的一部分。<br /><br />3.        在Source文件夹中按如下内容创建HelloWorld.java文件：<br /><pre class="overflow">public class HelloWorld extends GenericPortlet{<br />  protected void doView(RenderRequest request,<br />  RenderResponse response) throws<br />  PortletException, IOException {<br />        response.setContentType("text/html");<br />        response.getWriter().println("Hello Portlet");<br />        }<br />}</pre><br /><br />　　每个portlet都要实现Portlet接口，该接口为portlet定义了生命周期方法。由于不想覆盖所有这些方法，我们只对GenericPortlet类进行扩展，它是一个实现了Portlet接口的适配器类。GenericPortlet类提供了所有生命周期方法的默认实现，所以我们只需实现我们所需要的方法。<br /><br />　　我们在 HelloWorld portlet里要做的只是显示“Hello Portlet”，所以我们将覆盖GenericPortlet类的doView()方法，该方法以PortletRequest 和 PortletResponse作为参数。在doView()方法中首先调用response.setContentType()以通知portlet容器该portlet将要生成何种类型的内容－如果不这样做就会导致IllegalStateException异常。一旦设置了内容的类型，就可以从response对象中获得PrintWriter并开始写入。<br /><br />4.        每个portlet应用在/WEB-INF文件夹中都有一个portlet.xml文件，它是portlet应用的部署描述符。按以下内容创建portlet.xml文件：<br /><pre class="overflow">&lt;portlet&gt;<br />  &lt;description&gt;HelloWorldDescription<br />        &lt;/description&gt;<br />    &lt;portlet-name&gt;HelloWorld<br />        &lt;/portlet-name&gt;<br />    &lt;display-name&gt;Hello World<br />        &lt;/display-name&gt;<br /><br />    &lt;portlet-class&gt;com.test.HelloWorld<br />        &lt;/portlet-class&gt;<br />    &lt;expiration-cache&gt;-1<br />        &lt;/expiration-cache&gt;<br />        &lt;supports&gt;<br />          &lt;mime-type&gt;text/html&lt;/mime-type&gt;<br />      &lt;portlet-mode&gt;VIEW<br />          &lt;/portlet-mode&gt;<br />        &lt;/supports&gt;<br />    &lt;supported-locale&gt;en<br />        &lt;/supported-locale&gt;<br /><br />        &lt;portlet-info&gt;<br />          &lt;title&gt;Hello World&lt;/title&gt;<br />          &lt;short-title&gt;Hello World<br />          &lt;/short-title&gt;<br />          &lt;keywords&gt;Hello,pluto&lt;/keywords&gt;<br />      &lt;/portlet-info&gt;<br />&lt;/portlet&gt;</pre><br /><br />　　&lt;portlet-name&gt;元素声明了portlet的名字，&lt;portlet-class&gt;元素指定了portlet的全限定类名，&lt;expiration-cache&gt;元素以秒为单位指定了内容超期的时间。这里面有一点需要注意：你在portlet上的某些动作可能会导致内容刷新，这与缓存时间无关。<br />　　&lt;supports&gt;元素指定对于给定的&lt;mime-type&gt;有哪些模式可供支持。在示例中我们假定HelloWorld只能生成text/html类型的内容，且只有view模式可支持该内容类型。如果要增加对其它内容类型的支持，需要添加新的&lt;support&gt;元素并指定支持该MIME类型的模式有哪些。通常portlet对于text/html类型有VIEW、EDIT和HELP模式可供支持，而对于WML MIME类型则只有VIEW模式。<br />　　还可以用&lt;supported-locale&gt;元素来指定portlet支持哪些本地化。&lt;title&gt;元素用来指定portlet的标题。如果要对标题做国际化处理，可以用元素&lt;resource-bundle&gt;指定资源（比例properties文件）的文件名。在这种情况下，容器将根据用户所在的地区从适当的properties文件中选择标题。<br /><br />5.        每个portlet应用都是一个web应用，因此除了portlet.xml文件之外还需要有web.xml文件。<br /><pre class="overflow">&lt;web-app&gt;<br />  &lt;display-name&gt;Hello World Portlet<br />  &lt;/display-name&gt;<br />  &lt;welcome-file-list<br />    &lt;welcome-file&gt;index.jsp<br />        &lt;/welcome-file&gt;<br />  &lt;/welcome-file-list&gt;<br />&lt;/web-app&gt;</pre><br /><br />6.        接下来将这些文件进行编译并打包为war文件。你可以自己完成这些工作，或者下载带有build.xml 的示例代码（参见“资源”部分）来创建war文件。<br />在Pluto上部署HelloWorld Portlet<br /><br />　　Pluto尚处于开发阶段的早期，因此还没有一套易于使用的管理工具。为了能使用Pluto服务器，需要将编译和源代码两个版本都下载。需要注意的是以下说明是针对Windows平台的，Unix用户通过修改斜杠符号和执行sh shell脚本（不是bat批命令文件）会得到类似的结果。<br /><br />1.        创建一个文件夹，比如C:\PlutoInstallation。<br />2.        从Pluto的网站下载pluto-1.0.1-rc1.zip和pluto-src-1.0.1-rc1.zip。<br />3.        将pluto-1.0.1-rc1.zip解压到C:\PlutoInstallation.文件夹，它应被解压到C:\PlutoInstallation\pluto-1.0.1-rc1文件夹下。<br />4.        执行C:\PlutoInstallation\pluto-1.0.1-rc1\bin\startup.bat启动Pluto，现在可以通过地址http://localhost:8080/pluto/portal访问Pluto服务器。<br />5.        将pluto-src-1.0.1-rc1.zip解压到C:\PlutoInstallation\PlutoSrc文件夹。<br />6.        进入C:\PlutoInstallation\PlutoSrc文件夹，执行maven distribute:all.，编译并下载运行常规管理任务所必需的相关资源文件。现在可以将HelloWorldPortlet.war作为portlet进行安装了。<br />7.        首先将HelloWorldPortlet.war文件拷贝到C:\PlutoInstallation\portlets目录，如果没这个目录就创建它。<br />8.        将C:\PlutoInstallation\plutosrc\build.properties.sample更名为build.properties。<br />9.        编辑build.properties，将maven.tomcat.home指向Pluto编译版的安装位置，在本例中应改为maven.tomcat.home=C:/PlutoInstallation/pluto-1.0.1-rc1。<br />10.        为了安装portlet，进入C:\plutoInstallation\plutosrc\deploy文件夹，执行maven deploy -Ddeploy=c:\PlutoInstallation\portlets\HelloWorldPortlet.war，应能看到“build successful”信息。<br />11.        在C:\PlutoInstallation\pluto-1.0.1-rc1\webapps文件夹下，应该有一个HelloWorldPortlet文件夹。<br />12.        现在进入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\HelloWorld\WEB-INF\ folder文件夹，打开portlet的web.xml文件，你会发现里面自动多了几行，如下所示：<br /><pre class="overflow">&lt;servlet&gt;<br />  &lt;servlet-name&gt;HelloWorld&lt;/servlet-name&gt;<br />     &lt;display-name&gt;HelloWorld Wrapper&lt;/display-name&gt;<br />      &lt;description&gt;Automated generated<br />      Portlet Wrapper&lt;/description&gt;<br />      &lt;servlet-class&gt;org.apache.pluto.core.PortletServlet<br />      &lt;/servlet-class&gt;<br />      &lt;init-param&gt;<br />         &lt;param-name&gt;portlet-class&lt;/param-name&gt;<br />         &lt;param-value&gt;com.test.HelloWorld<br />         &lt;/param-value&gt;<br />      &lt;/init-param&gt;<br />      &lt;init-param&gt;<br />         &lt;param-name&gt;portlet-guid&lt;/param-name&gt;<br />         &lt;param-value&gt;HelloPluto.HelloWorld<br />         &lt;/param-value&gt;<br />      &lt;/init-param&gt;<br />&lt;/servlet&gt;</pre><br />13.        接下来我们将该portlet加到页面里。进入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\data文件夹，可以看到有两个XML文件：pageregistry.xml和portletentityregistry.xml。<br />14.        portletentityregistry.xml包含了portlet的定义，在该文件中加入以下几行：<br /><pre class="overflow"> &lt;application id="5"&gt;<br />   &lt;definition-id&gt;HelloWorld&lt;/definition-id&gt;<br />     &lt;portlet id="1"&gt;<br />       &lt;definition-id&gt;HelloWorld.HelloWorld&lt;/definition-id&gt;<br />     &lt;/portlet&gt;<br />&lt;/application&gt;</pre><br />　　应用的&lt;definition-id&gt;应为web应用所在文件夹的名字，portlet的&lt;definition-id&gt;应与web.xml中生成的portlet-guid相一致。<br />15.        pageregistry.xml定义了页面中包含了哪些portlets，对该文件做如下改动：<br /><pre class="overflow">  &lt;fragment name="p2" type="portlet"&gt;<br />    &lt;property name="portlet" value="5.1"/&gt;<br />&lt;/fragment&gt;</pre><br />16.        执行shutdown命令和startup命令重启Pluto服务器，返回到地址http://localhost:8080/pluto/portal并点击“Test Link”－此时页面中将出现我们的<br /><br /><span style="COLOR: blue">HelloWorld portlet。</span><br /><br />图3的右侧显示了HelloWorld portlet看上去的样子。<br /><br /><img onmouseover="javascript:imgShowTip(this);" style="DISPLAY: inline" onclick="javascript:imgClick(this);" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2005_12_05_021757_PvflGMTbcZ.gif" width="600" onload="javascript:imgLoad(this);" border="0" resized="1" /><br />图3 portlet的屏幕截图<br /><br /><b><span style="FONT-SIZE: 16px">如何创建Portal页面</span></b><br /><br />图4显示了portal容器如何将分离的portlets组装为页面。<br /><br /><img onmouseover="javascript:imgShowTip(this);" style="DISPLAY: inline" onclick="javascript:imgClick(this);" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2005_12_05_021832_mFdIUWtdpN.gif" onload="javascript:imgLoad(this);" border="0" resized="0" /><br />图4 创建Portal页面<br /><br />　　大部分的portal服务器基本上都是部署于应用服务器上的web应用，通过servlet来处理访问portal服务器的请求。查看一下Pluto的安装目录就会发现Pluto不过是一个部署于Tomcat服务器上的一个普通web应用，再看看C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\web.xml会发现所有发往Pluto服务器的请求都被映射到org.apache.pluto.portalImpl.Servlet上。<br /><br />　　在本文开始部分“Portal页面的元素”中，我们提到portal页面由两部分组成。一部分是由页面中的portlets生成的内容，另一部分是由portal服务器生成的内容。<br /><br />　　在Pluto里，只要用户发出请求，就会由servlet进行控制，根据用户所请求的页面来确定需要显示的portlets的列表。一旦生成了列表，servlet就将控制转给这些portlets线程并收集由它们生成的内容。<br /><br />　　对于由portal服务器生成的内容（像portal网站的观感及每个portlet的外观和控制之类）则取决于C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\aggregation文件夹下的JSP文件。RootFragment.jsp是主JSP文件，它决定了整体的观感和对齐方式；它还包含了Heads以定义在生成的页面中的&lt;HEAD&gt;标签里的内容。TabNavigation.jsp用来选择在banner中该显示什么（默认情况下在banner显示列表中也包扩了pluto.png图片）。TabNavigation.jsp用来确定portal网站的导航方案。这意味着只需改动该文件夹下少量的几个JSP文件，就能改变整个portal网站的观感。<br /><br />　　Pluto根据pageregistry.xml中的设置确定页面中有多少行，并用RowFragment.jsp去填充。ColumnFragment.jsp用来填充每个栏目。PortletFragmentHeader.jsp用来填充每个portlet的页头，像标题条及最大化和最小化控制。footer.jsp用来填充JSP的页脚。如果去看一下portal页面的HTML代码就会发现每个portlet窗口无非都是嵌入&lt;TD&gt;标签的内容块。<br /><br /><b><span style="FONT-SIZE: 16px">结束语</span></b><br /><br />　　任何一种新技术要想获得成功都应具备以下条件：首先，它能提升现有技术；其次，它能解决现有技术遇到的普遍问题；再次，它能提供多于一个的抽象层（有人说，每抽象出一层，问题就解决一半）。<br /><br />　　由于portlet与现有的应用服务器架构兼容，这对Portlet API来说是一次发展servlet技术的好机会。你可以从portlet里调用EJB，或者用它启动和参与由应用服务器控制的全局性事务。换句话说，在以商业逻辑为核心的领域里，portlet完全可以做得和servlet一样好。<br /><br />　　Portlets提供了一个抽象层，现在你不必再担心客户端使用了什么样的HTTP方法，也不必自己编写程序去捕获像点击按钮这样的客户端事件。最后但绝不是最次要的一点是，portlets以提供像单次登录、个性化等服务的方式解决了servlets不能解决的大部分问题。<br /><br /><b>资源</b><br />·<a href="http://www.matrix.org.cn/resource/upload/forum/2005_12_05_021921_tLDwmSMZnA.zip" target="_new">本文的示例代码</a><br />·JSR 168的首页:http://www.jcp.org/en/jsr/detail?id=168<br />·Pluto的首页:http://portals.apache.org/pluto/ <br />·onjava.com:<a href="http://onjava.com/" target="_new">onjava.com</a><br />·Matrix-Java开发者社区:<a href="http://www.matrix.org.cn/" target="_new">http://www.matrix.org.cn</a><img src ="http://www.blogjava.net/kingwell/aggbug/48559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kingwell/" target="_blank">KingWell</a> 2006-05-28 09:01 <a href="http://www.blogjava.net/kingwell/articles/48559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单点登录的简单实现</title><link>http://www.blogjava.net/kingwell/articles/46696.html</link><dc:creator>KingWell</dc:creator><author>KingWell</author><pubDate>Wed, 17 May 2006 14:08:00 GMT</pubDate><guid>http://www.blogjava.net/kingwell/articles/46696.html</guid><wfw:comment>http://www.blogjava.net/kingwell/comments/46696.html</wfw:comment><comments>http://www.blogjava.net/kingwell/articles/46696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kingwell/comments/commentRss/46696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kingwell/services/trackbacks/46696.html</trackback:ping><description><![CDATA[
		<p>　　在门户项目中，经常会遇到如何实现单点登录的问题，下面就本人的经验做个总结。欢迎大家进行补充讨论。</p>
		<h3>单点登录的具体实现有很多种选择，包括：</h3>
		<ol>
				<li>采用专门的SSO商业软件： 主要有：Netgrity的Siteminder，已经被CA收购。Novell 公司的iChain。RSA公司的ClearTrust等。 
</li>
				<li>采用门户产品供应商自己的SSO产品，如：BEA的WLES，IBM 的Tivoli Access Manager，Sun 公司的identity Server，Oracle公司的OID等。 
</li>
				<li>这些商业软件一般适用于客户对SSO的需求很高，并且企业内部采用COTS软件如：Domino,SAP,Sieble的系统比较多的情况下采用。并结合身份管理。统一认证等项目采用。采用这些软件一般都要对要集成的系统做些改造，如在要集成的系统上安装AGENT。现在一般只提供常见软件如：Domino,SAP,Sieble，常见应用服务器：weblogic,websphere等的AGENT。要先统一这些系统的认证。一般采用LDAP或数据库。然后才能实现SSO。比较麻烦。 
</li>
				<li>另外，如果不想掏银子，也有OPEN SOURCE的SSO软件可选：主要有：<a href="http://www.josso.org/" target="_blank">http://www.josso.org/</a><a href="https://opensso.dev.java.net/" target="_blank">https://opensso.dev.java.net/</a><a href="http://www.sourceid.org/" target="_blank">http://www.sourceid.org</a> 等。具体怎么样就不清楚了。 </li>
		</ol>
		<p>　　如果项目对SSO的要求比较低，又不想对要被集成的系统做任何改动，可采用下面介绍的方式简单实现：下面我们通过一个例子来说明。假如一个门户项目要对下面的几个系统做SSO。</p>
		<p align="center">
				<img height="351" alt="图一" src="http://dev2dev.bea.com.cn/images/image060228002.gif" width="554" border="0" />
		</p>
		<p>　　用户在这些系统中的用户名，密码各不相同，如：员工号为001的员工在这些系统中的用户名，密码分别如下：</p>
		<table class="tabel-general" cellspacing="0" cellpadding="0" width="100%" align="center">
				<tbody>
						<tr>
								<th class="left">用户</th>
								<th class="center">系统</th>
								<th class="center">用户名</th>
								<th class="right">密码</th>
						</tr>
						<tr>
								<td>001</td>
								<td>Portal系统</td>
								<td>A</td>
								<td class="right">1234</td>
						</tr>
						<tr>
								<td>001</td>
								<td>邮件系统</td>
								<td>B</td>
								<td class="right">2345</td>
						</tr>
						<tr>
								<td>001</td>
								<td>DOMINO系统</td>
								<td>C</td>
								<td class="right">AAAA</td>
						</tr>
						<tr>
								<td>001</td>
								<td>报销系统</td>
								<td>D</td>
								<td class="right">CCCC</td>
						</tr>
						<tr>
								<td>001</td>
								<td>工资系统</td>
								<td>E</td>
								<td class="right">BBBB</td>
						</tr>
				</tbody>
		</table>
		<h4>首先，建立员工在PORTAL系统中的用户名和其他系统中的用户名之间的对应关系 </h4>
		<p>　　首先，要建立员工在PORTAL系统中的用户名和其他系统中的用户名之间的对应关系并保存。可保存在表中或LDAP中或文件系统中。当然要考虑这些系统之间的数据同步问题。比较好的方式是找到用户在这些系统中的都存在的唯一信息（如员工号，MAIL地址，姓名等）。通过唯一信息实时到各个系统中去取认证所需要的信息。就不需要考虑数据同步问题。比较实用。可以建立类似下面的表：密码可采用加密保存。如果是采用BEA的Weblogic Portal,可采用UUP来保存这些信息。</p>
		<pre class="code">	(
	
	user	 varchar2(20),   	/*用户名*/
	app_name varchar2(20),  	/*应用系统*/
	architect varchar2(4),  		/*应用系统的架构BS或CS*/
	app_company varchar2(50),          /*用户所属分公司*/
	app_department varchar2(50),      /*用户所在的部门*/
	app_user varchar2(15),                 /*在该系统中的用户名*/
	app_passwd varchar2(15), 	/*在该系统中的密码*/
	app_cookie varchar2(30),              /*COOKIE名称*/
	form_user varchar2(20),                /*认证页面中FORM的用户名字段*/
	form_passwd varchar2(20),          /*认证页面中FORM的密码字段*/
	app_special  varchar2(20)           /*其他*/
	);
</pre>
		<h4>通过IFRAME或超连接方式集成目标系统，并进行SSO</h4>
		<p>　　通过IFRAME或超连接方式集成目标系统,并在URL中带上用户名和密码。如集成DOMINO可采用如下方式：</p>
		<p>　　&lt;IFRAME src=<a href="http://host1/names.nsf?Login&amp;Username=admin&amp;Password=pass&amp;RedirectTo=/names.nsf" target="_parent">http://host1/names.nsf?Login&amp;Username=admin&amp;Password=pass&amp;RedirectTo=/names.nsf</a><br />width="100%" frameborder="0" align="middle" height="100%" hspace="0" marginheight="0" marginwidth="0" scrolling="yes" style="background-color:#f7f7ff;"&gt;<br />&lt;/IFRAME&gt;</p>
		<p>　　或： <br />Href src=“<a href="http://localhost/names.nsf?Login&amp;Username=admin&amp;Password=password&amp;RedirectTo=/names.nsf" target="_parent">http:// </a><a href="http://host1/names.nsf?Login&amp;Username=admin&amp;Password=password&amp;RedirectTo=/names.nsf" target="_parent">host1</a><a href="http://localhost/names.nsf?Login&amp;Username=admin&amp;Password=password&amp;RedirectTo=/names.nsf" target="_parent">/names.nsf?Login&amp;Username=admin&amp;Password=pass&amp;RedirectTo=/names.nsf</a>” <br />以上采用的是在HTTP中直接传递明码，为提高安全性，可采用HTTPS来传递用户名和密码。另外采用这种方式被集成的系统必须支持FORM方式认证。J2EE应用，DOMINO等都支持FORM认证。</p>
		<p>　　这两种方式如果SSO成功，就自动进入目标系统的界面，如果实现会显示目标系统的登录界面。其效果图如下：</p>
		<p align="center">
				<img height="355" alt="登录界面" src="http://dev2dev.bea.com.cn/images/image060228004.jpg" width="552" />
		</p>
		<p>　　这种方式，必须维护对应关系表，如上面的sso_info。更好的方式是提供界面，让最终用户自己维护这种对应关系，可模仿Compoze portlets for lotus的做法，在用户第一次进入要与之做SSO的系统时，如DOMINO系统，显示一个界面，让用户自己输入他在该系统中的用户名/密码等信息。并保存到表中或LDAP等其他数据源中。以后用户要进入这些系统时，就直接从表中或其他数据源中取用户的用户名/密码等信息，帮助用户做认证。建议采用这种方式。如下图所示。如果用户改变了自己在DOMINO系统中的用户名，密码。从门户系统进入DOMINO系统时，认证会失败，就重新显示类似下面的界面。让用户重新输入他在DOMINO系统中新的用户名，密码并保存。</p>
		<p align="center">
				<img height="354" alt="认证失败" src="http://dev2dev.bea.com.cn/images/image060228006.jpg" width="575" />
		</p>
		<p>　　以上这种实现方式，一般需要浏览器支持COOKIE，所以要注意浏览器的配置，在开发阶段，为方便调试，可设置IE，让它显示COOKIE的名称。如下所示：</p>
		<p align="center">
				<img height="285" alt="浏览器的配置" src="http://dev2dev.bea.com.cn/images/image060228008.gif" width="553" border="0" />
		</p>
		<p>　　采用这种方式，对要集成的系统不需要做任何的改动。如果PORTAL系统中的用户在被集成的系统中的权限都一样，可采用建立一个通用用户的做法。也就是所有在PORTAL系统中的用户都采用这个通用用户进入目标系统。这种方式等于是采用页面集成方式做集成。比较方便使用。另外，有时候需要采用调用API，或配置Adapter等应用集成方式来集成其他系统，一般也是通过定义一个连接专用的用户。在API中或在配置Adapter的时候写死。如采用JAVA API方式集成DOMINO：</p>
		<p>　　<b>lotus.domino.Session dominoSession = NotesFactory.createSession(dominoServer, “admin”, “password”);</b></p>
		<h4>CS结构实现方式</h4>
		<p>　　经常有人问CS结构的应用如何实现SSO，本人的建议是对这种系统不要自己去实现SSO。很麻烦，其实输个用户名，密码没什么大不了的。如果要实现，一是采用商业软件。另外也可以采用以下方式：在PORTAL的PORTLET上建立超连接。并通过APPLET方式启动CS结构的应用系统的登录界面。然后通过如下的方式把用户名/密码传递过去。</p>
		<p>　　<b>-不能做任何改动的客户端</b> - WIN消息（给登录窗口发送用户名，密码等登录所需要的信息）,模拟键盘（java有模拟键盘输入的API）</p>
		<p>　　-<b>可以做改动的客户端</b> - 参数传递，并让登录的EXE文件读取参数进行认证。</p>
		<p>　　因为要让APPLET执行本地的EXE文件，所以必须对IE中的JRE的安全进行设置。</p>
		<p align="center">
				<img height="213" alt="对IE中的JRE的安全进行设置" src="http://dev2dev.bea.com.cn/images/image060228010.gif" width="554" border="0" />
		</p>
		<h4>其他：</h4>
		<p>　　在采用以上方式实现了SSO后，要注意LOGOUT，可采用与LOGIN相同的方式。也可以通过被集成系统的超时设置来实现。</p>
		<h4>单点登录SSO技术资料收集</h4>
		<ul>
				<li>
						<a href="http://www2.ccw.com.cn/05/0536/d/0536d06_2.asp/" target="_blank">统一用户认证和单点登录解决方案: </a> 计算机世界网上的文章,比较全面的介绍统一用户认证和单点登录解决方案 
</li>
				<li>
						<a href="http://www.ccw.com.cn/cio/solution/htm2005/20050829_102WJ.asp" target="_blank">惠普灵动单点登录(SSO)解决方案:</a>  包括C/S结构的系统单点登录解决方案 
</li>
				<li>
						<a href="http://www.ronghai.com/solution/2004-09/627/627_1.html" target="_blank">网站用户单点登录系统解决方案:</a>  通过令牌方式实现网站用户单点登录 
</li>
				<li>
						<a href="http://dev2dev.bea.com.cn/techdoc/200504501.html" target="_blank">WebLogic平台的Web SSO（SAML）解决方案:</a>  在WebLogic 8.1SP4中，提供了用于和Microsoft Windows客户端进行SSO的Single Pass Negotiate Identity Assertion Provider。本文对其做了详细的介绍。 
</li>
				<li>
						<a href="http://blog.beijingnet.com/index.php?blogId=4" target="_blank">http://blog.beijingnet.com/index.php?blogId=4:  </a>收录了一些SSO方面的文章 
</li>
				<li>
						<a href="http://www.ccw.com.cn/cio/research/info/htm2004/20041028_119LC.asp" target="_blank">应用整合中SSO的技术实现:  </a>作者介绍了南京地税进行应用整合SSO的技术实现方案 </li>
		</ul>
		<!--文章其他信息-->
		<div class="dot001">
				<img height="1" alt="" src="http://dev2dev.bea.com.cn/images/_.gif" width="100%" />
		</div>
		<table cellspacing="0" cellpadding="3" width="100%" border="0">
				<tbody>
						<tr valign="bottom">
								<td colspan="2" height="20"> <span class="h2b">作者简介</span></td>
						</tr>
						<tr>
								<td valign="top" align="middle" width="0">
								</td>
								<td>dev2dev ID: <a href="http://dev2dev.bea.com.cn/bbs/profile.jspa?userID=2751">xcjing</a>，BEA 资深技术顾问，加入BEA中国多年，在门户技术、RFID解决方案上有着丰富的经验。</td>
						</tr>
				</tbody>
		</table>
		<div class="dot001">
				<img height="1" alt="" src="http://dev2dev.bea.com.cn/images/_.gif" width="100%" />
		</div>
		<table cellspacing="1" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr valign="center" align="middle">
								<td class="colC1C1C1">
										<img height="1" alt="dot" src="http://dev2dev.bea.com.cn/images/_.gif" width="1" />
								</td>
								<td class="colC1C1C1">
										<img height="1" alt="dot" src="http://dev2dev.bea.com.cn/images/_.gif" width="1" />
								</td>
								<td class="colC1C1C1">
										<img height="1" alt="dot" src="http://dev2dev.bea.com.cn/images/_.gif" width="1" />
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<div class="dot001">
				<img height="1" alt="dot" src="http://dev2dev.bea.com.cn/images/_.gif" width="100%" />
		</div>  <span class="h2b">作者其它文章</span><ul><li><a href="http://dev2dev.bea.com.cn/techdoc/20020849.html">WebLogic 6.1使用技巧</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20020850.html">WebLogic6.0的一些使用经验</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20020851.html">编写线程安全的JSP程序</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20030852.html">JSP学习心得</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20030469.html">WebLogic Server8.1新功能介绍</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/200404158.html">WLI81使用经验</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/200306521.html">Weblogic Server7.0学习笔记</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/200512582.html">WLI81 系统管理功能说明</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/200403556006.html">WLP8.1中的权限管理</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/200403556004.html">WLP81中使用visitorTools</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/200512583.html">BEA WebLogic Portal 8.1 使用技巧</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20060223737.html">企业门户的发展方向</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20060308742.html">WLP8.1 CMS 使用经验</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20060325752.html">WLP81 Portlet之间的通信方式总结</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20060405759.html">客户端调用WLI81 JPD的方法总结 第一部分</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20060405760.html">客户端调用WLI81 JPD的方法总结 第二部分</a></li><li><a href="http://dev2dev.bea.com.cn/techdoc/20060413768.html">RFID-企业软件的下一座金矿</a></li></ul><img src ="http://www.blogjava.net/kingwell/aggbug/46696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kingwell/" target="_blank">KingWell</a> 2006-05-17 22:08 <a href="http://www.blogjava.net/kingwell/articles/46696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单的stateful session bean实例</title><link>http://www.blogjava.net/kingwell/articles/37051.html</link><dc:creator>KingWell</dc:creator><author>KingWell</author><pubDate>Thu, 23 Mar 2006 07:35:00 GMT</pubDate><guid>http://www.blogjava.net/kingwell/articles/37051.html</guid><wfw:comment>http://www.blogjava.net/kingwell/comments/37051.html</wfw:comment><comments>http://www.blogjava.net/kingwell/articles/37051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kingwell/comments/commentRss/37051.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kingwell/services/trackbacks/37051.html</trackback:ping><description><![CDATA[很久之前写给一个朋友看的，在JR发过，试发下，测试下这个blog<br /><br />开发及调试环境为 JBOSS4.0+ECLIPSE3.1，软件下载配置安装我就不多说了，相信大家都会很轻易搞定。<br /><br />开发流程，写一个简单的stateful session bean，进行远程调用,计算出某一特定正整数的Fibonacci值。<br /><br />所创建的project下引入jbossall-client.jar，在JBOSS_HOME/client目录下<br />分别用eclipse写出EJB远程调用的home接口，remote接口和相对应的Bean<br />———1. home接口———<br />package com.terry.ejbsample;<br /><br />import java.rmi.RemoteException;<br />import javax.ejb.CreateException;<br />import javax.ejb.EJBHome;<br /><br />/**<br /> * @author terry<br /> *<br /> */<br />public interface FibonacciHome extends EJBHome<br />{<br />    Fibonacci create() throws RemoteException, CreateException;<br /><br />}<br />———2. remote 接口———<br />package com.terry.ejbsample;<br /><br />import java.rmi.RemoteException;<br />import javax.ejb.EJBObject;<br />/**<br /> * @author terry<br /> *<br /> */<br />public interface Fibonacci extends EJBObject<br />{<br />    public long getFibonacci(int n) throws RemoteException;<br />}<br />———3. FibonacciBean———<br />package com.terry.ejbsample;<br /><br />import javax.ejb.CreateException;<br />import javax.ejb.SessionBean;<br />import javax.ejb.SessionContext;<br />/**<br /> * @author terry<br /> *<br /> */<br />public class FibonacciBean implements SessionBean<br />{<br />    public long getFibonacci(int n)<br />    {<br />        if (n==0) return 1;<br />        else if (n==1) return 1;<br />        else<br />            return getFibonacci(n - 1) + getFibonacci(n - 2);<br />    }<br />    public void ejbCreate() throws CreateException<br />{<br />System.out.println(“Bean created”);<br />}<br />    public void ejbRemove(){}    <br />    public void ejbActivate(){}    <br />    public void ejbPassivate(){}<br />    public void setSessionContext(SessionContext ctx){}<br />}<br /><br />配置相对应的ejb-jar.xml和jboss.xml文件<br />———1. ejb-jar.xml———<br />&lt;?xml version="1.0"?&gt;<br /><br />&lt;ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"<br />    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee<br />                         http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"<br />    version="2.1"&gt;<br />    &lt;enterprise-beans&gt;<br />        &lt;session&gt;<br />            &lt;ejb-name&gt;Fibonacci&lt;/ejb-name&gt;<br />            &lt;home&gt;com.terry.ejbsample.FibonacciHome&lt;/home&gt;<br />            &lt;remote&gt;com.terry.ejbsample.Fibonacci&lt;/remote&gt;<br />            &lt;ejb-class&gt;com.terry.ejbsample.FibonacciBean&lt;/ejb-class&gt;<br />            &lt;session-type&gt;Stateful&lt;/session-type&gt;<br />            &lt;transaction-type&gt;Container&lt;/transaction-type&gt;<br />        &lt;/session&gt;<br />    &lt;/enterprise-beans&gt;<br />&lt;/ejb-jar&gt;<br />———2. jboss.xml———<br />&lt;?xml version="1.0"?&gt;<br /><br />&lt;jboss&gt;<br />    &lt;enterprise-beans&gt;<br />        &lt;session&gt;<br />            &lt;ejb-name&gt;Fibonacci&lt;/ejb-name&gt;<br />            &lt;jndi-name&gt;FibonacciHome&lt;/jndi-name&gt;<br />        &lt;/session&gt;<br />    &lt;/enterprise-beans&gt;<br />&lt;/jboss&gt;<br />在Eclipse中配置所需package的jar包，将class文件以及xml描述文件分别添加进去，注意正确的前缀，xml文件必须在根目录下的META-INF文件夹中。或者你可以在console窗口使用jar命令进行打包（如 jar cf ff.jar *）<br /><br />将刚刚打包的ff.jar放入JBOSS_HOME/server/default/deploy，启动jboss的默认服务器，如果一切顺利的话，你会在console窗口中看到你刚刚所写的FibonacciBean已经被成功部署到jboss中了。<br /><br />写一个简单的测试程序<br />———FibonacciClient.java———<br />package com.terry.ejbsample;<br />import javax.naming.Context;<br />import javax.naming.InitialContext;<br />import javax.rmi.PortableRemoteObject;<br />/**<br /> * @author terry<br /> * <br /> */<br />public class FibonacciClient<br />{<br />    public static void main(String[] args)<br />    {<br />        try<br />        {<br />            java.util.Properties p = new java.util.Properties();<br />            p.put(Context.INITIAL_CONTEXT_FACTORY,<br />                    "org.jnp.interfaces.NamingContextFactory");<br />            p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");<br />            p.put(Context.PROVIDER_URL, "localhost:1099");<br />            <br />            Context jndiContext = new InitialContext(p);<br />            Object ref = jndiContext.lookup("FibonacciHome");<br />            FibonacciHome home = (FibonacciHome) PortableRemoteObject.narrow(<br />                    ref, FibonacciHome.class);<br />            Fibonacci ff = home.create();<br />            long result;<br />            for (int i = 40; i &gt;= 0; i--)<br />            {<br />                result = ff.getFibonacci(i);<br />                System.out.println("Fibonacci of" + i + " is " + result);<br />            }<br />        } catch (java.rmi.RemoteException re)<br />        {<br />            re.printStackTrace();<br />        } catch (Throwable t)<br />        {<br />            t.printStackTrace();<br />        }<br />    }<br />}<br /><br />解析此例<br />J2EE应用说白了其实原理也很简单，J2EE是分布式系统，意味着server与client是通过RMI-IIOP和JNDI进行交互的。简单来说就是提供给client一种可以远程调用server端程序的方法，当然其中的细节会比较复杂，不过这些都是你深入之后才会接触到的东西。<br />本文示例，客户端通过JNDI利用Home接口创建出一个Remote object，再通过调用Remote object 中的方法与FibonacciBean进行交互，处理逻辑。客户端并不是直接与Bean进行交互。<br />程序中的ejb-jar.xml是用来描述EJB属性的，jboss.xml是用来定义ejb-jar.xml中Bean所对应的JNDI信息。<img src ="http://www.blogjava.net/kingwell/aggbug/37051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kingwell/" target="_blank">KingWell</a> 2006-03-23 15:35 <a href="http://www.blogjava.net/kingwell/articles/37051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>