﻿<?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-Junky's IT Notebook-随笔分类-portal</title><link>http://www.blogjava.net/junky/category/22839.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 15 Jun 2007 04:31:35 GMT</lastBuildDate><pubDate>Fri, 15 Jun 2007 04:31:35 GMT</pubDate><ttl>60</ttl><item><title>轻松进行Java Portlets--开发基于JSR 168的开发和部署(转)</title><link>http://www.blogjava.net/junky/archive/2007/06/15/124442.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Fri, 15 Jun 2007 02:39:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/06/15/124442.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/124442.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/06/15/124442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/124442.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/124442.html</trackback:ping><description><![CDATA[作者：<a href="http://dev2dev.bea.com.cn/author/195.html"><u><font color=#0000ff>Prakash Malani</font></u></a><br><br><br>
<p>　　Portlet是生成片段（遵守特定规范的标记语言（如HTML、XML）的片段）的Web组件。片段再合成一个完整的文档。本文介绍了关于Java Portlet的Java Specification Request (JSR) 168规范。它说明了如何使用BEA WebLogic Workshop 8.1 SP2来创建Java Portlet，以及如何将这些portlet部署到BEA WebLogic Portal 8.1 Sp2上。我将介绍一些关键概念，如门户、桌面和portlet，并详细描述多种portlet模式和窗口状态。我还将介绍如何使用Workshop来设计、实现、配置和执行portlet。<br><br><br>　　JSR 168定义了有关Java Portlet的规范。门户是一个Web应用程序和一个portlet的聚合。Portlet容器运行portlet，并管理它们的生命周期。JSR 168定义了portlet与portlet容器之间的契约，它没有定义portlet容器与门户之间的契约。门户的实现留给了门户供应商。<br><br>　　<strong>BEA WebLogic门户</strong><br>　　BEA WebLogic Portal (8.1 SP2)的当前版本支持不同类型的portlet：JSP/HTML portlet、Java PageFlow portlet、Struts portlet和Java portlet，将来还会支持其他portlet，如Web Services for Remote Portlets (WSRP)。我们将着重介绍Java portlet。<br><br>　　WebLogic Portal提供了JSR 168中未描述的门户功能，包括但不限于：书和页面中portlet的组织、多渠道支持和使用skin、skeleton和shell定制。<br><br>　　为了能够继续下去，在进行下一部分之前，请先完成以下内容：<br>　　　&#183;使用WebLogic Domain Configuration Wizard创建一个门户域（如JSR168PortalDomain）。 <br>　　　&#183;使用WebLogic Workshop创建一个使用上面所建立域的门户应用程序（如JSR168PortalApp）。 <br>　　　&#183;在门户应用程序内创建一个门户Web项目（如JSR168PortalWebProject）。 <br>　　　&#183;在门户Web项目中创建一个WebLogic Portal .portal文件（如JSR168.portal）。 <br>　　　&#183;启动服务器实例。 <br><br>　　<strong>创建您的第一个Java Portlet</strong><br>　　下面的步骤描述了如何创建您的第一个JSR 168 portlet。<br>　　&#183;在门户Web项目（如JSR168PortalWebProject）中，使用WebLogic Workshop为portlet（入FirstPortlet）创建一个新文件夹。 <br>　　&#183;在新文件夹内使用Wizard通过创建相应的.portlet文件创建一个新portlet（如Firstportlet）。<br>　　&#183;选择portlet类型为Java Portlet。 <br>　　&#183;指定标题（如First）。 <br>　　&#183;指定定义标签（如first）。<br>　　&#183;指定类名称（如com.malani.examples.portlets.jsr168.FirstPortlet）。 <br>　　&#183;打开门户（如JSR168.portal）。 <br>　　&#183;将portlet（如Firstportlet）拖放到门户中的页面上（如JSR168.portal）。 <br>　　&#183;运行.portal文件进行测试。 <br><br>　　您的第一个JSR 168 portlet已经成功运行了！但向导在背后作了些什么呢？<br>　　&#183;它创建了一个特定于WebLogic Workshop和WebLogic Portal的.portlet文件。.portlet文件构成了与特定于Workshop和WebLogic Portal的.portal文件的契约。 <br>　　&#183;向导创建了一个.java文件（如com.malani.examples.portlets.jsr168.FirstPortlet.java），该文件放置在WEB-INF/src目录中。<br>　　&#183;向导创建了一个WEB-INF/portlet.xml配置文件，并为portlet在文件中插入了一个条目。该portlet的条目看上去如下：<br><br><font color=#666666>&lt;portlet&gt;<br>&lt;description&gt;Description goes here&lt;/description&gt;<br>&lt;portlet-name&gt;first&lt;/portlet-name&gt;<br>&lt;portlet-class&gt;com.malani.examples.portlets.jsr168.FirstPortlet<br>&lt;/portlet-class&gt;<br>&lt;portlet-info&gt;<br>&lt;title&gt;First&lt;/title&gt;<br>&lt;/portlet-info&gt;<br>&lt;/portlet&gt; </font><br><br><strong>　　Java Portlet类</strong><br>　　在该示例中，向导生成的Portlet Java文件扩展了javax.portlet.GenericPortlet类。GenericPortlet类实现了javax.portlet.Portlet接口。图1是一个Unified Modeling Language (UML)类图，描述了这些关系。通过直接实现portlet接口，可以编写一个portlet。然而，GenericPortlet是一个创建portlet的更方便方法。首先，我们看一下portlet生命周期、portlet模式和window状态。 </p>
<p align=center><img height=287 src="http://dev2dev.bea.com.cn/images/wlintegra/image2004102206.gif" width=460><br>图 1</p>
<p>　　<strong>Portlet生命周期</strong><br>　　为了成功地创建portlet，您必须遵照portlet生命周期。javax.portlet.Portlet接口中的方法定义了该生命周期，这些生命周期方法是init()、render()、processAction()和destroy()。当部署portlet的实例时调用init()方法。它用于获得所需的任何昂贵资源（如后台连接），并执行其他一次性活动。当portlet的实例被撤销部署时，使用destroy()方法来释放这些资源。<br><br>　　Portlet规范清晰区别render请求和动作请求。图2描述了portlet请求和响应的一个UML类图。门户页面上的render请求会导致对所页面上的每个portlet上调用render()方法，当用户在特定portlet上调用某个动作（通常是HTML表单提交）时，将会调用该portlet的processAction()方法。这样，用户的动作请求转换为processAction()方法的一次调用和render()方法的多次调用。</p>
<p align=center><img height=231 src="http://dev2dev.bea.com.cn/images/wlintegra/image2004102207.gif" width=459><br>图 2</p>
<p>　　图3是一个序列图，说明了调用processAction()方法的效果，以及为同一页面上的portlet进行后续render()方法的调用。关于更多信息，请参阅关于处理动作的一节。</p>
<p align=center><img height=293 src="http://dev2dev.bea.com.cn/images/wlintegra/image2004102208.gif" width=462><br>图 3</p>
<p>　　有两种重载的init()方法，一个没有参数，另一个有一个javax.portlet.PortletConfig类的实例。注意：关于init(PortletConfig)有一个特殊的caveat。调用super.init(aPortletConfig)失败将导致一个NullPointerException。所包含的源代码示例中的Init portlet说明了这种行为（源代码可以在www.sys-con.com/weblogic/source.cfm中找到）。<br><br><strong>　　Portlet模式</strong><br>　　JSR 168定义了三种Portlet模式：VIEW、EDIT和HELP。一个portlet实例在任何时候都可以恰巧在一种　portlet模式下。其他自定义portlet模式（如配置和源）都是可能的。VIEW模式是默认的模式。Portlet规范建议EDIT模式允许portlet用户定制portlet实例，以及HELP模式显示关于portlet的用法信息。Portlet必须支持VIEW模式，但在portlet中对EDIT模式和HELP模式的支持是可选的。例如，portlet First portlet示例不支持EDIT模式和HELP模式。<br><br><strong>　　window状态</strong><br>　　JSR 168定义了三种Window状态：NORMAL、MINIMIZED和MAXIMIZED。Portlet实例任何时候都可以恰好是一种window状态。其他自定义window状态（如半页）也是可能的。在NORMAL状态下，portlet占了屏幕区的一小部分。屏幕状态与其他portlet共享。在MINIMIZED状态下，portlet的内容被隐藏。在MAXIMIZED状态下，portlet的内容占屏幕区的大部分。其他共享同一页面的portlet在MAXIMIZED状态下被隐藏。例如，portlet First示例支持所有三种window状态。<br><br><strong>　　GenericPortlet类</strong><br>　　您创建的大多数portlet将会扩展javax.portlet.GenericPortlet类，而不是直接实现javax.portlet.Portlet接口。GenericPortlet类实现了render()方法。如果portlet的window状态被最小化，那么render()方法不能做任何事情。如果portlet的window状态不是最小化，那么render()方法设置在portlet.xml文件中指定的标题，并调用doDispatch()方法。根据Portlet模式， doDispatch()方法适当地调用doView()、doEdit()和doHelp()方法。这样，由于GenericPortlet类帮助实现render()方法，并且提供doView()、doEdit()和doHelp()方法来覆盖，因此GenericPortlet类比Portlet接口更便于扩展。 <br><br>　　考虑一下First portlet示例。FirstPortlet类扩展了GenericPortlet，FirstPortlet改写了doView()方法。<br><br><font color=#666666>public void doView(RenderRequest request, RenderResponse response)<br>throws PortletException, IOException<br>{<br>response.setContentType("text/html");<br>response.getWriter().write("&lt;p&gt;Hello World&lt;/p&gt;");<br>}</font><br><br>　　注意：调用setContentType()方法前调用getWriter()方法会导致java.lang.IllegalStateException。<br><br><strong>　　实现Portlet模式</strong><br>　　VIEW模式是强制的，但EDIT和HELP模式是可选的。为了实现EDIT和HELP portlet模式，需要在portlet类中实现适当的doEdit()和doHelp()方法。请参考包含在源代码示例（本文的源代码可以在www.sys-con.com/wldj/sourcec.cfm找到）中的portlet Mode。此外，必须在portlet.xml中如下配置各模式：<br><br><font color=#666666>&lt;supports&gt;<br>&lt;mime-type&gt;text/html&lt;/mime-type&gt;<br>&lt;portlet-mode&gt;edit&lt;/portlet-mode&gt;<br>&lt;portlet-mode&gt;help&lt;/portlet-mode&gt;<br>&lt;/supports&gt; </font><br><br>　　注意：修改portlet.xml配置文件，但不实现portlet类中的相应方法，会导致javax.portlet.PortletException。<br><br><strong>　　实现window状态</strong><br>　　JSR 168没有描述禁用window状态支持的方法。然而，WebLogic Portal实现了对它们的禁用。为了禁用portlet对window状态的支持，需要在weblogic-portlet.xml文件中排除window状态：<br><br><font color=#666666>&lt;portlet&gt;<br>&lt;portlet-name&gt;state&lt;/portlet-name&gt;<br>&lt;supports&gt;<br>&lt;mime-type&gt;text/html&lt;/mime-type&gt;<br>&lt;excluded-window-state&gt;minimized&lt;/excluded-window-state&gt;<br>&lt;excluded-window-state&gt;maximized&lt;/excluded-window-state&gt;<br>&lt;/supports&gt;<br>&lt;/portlet&gt; </font><br><br>　　请参考源代码示例中的portlet State。<br><br>　　<strong>包含JavaServer Pages (JSPs)</strong><br>　　考虑portlet First的doView()方法，该方法获得了Writer的实例，并直接输出HTML片段。由于多种原因（如为了达到Java逻辑与HTML视图表现的分离），往往不推荐输出直接的HTML片段。推荐的方法是使用JSP来显示视图。portlet类中的方法执行业务逻辑、设置render参数以及包含JSP。为了包含一个特定的JSP，应首先获得PortletContext。从PortletContext实例中，通过调用getRequestDispatcher()方法获得一个PortletRequestDispatcher的实例。通过调用include()方法来包含JSP。例如：<br><br><font color=#666666>// execute the necessary logic here...<br>PortletRequestDispatcher aDispatcher =<br>getPortletContext().getRequestDispatcher(<br>"/IncludePortlet/includeView.jsp"<br>);<br>aDispatcher.include(aRequest, aResponse); </font><br><br>　　注意：在执行render()方法时，portlet可能只使用一个PortletRequestDispatcher对象。<br>　　请参考包含在源代码中的portlet Include。JSP页面（如includeView.jsp）不包含根HTML标签（如&lt;html&gt;、&lt;title&gt;和&lt;body&gt;），因为这些标签由门户框架提供。JSP页面只包含显示portlet所必需的HTML片段。<br><br>　　<strong>处理动作</strong><br>　　在一个标准的Web应用程序中，一个HTML表单提交将导致执行一些业务逻辑。业务处理的结果，要么作为属性而被设置在请求或会话中并转发，要么包含到下一个JSP。<br><br>　　在一个JSR 168 portlet中，一个HTML表单的动作URL应该是什么样呢？JSR 168定义了一个JSP标签库，称为portlet taglib。HTML表单的动作URL可以使用actionURL portlet标签生成。例如（请参考favoriteColorEdit.jsp文件）：<br><br><font color=#666666>&lt;form action="&lt;portlet:actionURL/&gt;" method="post"&gt;<br>...<br>&lt;/form&gt; </font><br><br>　　提交该HTML表单将会导致调用portlet的processAction(ActionRequest aRequest, ActionResponse aResponse)方法。像通常一样，可以通过调用request对象的getParameter()方法来获得表单参数。注意：通过提交表单调用动作，但portlet中却没有processAction()方法，将会导致javax.portlet.PortletException。<br><br>　　processAction()方法设置response对象中的值。不要使用ActionRequest或ActionResponse对象的setAttribute()方法。值不会从processAction()传递到render()方法，而且在JSP中是不可用的。相反要使用ActionResponse对象的setRenderParameter()方法。这些render参数将对所有后续render请求可用，这一点与典型的Web应用程序请求属性很不相同。典型的Web application请求属性只对于一个请求可用。另一方面，render请求参数对于许多后续render请求可用。render参数保持可用直到值被动作的重新执行显式地修改或删除。<br><br>　　考虑portlet FavoriteColor。它在VIEW模式显示了一个用户偏好的颜色，但是可以在EDIT模式下更改。在EDIT模式下提交偏好的颜色选择将调用processAction()方法。该方法获得偏好的颜色请求参数，并将其设置为render参数。这样，偏好的的颜色render参数将在所有后续render请求中都可用。<br><br>　　所呈现的参数是怎样显示在JSP上的呢？应使用来自portlet标签库的defineObjects标签来定义portlet对象。该标签使renderRequest、renderResponse和portletConfig portlet对象在页面中可用。参数通过调用renderRequest对象的getParameter()方法来显示。请参考与所包含的源代码示例中的favoriteColorView.jsp。<br><br>　　portlet FavoriteColor也展示了其他概念。第一个是如何在processAction()方法中用编程的方法改变portlet模式。调用ActionResponse对象的setPortletMode()方法来修改portlet模式。第二个概念是如何使用一个HTML链接来修改portlet模式。该链接使用来自portlet标签库的renderURL标签生成。根据希望的portlet模式指定portletMode属性的值。请参考源代码示例中的FavoriteColorPortlet类和favoriteColorView.jsp页面。 <br><br><strong>　　Portlet Preferences</strong><br>　　Portlet Preferences（Portlet首选项）是portlet的基本配置数据。一个preference是一个&#8220;名称和值&#8221;对。名称的类型是一个字符串，而值的类型是字符串或字符串数组。Portlet Preference不适于存储任意数据。portlet容器为portlet preferences提供持久性。在WebLogic Portal中，preference的持久性只在下面两个条件都为真时才起作用： <br>　　&#183;门户运行在桌面中，而不是DOT门户模式。<br>　　&#183;用户已经登录。<br><br>　　<strong>桌面与DOT门户模式</strong><br>　　在WebLogic Workshop中创建.portal文件时，像书、页面和portlet等项都可以被拖放到.portal文件中，.portal文件能够直接从Workshop内运行。然而，某些功能，如preferences的存储，在这种DOT门户模式下运行时是不可用的（DOT门户模式也称为单文件模式（Single File Mode））。 <br><br>　　其他模式称为桌面模式。创建一个门户时使用Portal Administrator。在门户内，一个桌面被创建。像图书、页面和portlet等项被创建，并放置在桌面中。在这种模式下，某些功能，像preferences的存储，是可用的（桌面模式也被称为流模式（Streamed Mode））。<br><br>在继续讨论前，先创建一个桌面：<br>　　启动Portal Administration（譬如，<a href="http://localhost:7001/JSR168PortalAppAdmin/" target=_blank>http://localhost:7001/JSR168PortalAppAdmin/</a>）。一种启动Portal Administration的方法是直接从Workshop中启动。选择Portal菜单，选中Portal Administration菜单项。 <br>　　&#183;登录进Portal Administration。<br>　　&#183;创建一个新门户（譬如，JSR168）。 <br>　　&#183;在门户中，创建一个新桌面（如d1）。 <br>　　&#183;将LoginPortlet添加到桌面的一个页面中。 <br>　　&#183;将ContactPortlet添加到桌面的一个文件中。 <br><br><strong>　　Portlet Preferences示例</strong><br>　　Contact portlet演示了Portlet Preferences。Portlet Preferences可以是静态的或动态的。静态 preferences与portlet一起在portal.xml文件中指定。例如，ContactPortlet具有一个成为contact-preference的 preferences。contact-preference的默认值也被指定：<br><br><font color=#666666>&lt;portlet-preferences&gt;<br>&lt;preference&gt;<br>&lt;name&gt;contact-preference&lt;/name&gt;<br>&lt;value&gt;Email&lt;/value&gt;<br>&lt;/preference&gt;<br>&lt;/portlet-preferences&gt; </font><br><br>　　动态 preferences不在portlet.xml配置文件中预定义。当portlet运行时，这些preferences被存储和读取。在运行期间，一个javax.portlet.PortletPreferences接口的实例包含这些preferences。该实例通过调用PortletRequest对象的getPreferences()方法获得。特定preferences的值通过调用preferences实例上的getValue()方法来获得。 <br><br>　　调用preferences实例的setValue()方法会更新一个preferences值。然而，需要一个额外的步骤来提交这些修改。preferences实例的store()方法被调用来使preferences持久化。preferences只能在processAction()方法中进行修改。如果在processAction()方法中没有调用store()方法，任何对preferences实例的修改都会被丢弃。注意：就如前面提到的，如果用户没有登录或门户处于DOT门户模式，那么调用store()方法将会导致一个运行时异常。<br><br>　　在portlet和servlet之间有很多相似点。然而，它们也存在着重要区别。portlet规范建立在servlet规范之上。portlet容器存在于servlet容器中。就像servlet部署在一个Web应用程序中，portlet也是如此。Servlet和Web应用程序使用portlet.xml文件进行配置。一个servlet具有显式的生命周期：init()、doGet()、doPost()等。类似地，一个portlet也具有显式的生命周期：doView()、doEdit()、processAction()等。servlet和portlet类的方法必须以安全线程的方式编码。<br><br>　　然而，也存在着重要的区别。Servlet被允许进行include、forward和redirect操作；然而portlet只被允许进行include操作。Servlet能够呈现一个完整的页面，但portlet只提交页面片段。portlet具有严格定义的portlet模式和Window状态，这方面不像servlet。Portlet具有更正式的请求，对render请求和动作请求进行处理，它们也具有preferences。portlet并不是servlet！<br><br><strong>　　结束语</strong><br>　　本文通过使用一个简单的向导描述portlet的创建而开始，并说明了portlet的生命周期以及portlet类实现的内部工作方式，描述了portlet.xml配置文件和相应的weblogic-portlet.xml配置文件的结构和语义。对各种概念，如portlet模式和window状态，本文也进行了解释。本文演示了portlet标签库的用法和portlet中的表单处理。最后，我介绍了如何使用portletpreferences。理解了本文所介绍的这些知识和概念，您就可以在创建和部署自己的强大portlet的道路上前进了。<br><br><strong>　　致谢</strong><br>　　感谢Subbu Allamaraju、Max Cooper、Steve Ditlinger、David Lu、Roshni Malani和Alex Toussaint，他们仔细阅读了这篇文章，并提供了有价值的反馈意见。<br><br><strong>　　参考资料</strong><br>　　&#183; 要讨论这篇文章、并提问问题，从这里开始： <a href="http://www.bartssandbox.com/" target=_blank>www.bartssandbox.com</a>。需要免费成员资格。 <br>　　&#183; 下载、阅读JSR 168：<a href="http://www.jcp.org/en/jsr/detail?id=168" target=_blank>www.jcp.org/en/jsr/detail?id=168</a> <br>　　&#183; WebLogic Portal文档的起始点：<a href="http://e-docs.bea.com/wlp/docs81/index.html" target=_blank>e-docs.bea.com/wlp/docs81/index.html</a><br>　　&#183; 建立Workshop Help的Java Portlet部分：<a href="http://e-docs.bea.com/workshop/docs81/doc/en/core/index.html" target=_blank>e-docs.bea.com/workshop/docs81/doc/en/core/index.html</a> <br>　　&#183; 用WebLogic Portal 8.1开发JSR 168 Portlet：<a href="http://dev2dev.bea.com/products/wlportal81/articles/JSR168.jsp%20" target=_blank>dev2dev.bea.com/products/wlportal81/articles/JSR168.jsp </a><br>　　&#183; Web Services for Remote Portlets (WSRP)规范：<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp" target=_blank>www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp</a> <br>　　&#183; 尝试一下WSRP：<a href="http://dev2dev.bea.com/codelibrary/code/wsrp_supportkit.jsp" target=_blank>dev2dev.bea.com/codelibrary/code/wsrp_supportkit.jsp</a> <br>　　&#183; Single File Mode和Streamed Rendering Mode：<a href="http://developers.sun.com/prodtech/portalserver/reference/techart/jsr168/pb_whitepaper.pdf" target=_blank>单击这里</a>！<br>　　&#183; 有关Portlet规范上的文章：<br>- 介绍Portlet规范，第1部分：<br><a href="http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-portlet_p.html" target=_blank>www.javaworld.com/javaworld/jw-08-2003/jw-0801-portlet_p.html</a><br>-介绍Portlet规范，第2部分：<br><a href="http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-portlet2_p.html" target=_blank>www.javaworld.com/javaworld/jw-09-2003/jw-0905-portlet2_p.html</a><br>　　&#183; 对JSR 168白皮书的介绍：单击这里！<br>　　&#183; Java Passion Portlet演讲笔记：<a href="http://www.javapassion.com/j2eeadvanced/Portlet4.pdf" target=_blank>www.javapassion.com/j2eeadvanced/Portlet4.pdf</a> <br><br><strong>　　</strong><strong>源代码</strong><br>　　<a href="http://photos.sys-con.com/story/res/45565/Malani0306.zip" target=_blank>源代码-Zip文件</a> <br>　　英文原文：<a href="http://www.sys-con.com/story/?storyid=45565&amp;DE=1" target=_blank>http://www.sys-con.com/story/?storyid=45565&amp;DE=1</a><br></p>
<!--文章其他信息-->
<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>&nbsp;<span class=h2b>作者简介</span></td>
        </tr>
        <tr>
            <td vAlign=top align=middle width=60><img height=51 alt=icon src="http://dev2dev.bea.com.cn/author/prakash_malani.jpg" width=42><br>Prakash Malani</td>
            <td><a href="http://dev2dev.bea.com/pub/au/25" target=_blank>Prakash Malani</a> 在架构、设计和开发软件方面经验丰富。他在许多应用领域从事过软件开发，比如娱乐、金融、零售、医学、通信和交互式电视。他喜欢实践和研究先进的技术，比如Java 2 Enterprise Edition (J2EE)、Unified Modeling Language (UML)和eXtensible Markup Language (XML)。他还在加利福尼亚州立理工大学波莫那校区等机构讲授最佳实践和设计模式。他在业界的著名出版物上发表过许多文章，比如JavaWorld和WebLogic Developers Journal。当前，他正在帮助组织Los Angeles BEA Users Group (LABEAUG)。</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>
&nbsp;&nbsp;<span class=h2b>作者其它文章</span>
<ul>
    <li><a href="http://dev2dev.bea.com.cn/techdoc/2005031802.html">WebLogic域配置策略</a>
    <li><a href="http://dev2dev.bea.com.cn/bbsdoc/20050518.html">BeanUtils: 威力和代价</a>
    <li><a href="http://dev2dev.bea.com.cn/bbsdoc/20050723.html">配置weblogic 8.1和hibernate 3.0 第一部分</a>
    <li><a href="http://dev2dev.bea.com.cn/bbsdoc/20050722.html">配置WebLogic 8.1和Hibernate 3.0，第二部分</a>
    <li><a href="http://dev2dev.bea.com.cn/bbsdoc/20050632.html">使用面向方面编程(AOP)实现Gang of Four (GoF)设计模式</a>
    <li><a href="http://dev2dev.bea.com.cn/bbsdoc/20050729.html">是否要使用门户代替POWA来开发web应用程序？</a> </li>
</ul>
<img src ="http://www.blogjava.net/junky/aggbug/124442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-06-15 10:39 <a href="http://www.blogjava.net/junky/archive/2007/06/15/124442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>liferay权限开发（一）</title><link>http://www.blogjava.net/junky/archive/2007/06/06/122347.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Wed, 06 Jun 2007 05:50:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/06/06/122347.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/122347.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/06/06/122347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/122347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/122347.html</trackback:ping><description><![CDATA[<p><span>HOWTO</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>：</span><span>liferay</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>权限开发（一）</span></p>
<p><span>权限控制是</span><span>liferay4.0</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>以后增加的新特性。在</span><span>liferay</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中开发权限是一件很容易的事情，基本上都是通过定义</span><span>xml</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>来实现。</span></p>
<p><span>首先，我们来看看给自己的</span><span>portlet</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>加上权限控制，主要要完成以下四步操作（</span><span>DRAC</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>）</span><span>:</span></p>
<p align=left><span>1.</span><span> Define all resources and their permissions.</span></p>
<p><span>先定义所有所需要的权限（包括</span><span>portlet resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>和</span><span>model resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>）</span></p>
<p align=left><span>2. For all the resources defined in step 1, register them into the permission system. This is also known</span></p>
<p align=left><span>simply as &#8220;adding resources.&#8221;</span></p>
<p><span>当定义完权限后，我们需要把权限的定义注册到权限系统中，即把权限相关信息保存到数据库中</span></p>
<p align=left><span>3. Associate the necessary permissions to these resources.</span></p>
<p><span>把所需的</span><span>permission</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>关联到</span><span>resources</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>上</span></p>
<p align=left><span>4. Check permission before returning resources.</span></p>
<p><span>在相应的位置加上权限检验的方法</span></p>
<p>&nbsp;</p>
<p><span>在解析上面四个步骤以前，有两个定义是非常重要的：</span></p>
<p><span><span>1．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>－在</span><span>portal</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>系统中，可以简单的认为</span><span>Resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>是一个个可以操作的实体对象。举个例子：一般</span><span>resources</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>包括</span><span>portlets</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>（如：</span><span>Message Boards</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>，</span><span>Calendar</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>，</span><span> etc</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>），</span><span>java</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>类（如：</span><span>Message Board Topics</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>，</span><span>Calendar Events</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>，</span><span> etc</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>）还有</span><span>flies</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>（如：</span><span>documents</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>，</span><span>images</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>，</span><span>etc</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>）</span></p>
<p><span><span>2．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Permission</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>－一个个可运行的权限动作，都已经在</span><span>resourcez</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中定义了。举个例子：&#8220;查看</span><span>calendar</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>的</span><span>portlet</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>&#8221;这个权限动作已经通过</span><span>resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>在</span><span>liferay</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>的权限系统中定义</span></p>
<p>&nbsp;</p>
<p><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>下面来简单解析一下开发权限的四个步骤：</span></p>
<p align=left><span>一．</span><strong><span>Defining Resources and Actions</span></strong></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>默认的权限定义的</span><span>xml</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>文件放</span><span>portal/portal-ejb/classes/resource-actions</span><span>中</span></p>
<p align=left></p>
<p align=left><span><img alt="" src="http://devilbaby.javaeye.com/upload/picture/pic/2164/bdac2c46-b3c1-4c40-afc8-393cd8750b2c.jpg"></span></p>
<p align=left><span>我们来看看</span><span>calendar</span><span>的权限定义</span></p>
<span Courier New?; mso-font-kerning: 0pt?>
<div>xml 代码</div>
<div>
<div></div>
<ol>
    <li><span><span>&lt;</span><span>resource-action-mapping</span><span>&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>portlet-resource</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>portlet-name</span><span>&gt;</span><span>8</span><span><span>portlet-name</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>supports</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>ADD_EVENT</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>CONFIGURATION</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>supports</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>community-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>community-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>guest-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>guest-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>guest-unsupported</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>ADD_EVENT</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>guest-unsupported</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>portlet-resource</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>model-resource</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>model-name</span><span>&gt;</span><span>com.liferay.portlet.calendar.model.CalEvent</span><span><span>model-name</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>portlet-ref</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>portlet-name</span><span>&gt;</span><span>8</span><span><span>portlet-name</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>portlet-ref</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>supports</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>DELETE</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>PERMISSIONS</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>UPDATE</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>supports</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>community-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>community-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>guest-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>guest-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>guest-unsupported</span><span>&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>UPDATE</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>guest-unsupported</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span><span>model-resource</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span><span>resource-action-mapping</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p align=left>&nbsp;</p>
<p align=left><span>首先，我们的权限定义的</span><span>root Element</span><span>为</span><span Courier New?; mso-font-kerning: 0pt?>&lt;</span><span Courier New?; mso-font-kerning: 0pt?>resource-action-mapping</span><span Courier New?; mso-font-kerning: 0pt?>&gt;</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>，所有的权限定义都必须包含在里面</span></p>
<p align=left><span>接着，我们可以看到</span><span Courier New?; mso-font-kerning: 0pt?>liferay</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>的权限定义分</span><span Courier New?; mso-font-kerning: 0pt?>&lt;</span><span Courier New?; mso-font-kerning: 0pt?>portlet-resource</span><span Courier New?; mso-font-kerning: 0pt?>&gt;</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>和</span><span Courier New?; mso-font-kerning: 0pt?>&lt;</span><span Courier New?; mso-font-kerning: 0pt?>model-resource</span><span Courier New?; mso-font-kerning: 0pt?>&gt;</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>两种，</span><span Courier New?; mso-font-kerning: 0pt?>portlet-resource</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>中定义的，我们可以在这里看到，</span></p>
<p align=left></p>
<p align=left><span><img alt="" src="http://devilbaby.javaeye.com/upload/picture/pic/2165/6897e8d0-59cb-44a9-b94c-17e31f1916f2.jpg"></span></p>
<p align=left><span>主要可以控制</span><span Courier New?; mso-font-kerning: 0pt?>portlet</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>的查看，配置权限，还有就是可以控制按钮一类设置的权限</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>model-resource</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>的权限控制到每条记录上</span></p>
<p align=left></p>
<p align=left><span><img alt="" src="http://devilbaby.javaeye.com/upload/picture/pic/2166/b03dd773-e685-4e13-8294-c2c17e0e3659.jpg"></span></p>
<p align=left><span><img alt="" src="http://devilbaby.javaeye.com/upload/picture/pic/2167/c2d46cf0-cff3-474f-9ac2-f2a5e75aa567.jpg"></span></p>
<p align=left></p>
<span>
<div>xml 代码</div>
</span><span>
<div>
<div></div>
<ol>
    <li><span><span>&lt;</span><span>community-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span><span>community-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p align=left>这里告诉我们当一个<span>community</span><span>拥有这个</span><span>portlet</span><span>的时候所具有的权限。</span></p>
<p align=left>&nbsp; </p>
<div>
<div></div>
<ol>
    <li><span><span>&lt;</span><span>guest-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>VIEW</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span><span>guest-defaults</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p align=left>&nbsp;</p>
<p align=left></p>
<span>当</span><span>guest</span><span>用户可以看到这个</span><span>portlet</span><span>的时候默认具有的权限，这里都为查看。</span>
<p>&nbsp;</p>
<p align=left>&nbsp; </p>
<div>
<div></div>
<ol>
    <li><span><span>&lt;</span><span>guest-unsupported</span><span>&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>action-key</span><span>&gt;</span><span>ADD_EVENT</span><span><span>action-key</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span><span>guest-unsupported</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p align=left>&nbsp;</p>
<p align=left></p>
<span Times Roman?; mso-hansi-font-family: ?Times New Roman??>这里为</span><span>guest</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>用户不提供的权限</span>
<p>&nbsp;</p>
<p align=left>&nbsp;</p>
<p align=left><span>上面的这些设置的权限都可以在运行的时候修改</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>ADD_EVENT</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>这类的定义，都已经在</span><span Courier New?; mso-font-kerning: 0pt?>ActionKeys</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>中有对应的常量定义，在二次开发的时候可以继承这个类来加入自定义的权限内容</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>在定义完权限的</span><span Courier New?; mso-font-kerning: 0pt?>resource</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>后，我们需要在</span><span Courier New?; mso-font-kerning: 0pt?>default.xml</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>中加入对应的</span><span Courier New?; mso-font-kerning: 0pt?>path</span></p>
<p align=left>&nbsp;</p>
<p align=left></p>
<p>&nbsp;</p>
<div>xml 代码</div>
<div>
<div></div>
<ol>
    <li><span><span>&lt;</span><span>resource-action-mapping</span><span>&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>resource</span>&nbsp;<span>file</span><span>=</span><span>"resource-actions/portal.xml"</span>&nbsp;<span>/&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>resource</span>&nbsp;<span>file</span><span>=</span><span>"resource-actions/calendar.xml"</span>&nbsp;<span>/&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>resource</span>&nbsp;<span>file</span><span>=</span><span>"resource-actions/communities.xml"</span>&nbsp;<span>/&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>resource</span>&nbsp;<span>file</span><span>=</span><span>"resource-actions/imagegallery.xml"</span>&nbsp;<span>/&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>resource</span>&nbsp;<span>file</span><span>=</span><span>"resource-actions/wiki.xml"</span>&nbsp;<span>/&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>resource</span>&nbsp;<span>file</span><span>=</span><span>"emsp-resource-actions/default.xml"</span>&nbsp;<span>/&gt;</span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span><span>resource-action-mapping</span><span>&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p align=left>&nbsp;</p>
<p align=left><span>Default.xml</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>的路径在</span><span Courier New?; mso-font-kerning: 0pt?>portal(-ext).properties</span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>中可以配置</span></p>
<p align=left><span>resource.actions.configs=resource-actions/default.xml</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>完成的上述工作后，我们需要在</span><span>liferay</span><span>的权限系统中把这些信息注册到数据库中（待续）</span></p>
</span></span>
<img src ="http://www.blogjava.net/junky/aggbug/122347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-06-06 13:50 <a href="http://www.blogjava.net/junky/archive/2007/06/06/122347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>liferay portlet配置文件介绍</title><link>http://www.blogjava.net/junky/archive/2007/05/31/121151.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 31 May 2007 06:09:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/31/121151.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/121151.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/31/121151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/121151.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/121151.html</trackback:ping><description><![CDATA[<div style="MARGIN-TOP: 5px; MARGIN-LEFT: 15px"><strong>关键字:</strong> &nbsp; liferay 配置文件&nbsp;&nbsp;&nbsp;&nbsp; </div>
<div style="MARGIN-TOP: 10px; MARGIN-LEFT: 15px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <h3>portlet.xml </h3>
            <p><font face=Arial>portlet定义描述文件，它描述portlet的类型，支持Mode, preferenes和role等，遵循JSR168标准实现，以便于移植（需要针对性的做一些小改过）。</font></p>
            <p><font face=Arial>下面是一个简单的定义:</font></p>
            <p><font face=Arial>&nbsp;〈portlet〉<br>&nbsp; 〈portlet-name〉2〈/portlet-name〉<br>&nbsp; 〈display-name〉My Account〈/display-name〉<br>&nbsp; 〈!-- portlet的实现类 --〉<br>&nbsp; 〈portlet-class〉com.liferay.portlet.StrutsPortlet〈/portlet-class〉<br>&nbsp; 〈init-param〉<br>&nbsp;&nbsp; 〈name〉view-action〈/name〉<br>&nbsp;&nbsp; 〈value〉/my_account/view〈/value〉<br>&nbsp; 〈/init-param〉<br>&nbsp; 〈expiration-cache〉0〈/expiration-cache〉<br>&nbsp; 〈supports〉<br>&nbsp;&nbsp; 〈mime-type〉text/html〈/mime-type〉<br>&nbsp; 〈/supports〉<br>&nbsp; 〈resource-bundle〉com.liferay.portlet.StrutsResourceBundle〈/resource-bundle〉<br>&nbsp;〈/portlet〉</font></p>
            <p><font face=Arial>在JSR168标准中，定义了view/edit/help三种模式，<br>liferay对其进行了扩展，增加了config/about/preview/print等模式。</font></p>
            <h3>liferay-portlet.xml</h3>
            <p><font face=Arial>liferay的portlet定义描述文件，是liferay对portlet.xml的扩展描述，允许我们对portlet的呈现、功能和行为进行更深入的定制。<br>它与com.liferay.portal.model.Portlet类对应，</font></p>
            <p><font face=Arial>下面是一个较为详细的liferay-portlet定义：<br>&nbsp;〈portlet〉<br>&nbsp; 〈portlet-name〉19〈/portlet-name〉<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 〈!-- struts路径 --〉<br>&nbsp; 〈struts-path〉message_boards〈/struts-path〉<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 〈!-- 配置路径 --〉<br>&nbsp; 〈configuration-path〉/message_boards/edit_configuration〈/configuration-path〉<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 〈!-- lucene索引类 --〉<br>&nbsp; 〈indexer-class〉com.liferay.portlet.messageboards.util.Indexer〈/indexer-class〉<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 〈!-- url处理类 --〉<br>&nbsp; 〈portlet-url-class〉com.liferay.portlet.messageboards.MBFriendlyPortletURL〈/portlet-url-class〉<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 〈!-- 友好url插件类 --〉<br>&nbsp; 〈friendly-url-plugin-class〉com.liferay.portlet.messageboards.MBFriendlyURLPortletPlugin〈/friendly-url-plugin-class〉&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 〈preferences-unique-per-layout〉false〈/preferences-unique-per-layout〉<br>&nbsp; 〈use-default-template〉false〈/use-default-template〉<br>&nbsp; 〈restore-current-view〉false〈/restore-current-view〉<br>&nbsp; 〈private-request-attributes〉false〈/private-request-attributes〉<br>&nbsp;〈/portlet〉</font></p>
            <h4>portlet类中常用的属性:</h4>
            <p><font face=Arial>// strtus 路径，对portlet的请求应该限制在这个路径下 <br>private String _strutsPath;&nbsp; </font></p>
            <p><font face=Arial>// 配置路径，即action定义<br>private String _configurationPath;</font></p>
            <p><font face=Arial>// portlet实现类<br>private String _portletClass;</font></p>
            <p><font face=Arial>// lucene索引类<br>private String _indexerClass;</font></p>
            <p><font face=Arial>// scheduler类<br>private String _schedulerClass;</font></p>
            <p><font face=Arial>// portletURL处理类<br>private String _portletURLClass;</font></p>
            <p><font face=Arial>// friendURL插件<br>private String _friendlyURLPluginClass;</font></p>
            <p><font face=Arial>// 默认的preferences<br>private String _defaultPreferences;</font></p>
            <p><font face=Arial>// preferences的验证类<br>private String _prefsValidator;</font></p>
            <p><font face=Arial>// 是否实例化，为true时可添加多个portlet到layout上<br>private boolean _instanceable;</font></p>
            <p><font face=Arial>// 是否为系统portlet，<br>private boolean _system;</font></p>
            <p><font face=Arial>// 初始化参数<br>private Map _initParams;</font></p>
            <p><font face=Arial>// portlet支持的模式<br>private Map _portletModes;</font></p>
            <p><font face=Arial>// portlet支持的语言<br>private Set _supportedLocales;</font></p>
            <p><font face=Arial>// PortletInfo<br>private PortletInfo _portletInfo;</font></p>
            <p><font face=Arial>// 是否静态portlet, 静态portlet不能移动.<br>private boolean _staticPortlet;</font></p>
            <p><font face=Arial>// 是否为开始的静态portlet.<br>private boolean _staticPortletStart;</font></p>
            <p><font face=Arial><strong>portlet解析</strong></font></p>
            <p><font face=Arial>&nbsp;com.liferay.portal.service.impl.PortletLocalServiceImpl</font></p>
            <p><font face=Arial>&nbsp;public void initEAR(String[] xmls) {<br>&nbsp; String scpId = PortletServiceImpl.class.getName() + "." + _SHARED_KEY;</font></p>
            <p><font face=Arial>&nbsp; Map portletsPool = (Map)SimpleCachePool.get(scpId);</font></p>
            <p><font face=Arial>&nbsp; if (portletsPool == null) {<br>&nbsp;&nbsp; portletsPool = CollectionFactory.getSyncHashMap();<br>&nbsp;&nbsp; SimpleCachePool.put(scpId, portletsPool);<br>&nbsp; }</font></p>
            <p><font face=Arial>&nbsp; try {<br>&nbsp;&nbsp; List servletURLPatterns = _readWebXML(xmls[4]);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Set portletIds =<br>&nbsp;&nbsp;&nbsp; _readPortletXML(xmls[0], portletsPool, servletURLPatterns);<br>&nbsp;&nbsp; portletIds.addAll(<br>&nbsp;&nbsp;&nbsp; _readPortletXML(xmls[1], portletsPool, servletURLPatterns));</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Set liferayPortletIds =<br>&nbsp;&nbsp;&nbsp; _readLiferayPortletXML(xmls[2], portletsPool);<br>&nbsp;&nbsp; liferayPortletIds.addAll(<br>&nbsp;&nbsp;&nbsp; _readLiferayPortletXML(xmls[3], portletsPool));</font></p>
            <p><font face=Arial>&nbsp;&nbsp; // Check for&nbsp;missing entries in liferay-portlet.xml<br>&nbsp;&nbsp; // 检查在liferay-portlet中丢失的portlet实体...</font></p>
            <p><font face=Arial>&nbsp;&nbsp; // Remove portlets that should not be included<br>&nbsp;&nbsp; // 移去不应该包括的portlet实体...<br>&nbsp; }<br>&nbsp; catch (Exception e) {<br>&nbsp;&nbsp; _log.error(StackTraceUtil.getStackTrace(e));<br>&nbsp; }<br>&nbsp;}</font></p>
            <p><font face=Arial>&nbsp;<strong>// 解析portlet.xml</strong><br>&nbsp;private Set _readPortletXML(<br>&nbsp;&nbsp; String servletContextName, String xml, Map portletsPool,<br>&nbsp;&nbsp; List servletURLPatterns)<br>&nbsp; throws DocumentException, IOException {</font></p>
            <p><font face=Arial>&nbsp; Set portletIds = new HashSet();</font></p>
            <p><font face=Arial>&nbsp; if (xml == null) {<br>&nbsp;&nbsp; return portletIds;<br>&nbsp; }</font></p>
            <p><font face=Arial>&nbsp; SAXReader reader = SAXReaderFactory.getInstance();</font></p>
            <p><font face=Arial>&nbsp; Document doc = reader.read(new StringReader(xml));</font></p>
            <p><font face=Arial>&nbsp; Element root = doc.getRootElement();</font></p>
            <p><font face=Arial>&nbsp; Set userAttributes = new HashSet();</font></p>
            <p><font face=Arial>&nbsp; Iterator&nbsp;itr1 = root.elements("user-attribute").iterator();<br>&nbsp; // 用户属性处理...</font></p>
            <p><font face=Arial>&nbsp; itr1 = root.elements("portlet").iterator();</font></p>
            <p><font face=Arial>&nbsp; while (itr1.hasNext()) {<br>&nbsp;&nbsp; Element portlet = (Element)itr1.next();</font></p>
            <p><font face=Arial>&nbsp;&nbsp; String portletId = portlet.elementText("portlet-name");</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (servletContextName != null) {<br>&nbsp;&nbsp;&nbsp; portletId =<br>&nbsp;&nbsp;&nbsp;&nbsp; portletId + Portlet.WAR_SEPARATor&nbsp;+ servletContextName;<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; portletId = PortalUtil.getJsSafePortletName(portletId);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (_log.isDebugEnabled()) {<br>&nbsp;&nbsp;&nbsp; _log.debug("Reading portlet " + portletId);<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; portletIds.add(portletId);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Portlet portletModel = (Portlet)portletsPool.get(portletId);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (portletModel == null) {<br>&nbsp;&nbsp;&nbsp; portletModel = new Portlet(<br>&nbsp;&nbsp;&nbsp;&nbsp; new PortletPK(portletId, _SHARED_KEY));</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp; portletsPool.put(portletId, portletModel);<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (servletContextName != null) {<br>&nbsp;&nbsp;&nbsp; portletModel.setWARFile(true);<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (servletURLPatterns != null) {<br>&nbsp;&nbsp;&nbsp; portletModel.setServletURLPatterns(servletURLPatterns);<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; portletModel.setPortletClass(portlet.elementText("portlet-class"));</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Iterator&nbsp;itr2 = portlet.elements("init-param").iterator();<br>&nbsp;&nbsp; // 初始化参数处理...</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Element expirationCache = portlet.element("expiration-cache");<br>&nbsp;&nbsp; // cache过期处理...</font></p>
            <p><font face=Arial>&nbsp;&nbsp; itr2 = portlet.elements("supports").iterator();<br>&nbsp;&nbsp; // 支持模式处理...</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Set supportedLocales = portletModel.getSupportedLocales();<br>&nbsp;&nbsp;&nbsp;&nbsp; // 支持语言处理...</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp; // 资源<br>&nbsp;&nbsp; portletModel.setResourceBundle(<br>&nbsp;&nbsp;&nbsp; portlet.elementText("resource-bundle"));</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Element portletInfo = portlet.element("portlet-info");<br>&nbsp;&nbsp;&nbsp;&nbsp; // portlet-info处理...</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Element portletPreferences = portlet.element("portlet-preferences");<br>&nbsp;&nbsp; // preferences处理...</font></p>
            <p><font face=Arial>&nbsp; <br>&nbsp;&nbsp; Set unlikedRoles = portletModel.getUnlinkedRoles();<br>&nbsp;&nbsp; itr2 = portlet.elements("security-role-ref").iterator();<br>&nbsp;&nbsp; // role处理...</font></p>
            <p><font face=Arial>&nbsp;&nbsp; portletModel.getUserAttributes().addAll(userAttributes);<br>&nbsp; }</font></p>
            <p><font face=Arial>&nbsp; return portletIds;<br>&nbsp;}</font></p>
            <p><font face=Arial>&nbsp;<strong>// 解析liferay-portlet.xml</strong><br>&nbsp;private Set _readLiferayPortletXML(<br>&nbsp;&nbsp; String servletContextName, String xml, Map portletsPool)<br>&nbsp; throws DocumentException, IOException {</font></p>
            <p><font face=Arial>&nbsp; Set liferayPortletIds = new HashSet();</font></p>
            <p><font face=Arial>&nbsp; if (xml == null) {<br>&nbsp;&nbsp; return liferayPortletIds;<br>&nbsp; }</font></p>
            <p><font face=Arial>&nbsp; SAXReader reader = SAXReaderFactory.getInstance();</font></p>
            <p><font face=Arial>&nbsp; Document doc = reader.read(new StringReader(xml));</font></p>
            <p><font face=Arial>&nbsp; Element root = doc.getRootElement();</font></p>
            <p><font face=Arial>&nbsp; Map roleMappers = new HashMap();</font></p>
            <p><font face=Arial>&nbsp; Iterator&nbsp;itr1 = root.elements("role-mapper").iterator();<br>&nbsp; // role-mapper处理...</font></p>
            <p><font face=Arial>&nbsp; Map customUserAttributes = new HashMap();</font></p>
            <p><font face=Arial>&nbsp; itr1 = root.elements("custom-user-attribute").iterator();<br>&nbsp; // 定制用户属性处理...</font></p>
            <p><font face=Arial>&nbsp; Map friendlyURLPlugins = _getFriendlyURLPlugins();</font></p>
            <p><font face=Arial>&nbsp; itr1 = root.elements("portlet").iterator();</font></p>
            <p><font face=Arial>&nbsp; while (itr1.hasNext()) {<br>&nbsp;&nbsp; Element portlet = (Element)itr1.next();</font></p>
            <p><font face=Arial>&nbsp;&nbsp; String portletId = portlet.elementText("portlet-name");</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (servletContextName != null) {<br>&nbsp;&nbsp;&nbsp; portletId =<br>&nbsp;&nbsp;&nbsp;&nbsp; portletId + Portlet.WAR_SEPARATor&nbsp;+ servletContextName;<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; portletId = PortalUtil.getJsSafePortletName(portletId);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (_log.isDebugEnabled()) {<br>&nbsp;&nbsp;&nbsp; _log.debug("Reading portlet extension " + portletId);<br>&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp; liferayPortletIds.add(portletId);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; Portlet portletModel = (Portlet)portletsPool.get(portletId);</font></p>
            <p><font face=Arial>&nbsp;&nbsp; if (portletModel != null) {<br>&nbsp;&nbsp;&nbsp; // 设置portlet属性...</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp; // 处理FriendURL插件<br>&nbsp;&nbsp;&nbsp; portletModel.setFriendlyURLPluginClass(GetterUtil.getString(<br>&nbsp;&nbsp;&nbsp;&nbsp; portlet.elementText("friendly-url-plugin-class"),<br>&nbsp;&nbsp;&nbsp;&nbsp; portletModel.getFriendlyURLPluginClass()));</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp; if (Validator.isNull(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; portletModel.getFriendlyURLPluginClass())) {</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp; friendlyURLPlugins.remove(portletId);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp; friendlyURLPlugins.put(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; portletId, portletModel.getFriendlyURLPluginClass());<br>&nbsp;&nbsp;&nbsp; }</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp; // 绑定role.<br>&nbsp;&nbsp;&nbsp; portletModel.getRoleMappers().putAll(roleMappers);<br>&nbsp;&nbsp;&nbsp; portletModel.linkRoles();</font></p>
            <p><font face=Arial>&nbsp;&nbsp;&nbsp; portletModel.getCustomUserAttributes().putAll(<br>&nbsp;&nbsp;&nbsp;&nbsp; customUserAttributes);<br>&nbsp;&nbsp; }<br>&nbsp; }</font></p>
            <p><font face=Arial>&nbsp; return liferayPortletIds;<br>&nbsp;}</font></p>
            <p><font face=Arial>从上面的代码可看出，liferay将portlet的描述定义存储在一个Map中.</font></p>
            <h3>liferay-display.xml</h3>
            <p><font face=Arial>portlet的类别定义文件，下面是一个简单的例子:</font></p>
            <p><font face=Arial>&nbsp;〈category name="category.admin"〉<br>&nbsp; 〈portlet id="9" /〉<br>&nbsp; 〈portlet id="40" /〉<br>&nbsp; 〈portlet id="79" /〉<br>&nbsp; 〈portlet id="80" /〉<br>&nbsp;〈/category〉</font></p>
            <p><font face=Arial>要注意的是，在portlet.xml/liferay-portlet.xml/liferay-display.xml三个文件中的portlet-name, portlet-id必须是一致的。</font></p>
            <h3>liferay-layout-templates.xml</h3>
            <p><font face=Arial>layout模板定义文件.<br></font></p>
            <h3>liferay-look-and-feel.xml<br></h3>
            <p><font face=Arial>主题定义文件.<br></font></p>
            <h3>portlet的web.xml</h3>
            <p><font face=Arial>如果以war的方式发布portlet，那么它的web.xml也要进行一些特定的说明, </font></p>
            <p><font face=Arial>下面是liferay中sample-jsp-portlet示例的web.xml:<br>〈web-app〉<br>&nbsp;〈display-name〉sample-jsp-portlet〈/display-name〉<br>&nbsp;〈context-param〉<br>&nbsp; 〈param-name〉company_id〈/param-name〉<br>&nbsp; 〈param-value〉liferay.com〈/param-value〉<br>&nbsp;〈/context-param〉<br>&nbsp;〈listener〉<br>&nbsp; 〈listener-class〉com.liferay.portal.kernel.servlet.PortletContextListener〈/listener-class〉<br>&nbsp;〈/listener〉<br>&nbsp;〈servlet〉<br>&nbsp; 〈servlet-name〉sample_jsp_portlet〈/servlet-name〉<br>&nbsp; 〈servlet-class〉com.liferay.portal.kernel.servlet.PortletServlet〈/servlet-class〉<br>&nbsp; 〈init-param〉<br>&nbsp;&nbsp; 〈param-name〉portlet-class〈/param-name〉<br>&nbsp;&nbsp; 〈param-value〉com.sample.jsp.portlet.JSPPortlet〈/param-value〉<br>&nbsp; 〈/init-param〉<br>&nbsp; 〈load-on-startup〉0〈/load-on-startup〉<br>&nbsp;〈/servlet〉<br>&nbsp;〈servlet-mapping〉<br>&nbsp; 〈servlet-name〉sample_jsp_portlet〈/servlet-name〉<br>&nbsp; 〈url-pattern〉/sample_jsp_portlet/*〈/url-pattern〉<br>&nbsp;〈/servlet-mapping〉<br>&nbsp;〈taglib〉<br>&nbsp; 〈taglib-uri〉http://java.sun.com/portlet〈/taglib-uri〉<br>&nbsp; 〈taglib-location〉/WEB-INF/tld/liferay-portlet.tld〈/taglib-location〉<br>&nbsp;〈/taglib〉<br>〈/web-app〉<br>上面的listener是必须的，它用于通知liferay进行热部署,<br>portlet-class指定Portlet的实现类，它必须遵循JSR168标准，直接或间接的从javax.portlet.GenericPortlet继承。<br><br>相关文章: <br></font></p>
            <li><a id=rptArticle__ctl1__ctl0_hlnkTitle href="http://blog.cchensoft.com/Articles/ArticleDetails.aspx?id=xqke4w" target=_blank>liferay中的图片处理</a>
            <li><a id=rptArticle__ctl7__ctl0_hlnkTitle href="http://blog.cchensoft.com/Articles/ArticleDetails.aspx?id=a8d5xf" target=_blank>使用liferay中的struts+tiles来开发portlet(一)</a>
            <li><a id=rptArticle__ctl11__ctl0_hlnkTitle href="http://blog.cchensoft.com/Articles/ArticleDetails.aspx?id=2m6vl1" target=_blank>Liferay中外部war方式整合portlet的处理流程</a>
            <li><a id=rptArticle__ctl0__ctl0_hlnkTitle href="http://blog.cchensoft.com/Articles/ArticleDetails.aspx?id=gv82gp" target=_blank>liferay中layout的处理</a> <br></li>
            </td>
        </tr>
    </tbody>
</table>
</div>
<img src ="http://www.blogjava.net/junky/aggbug/121151.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-31 14:09 <a href="http://www.blogjava.net/junky/archive/2007/05/31/121151.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Liferay的配置文件 —— 基于Struts开发Portlet</title><link>http://www.blogjava.net/junky/archive/2007/05/31/121147.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 31 May 2007 06:00:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/31/121147.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/121147.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/31/121147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/121147.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/121147.html</trackback:ping><description><![CDATA[<div class=postText>结合Liferay实例sample-struts-portlet，基于Struts开发Portlet一般具有以下配置文件：<br>
<ul>
    <li>liferay-display.xml
    <li>liferay-portlet.xml
    <li>portlet.xml
    <li>struts-config.xml
    <li>tiles-defs.xml
    <li>web.xml </li>
</ul>
<br>
<hr style="WIDTH: 100%; HEIGHT: 2px">
<span style="FONT-WEIGHT: bold">（1）liferay-display.xml （定义Portal 中Portlet 管理的目录结构）</span><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 配置在Portlet 的显示名称，以及该portlet 在显示列表中所在的目录。值得注意的是该处并没有直接给出在Portlet 显示列表中的显示名字，而是给出了Portlet ID，根据在porlet.xml 中portlet ID与Name 的关联，可得到该Portlet 的显示名字。<br><br><span style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;display&gt;</span><br style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)"><span style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)">&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &lt;category name="category.test"&gt;</span><br style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)"><span style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)">&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet id="sample_struts_portlet" /&gt;</span><br style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)"><span style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/category&gt;</span><br style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)"><span style="COLOR: rgb(51,102,255); BACKGROUND-COLOR: rgb(255,255,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/display&gt;<br><br></span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(255,0,0)">效果：</span>添加porlet 内容时，也就是在点击&#8220;add content&#8221; 时，名叫sample_struts_portlet 的portlet 将在目录中的test 项下显示。<br><br><span style="FONT-WEIGHT: bold">（2）liferay-portlet.xml （定义基于Liferay Portal 下的Portlet 的特有属性）</span><br>&nbsp;&nbsp;&nbsp; 该配置文件定义portlet 属性和角色，该配置文件对基于JSR168的 portlet.xml 的属性进行扩展。<br><br><span style="COLOR: rgb(51,102,255)">&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &lt;liferay-portlet-app&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,0,0)"> &lt;!-- 配置portlet 名，该名应对应于</span></span><span style="COLOR: rgb(0,0,0)">liferay-display.xml 中</span><span style="COLOR: rgb(0,0,0); BACKGROUND-COLOR: rgb(255,255,255)">portlet 的id 属性 --&gt;</span><br><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-name&gt;sample_struts_portlet&lt;/portlet-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,0,0)">&lt;!-- 配置portlet 的实现类，该类响应该portlet 的请求，实现功能&nbsp; --&gt;</span><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-url-class&gt;<br>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; com.liferay.portal.apache.bridges.struts.LiferayStrutsPortletURLImpl<br>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &lt;/portlet-url-class&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &lt;use-default-template&gt;true&lt;/use-default-template&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &lt;restore-current-view&gt;true&lt;/restore-current-view&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &lt;/portlet&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- 配置该portlet 的角色，以及角色的显示名字，角色名role-name 是由portlet.xml 中进行定义 --&gt;</span></span><br><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;administrator&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &lt;role-link&gt;Administrator&lt;/role-link&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &lt;/role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;guest&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-link&gt;Guest&lt;/role-link&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;power-user&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-link&gt;Power User&lt;/role-link&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;user&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-link&gt;User&lt;/role-link&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/role-mapper&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;/liferay-portlet-app&gt;</span><br><br>&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(255,0,0)">效果：</span>该portlet 由<span style="COLOR: rgb(0,0,0)">com.liferay.portal.apache.bridges.struts.LiferayStrutsPortletURLImpl 类的实例进行处理，允许使用模版和实时刷新页面。可配置administrator，guest，power-user，user 四种角色对其拥有不同的权限。</span><br><br><span style="FONT-WEIGHT: bold">（3）portlet.xml （Portlet 的标准属性，该配置文件中的各项属性符合JSR168 标准，并非Liferay专用）</span><br><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="COLOR: rgb(0,0,0)">该配置文件设置Portlet的各个属性，该各项属性在Portlet初始化时得以加载。</span><br><br>&lt;portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;portlet&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-name&gt;sample_struts_portlet&lt;/portlet-name&gt;<br><br style="COLOR: rgb(51,102,255)"></span><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- display-name 即为该Portlet显示的名字，liferay-display.xml 中配置了Portlet&nbsp; id，关联该配置文件可找到其显示的名字，如下&#8220;Sample Struts Portlet" --&gt;</span></span><br><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;display-name&gt;Sample Struts Portlet&lt;/display-name&gt;<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- 由于在开发Portlet 时必须继承Portlet 的基础类，而此处是基于Struts 开发Portlet 时可继承该类&nbsp; --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-class&gt;org.apache.portals.bridges.struts.StrutsPortlet&lt;/portlet-class&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- init-param 标签表示Portlet 的初始化参数 ，由name 标签和 value 标签指明其名字和值的一对数据 --&gt;</span></span><br><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;name&gt;ServletContextProvider&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- 其值为该Portlet 可接收响应的URL或者类，URL 对应的类是哪个由Struts-config.xml 定义--&gt;</span></span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;value&gt;com.liferay.util.apache.bridges.struts.LiferayServletContextProviderWrapper&lt;/value&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;name&gt;EditPage&lt;/name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;value&gt;/portlet_action/sample_struts_portlet/edit&lt;/value&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;name&gt;HelpPage&lt;/name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;value&gt;/portlet_action/sample_struts_portlet/help&lt;/value&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;name&gt;ViewPage&lt;/name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;value&gt;/portlet_action/sample_struts_portlet/view&lt;/value&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br><br><br style="COLOR: rgb(51,102,255)"></span><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;expiration-cache&gt;0&lt;/expiration-cache&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- 定义该Portlet 所支持的功能，体现在每个Portlet 的展现模式 --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;supports&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;mime-type&gt;text/html&lt;/mime-type&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-mode&gt;edit&lt;/portlet-mode&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-mode&gt;help&lt;/portlet-mode&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/supports&gt;<br><br><br style="COLOR: rgb(51,102,255)"></span><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;portlet-info&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;title&gt;Sample Struts Portlet&lt;/title&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;short-title&gt;Sample Struts Portlet&lt;/short-title&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;keywords&gt;Sample Struts Portlet&lt;/keywords&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/portlet-info&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- 指明对该Portlet 可能拥有权限的角色，该角色定义决定了liferay-portlet.xml 所配置的角色名&nbsp; --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;administrator&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;guest&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;power-user&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;role-name&gt;user&lt;/role-name&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/security-role-ref&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;/portlet&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&lt;/portlet-app&gt;</span><br><span style="COLOR: rgb(255,0,0)"><br>效果：</span>定义了Portlet 的基本信息，展现方式，以及对该Portlet 可能分配权限的用户角色。<span style="COLOR: rgb(0,0,0)"><br><br><br><span style="FONT-WEIGHT: bold">（4）struts-config.xml （该配置文件为Struts 的配置文件，并非Liferay 专用）</span><br><span style="COLOR: rgb(51,102,255)">&lt;struts-config&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,0,0)">&lt;!-- Forms Beans --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;form-beans&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;form-bean name="subscribeForm" type="com.sample.struts.struts.form.SubscribeForm" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;form-bean name="unsubscribeForm" type="com.sample.struts.struts.form.UnsubscribeForm" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;form-bean name="uploadForm" type="com.sample.struts.struts.form.UploadForm" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;/form-beans&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,0,0)"> &lt;!-- Action Mappings --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;action-mappings&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp; &lt;!-- Sample Struts --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;action path="/sample_struts_portlet/edit" forward="portlet.sample_struts_portlet.edit" /&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;action path="/sample_struts_portlet/help" forward="portlet.sample_struts_portlet.help" /&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;action path="/sample_struts_portlet/subscribe/action" type="com.sample.struts.struts.action.SubscribeAction" name="subscribeForm" scope="session" validate="true" input="portlet.sample_struts_portlet.subscribe"&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;forward name="/sample_struts_portlet/subscribe_success" path="/portlet_action/sample_struts_portlet/subscribe_success" redirect="true" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/action&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp;</span><span style="COLOR: rgb(255,0,0)"><span style="COLOR: rgb(153,153,153)">&nbsp; &lt;!-- </span><br style="COLOR: rgb(153,153,153)"><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;&#8230;</span><br style="COLOR: rgb(153,153,153)"><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 该处省略的雷同的设置代码 </span><br style="COLOR: rgb(153,153,153)"><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &#8230;&#8230;</span><br style="COLOR: rgb(153,153,153)"><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; --&gt;</span><br><br style="COLOR: rgb(51,102,255)"></span></span><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,0,0)">&lt;!-- Custom Request Processor&nbsp;--&gt;</span></span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;controller processorClass="org.apache.portals.bridges.struts.PortletTilesRequestProcessor" /&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(0,0,0)"><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; &lt;!-- Message Resources --&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;message-resources parameter="content.test.Language" /&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,0,0)"> &lt;!-- Tiles Plugin --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;plug-in className="org.apache.struts.tiles.TilesPlugin" &gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;set-property property="moduleAware" value="true" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;set-property property="definitions-parser-validate" value="true" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;/plug-in&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,0,0)">&lt;!-- Validator&nbsp;Plugin --&gt;</span></span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;plug-in className="org.apache.struts.validator.ValidatorPlugIn"&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;/plug-in&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&lt;/struts-config&gt;</span><br><span style="COLOR: rgb(255,0,0)">效果：</span>此处可与其它基于Struts 应用开发同样配置，与Liferay 相互独立。<br><br><br><span style="FONT-WEIGHT: bold">（5）tiles-defs.xml （该配置文件是利用Tile 进行页面的布局管理，并非Liferay 专用）</span><br><span style="COLOR: rgb(51,102,255)"><br>&lt;tiles-definitions&gt;</span><br style="COLOR: rgb(51,102,255)"><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp; &lt;!-- 关于页面的布局定义，表示当请求的Url为</span></span><span style="COLOR: rgb(0,0,0)"> portlet.sample_struts_portlet 则以路径path参数指定的 /html/portlet/sample_struts_portlet/template.jsp 页面进行响应--&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;definition name="portlet.sample_struts_portlet" path="/html/portlet/sample_struts_portlet/template.jsp" /&gt;</span><br style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(0,0,0)">&lt;!-- 关于页面的布局定义，表示名为</span></span><span style="COLOR: rgb(0,0,0)"> portlet.sample_struts_portlet.edit Url 的页面嵌套页面 /portlet/sample_struts_portlet/edit.jsp --&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;definition name="portlet.sample_struts_portlet.edit" extends="portlet.sample_struts_portlet"&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;put name="portlet_content" value="/portlet/sample_struts_portlet/edit.jsp" /&gt;</span><br style="COLOR: rgb(51,102,255)"><span style="COLOR: rgb(51,102,255)">&nbsp;&nbsp;&nbsp; &lt;/definition&gt;<br>&nbsp;&nbsp;&nbsp; <br><span style="COLOR: rgb(153,153,153)">&nbsp;&nbsp;&nbsp; &lt;!-- <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#8230;&#8230;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 该处省略的雷同的设置代码 <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &#8230;&#8230;<br>&nbsp;&nbsp;&nbsp; &nbsp; --&gt;</span><br>&nbsp;&nbsp;&nbsp; <br></span><span style="COLOR: rgb(51,102,255)">&lt;tiles-definitions&gt;</span><br>&nbsp;&nbsp; <br><span style="COLOR: rgb(255,0,0)">效果：</span>此处可与其它基于Tiles 应用开发同样配置，与Liferay 相互独立。<br><br><br><span style="FONT-WEIGHT: bold">（6）web.xml （该配置文件为Tomcat 的应用配置文件，并非Liferay 专用）</span><br style="FONT-WEIGHT: bold"><span style="COLOR: rgb(51,102,255)">&lt;web-app&gt;<br>&nbsp;&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp; &lt;!-- <span style="COLOR: rgb(255,0,0)">注意：</span>此处的display-name与portlet.xml 中的display-name 含义不同，此处仅标识在Tomcat 下的应用编写此不得与其它Portlet 和发布的其他应用标识重名 --&gt;</span><br>&nbsp;&nbsp;&nbsp; &lt;display-name&gt;sample-struts-portlet&lt;/display-name&gt;<br><br>&nbsp;&nbsp;&nbsp; &lt;context-param&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-name&gt;company_id&lt;/param-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-value&gt;liferay.com&lt;/param-value&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/context-param&gt;<br><br>&nbsp;&nbsp;&nbsp; &lt;listener&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;listener-class&gt;com.liferay.portal.kernel.servlet.PortletContextListener&lt;/listener-class&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/listener&gt;<br><br>&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;sample_struts_portlet&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;com.liferay.portal.kernel.servlet.PortletServlet&lt;/servlet-class&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-name&gt;portlet-class&lt;/param-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-value&gt;org.apache.portals.bridges.struts.StrutsPortlet&lt;/param-value&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;<br>&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;PortletActionServlet&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;com.liferay.util.apache.bridges.struts.LiferayPortletServlet&lt;/servlet-class&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-name&gt;config&lt;/param-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/struts-config.xml&lt;/param-value&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;<br>&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;TestSessionServlet&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;com.sample.struts.servlet.TestSessionServlet&lt;/servlet-class&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;<br><br>&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;sample_struts_portlet&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/sample_struts_portlet/*&lt;/url-pattern&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;<br>&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;PortletActionServlet&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/portlet_action/*&lt;/url-pattern&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;<br>&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;TestSessionServlet&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/test_session/*&lt;/url-pattern&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;<br><br>&nbsp;&nbsp;&nbsp; &lt;taglib&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-uri&gt;http://java.sun.com/portlet&lt;/taglib-uri&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-location&gt;/WEB-INF/tld/liferay-portlet.tld&lt;/taglib-location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/taglib&gt;<br>&nbsp;&nbsp;&nbsp; &lt;taglib&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-uri&gt;http://struts.apache.org/tags-bean&lt;/taglib-uri&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-location&gt;/WEB-INF/tld/struts-bean.tld&lt;/taglib-location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/taglib&gt;<br>&nbsp;&nbsp;&nbsp; &lt;taglib&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-uri&gt;http://portals.apache.org/bridges/struts/tags-portlet-html&lt;/taglib-uri&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-location&gt;/WEB-INF/tld/struts-portlet-html.tld&lt;/taglib-location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/taglib&gt;<br>&nbsp;&nbsp;&nbsp; &lt;taglib&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-uri&gt;http://struts.apache.org/tags-logic&lt;/taglib-uri&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-location&gt;/WEB-INF/tld/struts-logic.tld&lt;/taglib-location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/taglib&gt;<br>&nbsp;&nbsp;&nbsp; &lt;taglib&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-uri&gt;http://struts.apache.org/tags-nested&lt;/taglib-uri&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-location&gt;/WEB-INF/tld/struts-nested.tld&lt;/taglib-location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/taglib&gt;<br>&nbsp;&nbsp;&nbsp; &lt;taglib&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-uri&gt;http://struts.apache.org/tags-tiles&lt;/taglib-uri&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;taglib-location&gt;/WEB-INF/tld/struts-tiles.tld&lt;/taglib-location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/taglib&gt;<br>&lt;/web-app&gt;<br><br></span><span style="COLOR: rgb(255,0,0)">效果：</span>此处可与其它基于Tomcat 应用开发同样配置，但与Liferay 不完全独立。</span><br></div>
<img src ="http://www.blogjava.net/junky/aggbug/121147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-31 14:00 <a href="http://www.blogjava.net/junky/archive/2007/05/31/121147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Liferay的授权与内容管理(转)</title><link>http://www.blogjava.net/junky/archive/2007/05/31/121146.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 31 May 2007 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/31/121146.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/121146.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/31/121146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/121146.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/121146.html</trackback:ping><description><![CDATA[<p><span>Liferay</span><span>的授权与内容管理 </span></p>
<p>&nbsp;</p>
<p><span>本节主要内容是<span>Liferay</span>的授权操作以及内容管理，在介绍授权早作的同时将结合上一篇的内容，探讨程序背后的执行流程，也会凸现出在进行自己的<span>portlet</span>开发时所要注意的权限相关代码，为<span>portlet</span>的开发打下基础。</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;liferay-portal-4.1.2</span><span>的权限管理主要有<span>2</span>部分构成：<span> </span></span></p>
<p><span><span>1．</span></span><span>user</span><span>的部门归属</span></p>
<p><span><span>2．</span></span><span>对单个<span>portlet</span>的授权</span></p>
<p>&nbsp;</p>
<p><span>超级用户登陆系统后，将进入超级用户的管理界面，管理界面总共有<span>Guest</span>、<span>Private</span>、<span>CMS</span>、<span>Support </span>四层组成，即在<span>Myplace</span>中的<span>4</span>种视图<span>, </span>现对其进行介绍<span>.</span></span></p>
<p><strong><span>Guest</span></strong><strong><span>视图：</span></strong><span>主要管理普通用户的所访问的主页内容，在此视图中可以管理展现在主页上的各个<span>portlet</span>，管理<span>portlet</span>中展现的内容以及<span>portlet</span>的展现形式以及方位。<span>Portlet</span>的内容管理放在稍后的视图中详细讲解，<span>portlet</span>的方位以及显示形式后可以通过页面上直接的拖放进行设置。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>默认情况下，我们所列的<span>portlet</span>就是匿名用户所看到的门户，在每个<span>portlet</span>的设置中，我们还看到了权限的设置，可以将这个<span>portlet</span>的配置，查看等权限（每个<span>portlet</span>的权限不相同，每个都有配置、查看权限，但是有个复杂的<span>portlet</span>如用户管理的就有更多的如添加用户、删除用户等权限）授予用户，这里权限的授予分<span>6</span>级，直接授予用户，授予组织、授予地点、授予用户群、授予社群和授予客人（用户群和社群是自定义的）。<span>Liferay</span>的用户机制为公司—地点—组织—个人，所以授予某一高级的组，下挂的用户将都会自动获得权限。在我的应用中，我将<span>WIKI</span>加入了门户首页，同时将察看与删除授予匿名用户，所以，首页就拥有了一个大家参与修改的区域<span>WIKI</span>了！</span></p>
<p><strong><span>Private </span></strong><strong><span>视图</span></strong><span>：这个是超级用户的私人界面，这里特别分析了几个简单<span>portlet</span>的权限管理的实现。</span></p>
<p><strong><span>HelloWorldPortlet</span></strong><strong><span>。</span></strong><span>位置</span><span>Test</span><span>－<span>&gt;helloworld </span>这个<span>portlet</span>是最简单的一个展示，而且仅仅只有<span>view</span>的功能，所以这个权限管理就是能否在用户的视图中显示就行了，代码中的权限代码无，只是由<span>layout</span>调用<span>HelloWorldPortlet</span>。注：这里是通过设置直接调用<span>HelloWorldPortlet</span>，没有经过<span>Struts</span>框架，所以代码直接继承<span>GenericPortlet</span>，不能由路径访问。</span></p>
<p><strong><span>Announcements</span></strong><strong><span>。</span></strong><span>位置，这个<span>portlet</span>中访问路径由<span>struts</span>配置文件指定，这个<span>portlet</span>代码<span>ViewAction</span>继承<span>PortletAction</span>，<span>PortletAction</span>继承的是<span>Struts Action.</span>在<span>portlet.xml</span>中，</span></p>
<p><span>&lt;name&gt;view-action&lt;/name&gt;</span></p>
<p><span>&lt;value&gt;/wiki/view&lt;/value&gt;</span></p>
<p><span>指定了这个<span>portlet</span>的<span>view</span>所调用的路径，<span>portal</span>容器会根据<span>struts</span>的配置调用指定的<span>Action</span>。在进行<span>action</span>调用时，很显然通过了<span>Liferay</span>扩展的</span><span>PortalRequestProcessor</span><span>（上一篇提到），也就进行了权限检查。配置</span><span>Announcements</span><span>的路径在<span>liferay</span>－<span>portlet.xml</span>中配置，为<span>/announcements/edit_configuration</span>，同样这也是一个<span>struts</span>路径，她的权限管理也同<span>view</span>一样，在</span><span>PortalRequestProcessor</span><span>中完成。</span></p>
<p><strong><span>IFramePortlet</span></strong><strong><span>。</span></strong><span>这个<span>portlet</span>也是一个简单标签的使用例子。在这个<span>portlet</span>中，与<strong><span>HelloWorldPortlet</span></strong>相同，也没有<span>Struts</span>的路径配置，而是直接在<span>portlet.xml</span>中定义了接受请求的<span>Action</span>，所继承的<span>StrutsPortlet</span>由于不是由<span>struts Action</span>而是<span>GenericPortlet</span>扩展而来，所以在访问的时候没有通过</span><span>PortalRequestProcessor</span><span>，所以其内部明确调用了<span>liferay</span>的权限管理代码：</span></p>
<p align=left><span>PermissionChecker checker =</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>PermissionThreadLocal.<em>getPermissionChecker</em>();</span></p>
<p>&nbsp;</p>
<p><span>由上面我们所分析的几个简单的<span>portlet</span>来看，以后在进行<span>portlet</span>开发时有<span>2</span>种选择，当逻辑比较少时，我们可以象<strong><span>IFramePortlet</span></strong>一样，通过对<span>StrutsPortlet</span>的继承完成。当业务逻辑比较复杂时（多个路径），采用<span>Struts</span>进行路径配置时，最好同<strong><span>Announcements</span></strong>一样，通过继承<span>PortletAction</span>来将自身开发的<span>portlet</span>纳入<span>liferay</span>的权限管理框架中。</span></p>
<p>&nbsp;</p>
<p><strong><span>CMS</span></strong><strong><span>视图：</span></strong><span>明显，这个层进行文档管理，用过<span>Guest</span>视图就可以知道门户的所有的新闻文章都在<span>journal</span>中进行管理，对它的使用网上有很多很有用的文章，多用几次也就熟悉了，强大的文本、图像编辑功能可以就近使用而不再用自己编码，肯定也是很愉快的了：）</span></p>
<p>&nbsp;</p>
<p><strong><span>Support</span></strong><strong><span>视图：</span></strong><span>这个视图也是其他用户（非管理员用户）登陆后的定制页面，由管理员进行定制，主要操作和上面一致。</span></p>
<img src ="http://www.blogjava.net/junky/aggbug/121146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-31 13:55 <a href="http://www.blogjava.net/junky/archive/2007/05/31/121146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Liferay 安全管理(转)</title><link>http://www.blogjava.net/junky/archive/2007/05/31/121139.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Thu, 31 May 2007 05:45:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/31/121139.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/121139.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/31/121139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/121139.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/121139.html</trackback:ping><description><![CDATA[<p><span>企业应用整合成为了越来越多的企、事业单位的当务之急，我所处环境也不可避免的遇到这个棘手的问题，各种技术的交集使得<span>portal</span>技术有了大显身手之处。可惜<span>IBM</span>、<span>BEA</span>的高额费用让我们望而却步，自然，开源的<span>portal</span>成为了首选，<span>Liferay</span>是开源社区里一个非常活跃的项目：）而且重要的是其技术架构如图<span>1</span>，也和我们现在的技术路线相近，所以我们决定采用<span>Liferay（版本：liferay-portal-src-4.1.2）</span>作为基础来进行应用开发和系统整合。</span></p>
<p align=center></p>
<p align=center><span></span><span><strong>图1 Liferay技术架构</strong><br><img height=581 alt="" src="http://blog.ccidnet.com/attachment/Mon_0611/10_22729_ca4dfd74ac09ce2.gif" width=450 border=0><br>&nbsp;</span>&nbsp;</p>
<p><span>要用好这个基础平台，必须要对她的自身实现原理有个比较清晰的认识，以下文章为我在研究<span>Liferay</span>原理时所做的一些笔记，现整理和分享（由于笔记带有强烈的个人思想，有错误再所难免，希望能对进一步的分析做为铺垫，更欢迎批评指正）。</span></p>
<p>&nbsp;</p>
<p><strong><span>Liferay Portal</span></strong></p>
<p><strong><span>Liferay </span></strong><strong><span>的<span>JAAS</span>权限管理</span></strong></p>
<p><strong><span>Liferay</span></strong><strong><span>的业务逻辑管理</span></strong></p>
<p><strong><span>Liferay</span></strong><strong><span>二次开发</span></strong></p>
<p><strong><span>Liferay WSRP</span></strong></p>
<p>&nbsp;</p>
<p><span>Liferay</span><span>的权限管理实现了一个典型的</span><span>JAAS</span><span>管理策略，所以在分析其本身前，在此首先介绍<span>JAAS</span>的验证原理和<span>Tomcat</span>上如何开发标准<span>JAAS</span>应用。</span></p>
<p align=left>&nbsp;<strong><span>JAAS</span></strong><strong><span>验证原理</span></strong></p>
<p align=left><span>JAAS</span><span>的核心类和接口可以被分为三种类型，大多数都在</span><span>javax.security.auth</span><span>包中。在</span><span>J2SE 1.4</span><span>中，还有一些接口的实现类在</span><span>com.sun.security.auth</span><span>包中，如下所示：</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>普通类</span><span> Subject</span><span>，</span><span>Principal</span><span>，</span><span>Credential(</span><span>凭证</span><span>)</span></p>
<p align=left><span>　</span><span>Subject</span><span>类代表了一个验证实体，它可以是用户、管理员、</span><span>Web</span><span>服务，设备或者其他的过程。该类包含了三中类型的安全信息：</span></p>
<p align=left><span>1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>身份（</span><span>Identities</span><span>）：由一个或多个</span><span>Principal</span><span>对象表示</span></p>
<p align=left><span>2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>公共凭证（</span><span>Public credentials</span><span>）：例如名称或公共密钥</span></p>
<p align=left><span>3)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>私有凭证（</span><span>Private credentials</span><span>）：例如口令或私有密钥</span></p>
<p align=left><span>　　</span><span>Principal</span><span>对象代表了</span><span>Subject</span><span>对象的身份。它们实现了</span><span>java.security.Principal</span><span>和</span><span>java.io.Serializable</span><span>接口。在</span><span>Principal</span><span>类中，最重要的方法是</span><span>getName</span><span>（）。该方法返回一个身份名称。在</span><span>Subject</span><span>对象中包含了多个</span><span>Principal</span><span>对象，因此它可以拥有多个名称。由于登录名称、身份证号和</span><span>Email</span><span>地址都可以作为用户的身份标识，可见拥有多个身份名称的情况在实际应用中是非常普遍的情况。</span></p>
<p align=left><span>在上面提到的凭证并不是一个特定的类或借口，它可以是任何对象。凭证中可以包含任何特定安全系统需要的验证信息，例如标签（</span><span>ticket</span><span>），密钥或口令。</span><span>Subject</span><span>对象中维护着一组特定的私有和公有的凭证，这些凭证可以通过</span><span>Subject </span><span>方法</span><span>getPrivateCredentials</span><span>（）和</span><span>getPublicCredentials</span><span>（）获得。这些方法通常在应用程序层中的安全子系统被调用。</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>验证</span><span> LoginContext</span><span>，</span><span>LoginModule</span><span>，</span><span>CallBackHandler</span><span>，</span><span>Callback</span></p>
<p align=left><span>验证：</span><span>LoginContext</span></p>
<p align=left><span>　　在应用程序层中，你可以使用</span><span>LoginContext</span><span>对象来验证</span><span>Subject</span><span>对象。</span><span>LoginContext</span><span>对象同时体现了</span><span>JAAS</span><span>的动态可插入性（</span><span>Dynamic Pluggability</span><span>），因为当你创建一个</span><span>LoginContext</span><span>的实例时，你需要指定一个配置。</span><span>LoginContext</span><span>通常从一个文本文件中加载配置信息，这些配置信息告诉</span><span>LoginContext</span><span>对象在登录时使用哪一个</span><span>LoginModule</span><span>对象。</span></p>
<p align=left><span>　　下面列出了在</span><span>LoginContext</span><span>中经常使用的三个方法：</span><span> </span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login () </span><span>进行登录操作。该方法激活了配置中制定的所有</span><span>LoginModule</span><span>对</span><span> </span><span>象。如果成功，它将创建一个经过了验证的</span><span>Subject</span><span>对象；否则抛出</span><span>LoginException</span><span>异常。</span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getSubject () </span><span>返回经过验证的</span><span>Subject</span><span>对象</span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logout () </span><span>注销</span><span>Subject</span><span>对象，删除与之相关的</span><span>Principal</span><span>对象和凭证</span></p>
<p align=left><span>　　验证：</span><span>LoginModule</span></p>
<p align=left><span>　　</span><span>LoginModule</span><span>是调用特定验证机制的接口。</span><span>J2EE 1.4</span><span>中包含了下面几种</span><span>LoginModule</span><span>的实现类：</span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JndiLoginModule </span><span>用于验证在</span><span>JNDI</span><span>中配置的目录服务</span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Krb5LoginModule </span><span>使用</span><span>Kerberos</span><span>协议进行验证</span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NTLoginModul </span><span>使用当前用户在</span><span>NT</span><span>中的用户信息进行验证</span></p>
<p align=left><span>&amp; #61550;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnixLoginModule </span><span>使用当前用户在</span><span>Unix</span><span>中的用户信息进行验证</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>　　同上面这些模块绑定在一起的还有对应的</span><span>Principal</span><span>接口的实现类，例如</span><span>NTDomainPrincipal</span><span>和</span><span>UnixPrincipal</span><span>。这些类在</span><span>com.sun.security.auth</span><span>包中。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>　　</span><span>LoginModule</span><span>接口中包含了五个方法：</span></p>
<p align=left><span>1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; initialize () </span><span>当创建一</span><span>LoginModule</span><span>实例时会被构造函数调用</span></p>
<p align=left><span>2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login () </span><span>进行验证</span><span>,</span><span>通常会按照登录条件生成若干个</span><span>Principal</span><span>对象</span></p>
<p align=left><span>3)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commit () </span><span>进行</span><span>Principal</span><span>对象检验，按照预定义</span><span>Principal</span><span>条件检验</span><span>Login</span><span>生成的</span><span>Principal</span><span>对象，所有需要的条件均符合后，把若干个生成的</span><span>Principal</span><span>对象付给</span><span>Subject</span><span>对象，</span><span>JAAS</span><span>架构负责回传给</span><span>LoginContext.</span></p>
<p align=left><span>4)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; abort () </span><span>当任何一个</span><span>LoginModule</span><span>对象验证失败时都会调用该方法。任何已经和</span><span>Subject</span><span>对象绑定的</span><span>Principal</span><span>对象都会被解除绑定。</span></p>
<p align=left><span>5)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logout () </span><span>删除与</span><span>Subject</span><span>对象关联的</span><span>Principal</span><span>对象和凭证，消除</span><span>Subject,Principal</span><span>等认证对象。</span></p>
<p align=left><span>　验证：</span><span>CallbackHandler</span><span>和</span><span>Callback</span></p>
<p align=left><span>　　</span><span>CallbackHandler</span><span>和</span><span>Callback</span><span>对象可以使</span><span>LoginModule</span><span>对象从系统和用户那里收集必要的验证信息，同时独立于实际的收集信息时发生的交互过程。</span></p>
<p align=left><span>　　</span></p>
<p align=left><span>　　</span><span>JAAS</span><span>在</span><span>javax.sevurity.auth.callback</span><span>包中包含了七个</span><span>Callback</span><span>的实现类和两个</span><span>CallbackHandler</span><span>的实现类：</span><span>ChoiceCallback</span><span>、</span><span>ConfirmationCallback</span><span>、</span><span>LogcaleCallback</span><span>、</span><span>NameCallback</span><span>、</span><span>PasswordCallback</span><span>、</span><span>TextInputCallback</span><span>、</span><span>TextOutputCallback</span><span>、</span><span>DialogCallbackHandler</span><span>和</span><span>TextCallBackHandler</span><span>。</span><span>Callback</span><span>接口只会在客户端会被使用到。我将在后面介绍如何编写你自己的</span><span>CallbackHandler</span><span>类。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>授权</span><span> Policy</span><span>，</span><span>AuthPermission</span><span>，</span><span>PrivateCredentialPermission</span></p>
<p><span>要了解<span>Liferay</span>（<span>tomcat</span>版本）的权限管理，必须首先了解<span>JAAS</span>在<span>tomcat</span>上的应用。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><span>u<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&nbsp;<strong><span>Tomcat</span></strong><strong><span>服务器<span>JAAS</span>配置方法</span></strong></p>
<p align=left><span>　　和在应用程序运行</span><span>JAAS</span><span>不同的是，配置</span><span>JAAS</span><span>方法会有很不一样。我们使用的是</span><span>Tomcat 5.0.x </span><span>应用服务器，它的</span><span>JAAS</span><span>配置方法有数种，分别是</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAASRealm</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JDBCRealm</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSourceRealm</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JNDIRealm</span></p>
<p align=left><span>&amp; #61557;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemoryRealm</span></p>
<p align=left><span>JAASRealm</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>把自定义</span><span> LoginModule</span><span>、</span><span>User</span><span>、</span><span>Role</span><span>等相关类放入</span><span>Tomcat </span><span>的</span><span> classpath</span></p>
<p align=left><span>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>把自定义</span><span>login.config JAAS</span><span>配置文件配置进</span><span>JVM</span><span>环境，例如：</span><span>&nbsp;JAVA_OPTS=-DJAVA_OPTS=-Djava.security.auth.login.config==$CATALINA_HOME/conf/jaas.config</span></p>
<p align=left><span>3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>设置</span><span> web.xml</span><span>里的</span><span> security-constraints </span><span>标签设定需要保护的资源</span></p>
<p align=left><span>4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>在</span><span>$CATALINA_HOME/conf/server.xml</span><span>里</span><span>engine</span><span>标签里设置</span><span>JAASRealm</span><span>标签</span></p>
<p align=left><span>以下是</span><span>JAASRealm</span><span>标签的详细说明</span></p>
<div align=center>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>属性</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>描述</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>className</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>只需要指定</span><span> org.apache.catalina.realm.JAASRealm</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>debug</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>设置</span><span>debug</span><span>级别，默认为不设置</span><span>0</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>appName</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>JAAS</span><span>配置文件应用名</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>userClassNames</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>自定义</span><span>user Principals</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>roleClassNames</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>自定义</span><span> role Principals</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=127>
            <p align=left><span>useContextClassLoader</span></p>
            </td>
            <td vAlign=top width=441>
            <p align=left><span>默认为</span><span>true, </span><span>为了向后兼容类装载方式，使用</span><span>Tomcat4</span><span>以上版本</span><span>ContextLoader</span><span>装载方式</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p align=left>&nbsp;</p>
<p align=left><span>以下是完整的</span><span>tomcat</span><span>服务器配置例子：</span></p>
<p align=left><span>在</span><span>%TOMCAT_HOME%/config/server.xml </span><span>中添加以下段落</span></p>
<p align=left><span>&lt;Realm className="org.apache.catalina.realm.JAASRealm"<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>appName="MyFooRealm"<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span>userClassNames="org.foobar.realm.FooUser"<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>roleClassNames="org.foobar.realm.FooRole" </span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>debug="99"/&gt;</span></p>
<p><span>上面介绍了<span>tomcat</span>的应用，而<span>liferay</span>（<span>tomcat</span>版本）也是利用了这种标准的<span>tomcat</span>的<span>JAAS</span>实现。</span></p>
<p><span>与权限管理、用户认证的主要类包为：</span></p>
<p><span>com.liferay.portal.security.auth.*</span></p>
<p><span>com.liferay.portal.service.permission</span></p>
<p><span>com.liferay.portal.struts.PortalRequestProcessor</span></p>
<p>&nbsp;</p>
<p><span>Liferay</span><span>关于<span>JAAS</span>的实现包都在<span>com.liferay.portal.security.auth.*</span>下，在<span>$catalina_home/conf/jaas.conf</span>中定义了<span>Liferay</span>实现的<span>loginModule</span>，在我使用的版本中，<span>PortalLoginModule</span>将首先通过对象池取出一个自定义<span>Liferay</span>用户自定义的实现，即也可以在<span>portal</span>中再次自定义<span>loginModule</span>。显然，如果没有自定义的实现，将根据用户所使用的服务器自动进行选择默认实现。</span></p>
<p><span>Liferay</span><span>自身所实现的</span><span>user Principals</span><span>和<span>role Principals</span>也仅仅是保存了用户的<span>userid</span>，以其作为自身标识，在登陆成功时赋予了所有用户&#8220;<span>users</span>&#8221;角色：</span></p>
<p align=left><span>PortalRole role = </span><strong><span>new</span></strong><span> PortalRole(</span><span>"users"</span><span>);</span></p>
<p><span>getSubject().getPrincipals().add(role);</span></p>
<p><span>Liferay</span><span>的<span>PortalRequestProcessor</span>扩展了<span>TilesRequestProcessor</span>，实现了自定义的请求处理流程。在请求流程中复写了</span><span>processRoles</span><span>（），在这个函数中进行了用户权限的判断，从而达到了对<span>web</span>资源的保护。</span></p>
<p><span>Permission</span><span>是<span>Liferay</span>定义的用户访问的权限判断，由</span><span>processRoles</span><span>调用进行访问控制。</span></p>
<p><span>值得一提的是，<span>Liferay</span>本身也含有登陆模块，这个登陆模块所做的主要工作为通过认证确定用户的登陆信息正确，并通过用户的登陆信息取得用户<span>userid</span>存放在<span>session</span>中，为<span>JAAS</span>的登陆模块提供基础（即通过登陆的正确用户<span>id</span>与密码）。登陆的用户默认为<span>LDAP</span>登陆，但是为默认禁用，所以用户认证<span>Liferay</span>都通过一个数据库的认证实现在<span>loginAction</span>中进行的用户判断，取出了<span>userid</span>和<span>password</span>存放在<span>session</span>中。</span></p>
<p><span>整个过程如下：</span></p>
<p>&#160;</p>
<p><span>如上图所示，触发<span>JAAS</span>的登陆模块的是在登陆成功后转向了<span>/c/portal/protected</span>，而此路径为<span>tomcat</span>的安全域，所以<span>tomcat</span>将调用用户自定义的登陆模块进行用户认证，通过认证后通过对用户角色的对比，来判断用户是否允许访问。</span></p>
<p><span>&nbsp;<span><strong>图2 Liferay认证流程</strong><br><img height=90 alt="" src="http://blog.ccidnet.com/attachment/Mon_0611/10_22729_0dff915b73eafc5.jpg" width=445 border=0><br>&nbsp;&nbsp;</span></span></p>
<p>&nbsp;</p>
<span>
<p><span>副录：帮助进行相关类查看</span></p>
<p><span>SecureFilter</span><span>-&gt;</span><span>进行访问地址限制和是使用安全连接转换。</span></p>
<p><span>PropsUtil</span><span>—<span>〉</span><span>portal-ejb.jar</span>里的<span>portal.property</span></span></p>
<p><span>MainServlet</span><span> </span><span>扩展<span>Struts</span>的<span>action Serverlet</span>，进行映射。</span></p>
</span>
<img src ="http://www.blogjava.net/junky/aggbug/121139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-31 13:45 <a href="http://www.blogjava.net/junky/archive/2007/05/31/121139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Single SignOn - Integrating Liferay With CAS Server</title><link>http://www.blogjava.net/junky/archive/2007/05/29/120724.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Tue, 29 May 2007 09:07:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/29/120724.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/120724.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/29/120724.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/120724.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/120724.html</trackback:ping><description><![CDATA[<h2>Introduction </h2>
<p>The following are a set of instructions for integrating Liferay Portal with CAS Server to setup single sign on (SSO) between Liferay and an existing web application. </p>
<a name=Setting_up_CAS_server></a>
<h2>Setting up CAS server </h2>
<p>We will begin with setting up JA-SIG CAS server on Tomcat 5.x.x. </p>
<p>Download cas-server WAR from <a class="external text" title=http://www.liferay.com/web/guest/downloads href="http://www.liferay.com/web/guest/downloads" rel=nofollow><u><font color=#800080>Liferay's download page</font></u></a> or the whole distribution from <a class="external text" title=http://www.ja-sig.org/products/cas/downloads/index.html href="http://www.ja-sig.org/products/cas/downloads/index.html" rel=nofollow><u><font color=#800080>here</font></u></a> and drop the cas-web.war file into Tomcat's webapps dir. In a production environment The CAS server should really run on its own tomcat instance but for testing purposes we'll drop it in the same instance as our Liferay portal. </p>
<p>We'll need to edit the server.xml file in tomcat and uncomment the SSL section to open up port 8443. </p>
<pre>&lt;Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" /&gt;
</pre>
<a name=Setting_up_the_CAS_client></a>
<h2>Setting up the CAS client </h2>
<p>Next we need to download the Yale CAS client from <a class="external text" title=http://www.ja-sig.org/products/cas/downloads/index.html href="http://www.ja-sig.org/products/cas/downloads/index.html" rel=nofollow><u><font color=#800080>here</font></u></a>. Get cas-client-2.0.11. Place the casclient.jar in ROOT/web-inf/lib of the Liferay install. </p>
<a name=Generate_the_SSL_cert_with_Java_keytool></a>
<h2>Generate the SSL cert with Java keytool </h2>
<p>Now that we have everything we need, it's time to generate an SSL cert for our CAS server. Instructions and more information on SSL certs can be found <a class="external text" title=http://www.ja-sig.org/products/cas/server/ssl/index.html href="http://www.ja-sig.org/products/cas/server/ssl/index.html" rel=nofollow><u><font color=#800080>here</font></u></a> </p>
<p>But I found some typos and errors on that page. So following the instructions below should get you what you need. </p>
<p>In any directory ( I use my root ) enter the command: </p>
<p>keytool -genkey -alias tomcat -keypass changeit -keyalg RSA </p>
<p>Answer the questions: (note that your firstname and lastname <strong>MUST</strong> be hostname of your server and cannot be a IP address; this is very important as an IP address will fail client hostname verification even if it is correct) </p>
<pre>Enter keystore password:  changeit
What is your first and last name?
[Unknown]:  localhost
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]:
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]:
Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
[no]: yes
</pre>
<p>Then enter the command: </p>
<pre>keytool -export -alias tomcat -keypass changeit -file %FILE_NAME%
</pre>
<p>I use server.cert for %FILE_NAME%. This command exports the cert you generated from your personal keystore (In windows your personal keystore is in C:\Documents and Settings\&lt;username&gt;\.keystore) </p>
<p>Finally import the cert into Java's keystore with this command. Tomcat uses the keystore in your JRE (%JAVA_HOME%/jre/lib/security/cacerts) </p>
<pre>keytool -import -alias tomcat -file %FILE_NAME% -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts
</pre>
<p>Startup the CAS server </p>
<p>Now you are ready to startup your CAS server. Simply startup Tomcat and access CAS with <a class="external free" title=https://localhost:8443/cas href="https://localhost:8443/cas" rel=nofollow><u><font color=#800080>https://localhost:8443/cas</font></u></a> You should see the CAS login screen and no errors in your catalina logs. </p>
<a name=Setting_up_Liferay_Portal></a>
<h2>Setting up Liferay Portal </h2>
<a name=web.xml></a>
<h3>web.xml </h3>
<p><strong>Note</strong>: If you are using Liferay 4.2, this filter is already defined. All you have to do is modify the URL parameters, if your CAS server is at a different location. </p>
<p>It's time to move on to configuring Liferay. In the web.xml file you will need to add a new filter and its mapping directly above the first existing auto login filter mapping. This new filter we just added will redirect all login attempts to the CAS server. If your hostname is different you can modify the init-params accordingly. </p>
<p><br></p>
<pre>&lt;filter&gt;
&lt;filter-name&gt;CAS Filter&lt;/filter-name&gt;
&lt;filter-class&gt;edu.yale.its.tp.cas.client.filter.CASFilter&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;edu.yale.its.tp.cas.client.filter.loginUrl&lt;/param-name&gt;
&lt;param-value&gt;<a class="external free" title=https://localhost:8443/cas-web/login href="https://localhost:8443/cas-web/login" rel=nofollow><u><font color=#0000ff>https://localhost:8443/cas-web/login</font></u></a>&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;init-param&gt;
&lt;param-name&gt;edu.yale.its.tp.cas.client.filter.validateUrl&lt;/param-name&gt;
&lt;param-value&gt;<a class="external free" title=https://localhost:8443/cas-web/proxyValidate href="https://localhost:8443/cas-web/proxyValidate" rel=nofollow><u><font color=#0000ff>https://localhost:8443/cas-web/proxyValidate</font></u></a>&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;init-param&gt;
&lt;param-name&gt;edu.yale.its.tp.cas.client.filter.serviceUrl&lt;/param-name&gt;
&lt;param-value&gt;<a class="external free" title=http://localhost:8080/c/portal/login href="http://localhost:8080/c/portal/login" rel=nofollow><u><font color=#800080>http://localhost:8080/c/portal/login</font></u></a>&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;
</pre>
<p>If you use a ...serviceUrl param like above, after logging in with CAS, the browser will be redirected back to that serviceUrl. However, you can change it to the following and it will redirect back to the full URL that was originally requested. This allows you to have a deep link (e.g. to a certain layout with parameters for a portlet even) that is preserved through the CAS login process: </p>
<pre>   &lt;init-param&gt;
&lt;param-name&gt;edu.yale.its.tp.cas.client.filter.serverName&lt;/param-name&gt;
&lt;param-value&gt;localhost:8080&lt;/param-value&gt;
&lt;/init-param&gt;
</pre>
<p><br></p>
<pre>&lt;filter-mapping&gt;
&lt;filter-name&gt;CAS Filter&lt;/filter-name&gt;
&lt;url-pattern&gt;/c/portal/login&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>
<p><br>Then add the following to the rest of the auto login filters </p>
<pre>&lt;filter-mapping&gt;
&lt;filter-name&gt;Auto Login Filter&lt;/filter-name&gt;
&lt;url-pattern&gt;/c/portal/login&lt;/url-pattern&gt;
&lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
&lt;dispatcher&gt;INCLUDE&lt;/dispatcher&gt;
&lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
&lt;/filter-mapping&gt;
</pre>
<a name=system-ext.properties></a>
<h3>system-ext.properties </h3>
<p><strong>Note</strong>: this is only needed in Liferay 4.2 </p>
<p>Set the com.liferay.filters.sso.cas.CASFilter setting to true. </p>
<p>Place the following in system-ext.properties: </p>
<pre>   #
# The CAS filter will redirect the user to the CAS login page for SSO. See
# <a class="external free" title=http://www.ja-sig.org/products/cas href="http://www.ja-sig.org/products/cas" rel=nofollow><u><font color=#0000ff>http://www.ja-sig.org/products/cas</font></u></a> for more information.
#
com.liferay.filters.sso.cas.CASFilter=true
</pre>
<a name=portal-ext.properties></a>
<h3>portal-ext.properties </h3>
<p>Put this in portal-ext.properties. </p>
<pre>##
## Auto Login
##
</pre>
<pre>#
# Input a list of comma delimited class names that implement
# com.liferay.portal.security.auth.AutoLogin. These classes will run in
# consecutive order for all unauthenticated users until one of them return a
# valid user id and password combination. If no valid combination is
# returned, then the request continues to process normally. If a valid
# combination is returned, then the portal will automatically login that
# user with the returned user id and password combination.
#
# For example, com.liferay.portal.security.auth.BasicAutoLogin reads from a
# cookie to automatically log in a user who previously logged in while
# checking on the "Remember Me" box.
#
# This interface allows deployers to easily configure the portal to work
# with other SSO servers. See com.liferay.portal.security.auth.CASAutoLogin
# for an example of how to configure the portal with Yale's SSO server.
#
#auto.login.hooks=com.liferay.portal.security.auth.BasicAutoLogin
auto.login.hooks=com.liferay.portal.security.auth.BasicAutoLogin,com.liferay.portal.security.auth.CASAutoLogin
</pre>
<p>Comment the first auto.login.hooks property and uncomment the second to add CASAutoLogin to the list of AutoLogin implementations. </p>
<a name=Startup_Liferay_and_Test></a>
<h2>Startup Liferay and Test </h2>
<p>Startup the portal and when the homepage loads up hit the login link. If all goes well you should be redirected to the CAS server's login screen. Login to CAS with liferay.com.1 as your username and liferay.com.1 as your password. You should now be logged into the portal. </p>
<a name=Next_steps></a>
<h2>Next steps </h2>
<p>If the above test worked, you already have a CAS server installed and integrated with Liferay. The next steps are more related to properly configuring the CAS server than with Liferay. That's out of the scope of this article but we'll give a very brief summary. </p>
<p>By integrating the CAS server Liferay, is no longer responsible for authenticating the users, it just trusts that the CAS server authenticates them properly. The CAS server has configurable strategies for authenticating users. So far the default one has been used, which just authenticates the user if the user and password are the same. That's completely unsecure so other options need to be considered before installing in a production environment. Some reasonable options would be: </p>
<ul lastCheckbox="null">
    <li>To authenticate with LDAP: The CAS server includes an authentication handler for LDAP. You can read about it in <a class="external free" title=http://www.ja-sig.org/products/cas/server/ldapauthhandler/index.html href="http://www.ja-sig.org/products/cas/server/ldapauthhandler/index.html" rel=nofollow><u><font color=#0000ff>http://www.ja-sig.org/products/cas/server/ldapauthhandler/index.html</font></u></a>. If this option is chosen it is recommended that you also configure Liferay to authenticate against LDAP using the instructions in: <a title=LDAP href="http://wiki.liferay.com/index.php/LDAP"><u><font color=#0000ff>LDAP</font></u></a>. Then you'll need to provide some way to synchronized the users between LDAP and Liferay's database. Two options are:
    <ul lastCheckbox="null">
        <li>Set up the automatic importer (see <a title=LDAP href="http://wiki.liferay.com/index.php/LDAP"><u><font color=#0000ff>LDAP</font></u></a>, available since v4.2)
        <li>Develop an extension to CASAutoLogin that upon successful login, if the user does not exist it is created with the user from LDAP (see <a class="external text" title=http://www.liferay.com/web/guest/devzone/forums/message_boards/message/31102 href="http://www.liferay.com/web/guest/devzone/forums/message_boards/message/31102" rel=nofollow><u><font color=#0000ff>this mb thread</font></u></a> for details) </li>
    </ul>
    <li>To authenticate with the portal's database: It is possible to develop your own CAS authentication handler that uses the information present in Liferay's database. One way of doing this would be using Liferay's services to authenticate the user.
    <li>To authenticate against another user store: in this case you'll also need to write your own CAS authentication handler and also provide Liferay some way to add the user entries in its own database. </li>
</ul>
<p>Some other steps that you might want to follow are: </p>
<ul lastCheckbox="null">
    <li>Modify the look and feel of the CAS server pages to match those provided by the portal: <a class="external free" title=http://www.ja-sig.org/products/cas/server/views/index.html href="http://www.ja-sig.org/products/cas/server/views/index.html" rel=nofollow><u><font color=#0000ff>http://www.ja-sig.org/products/cas/server/views/index.html</font></u></a>
    <li>Clustering: <a class="external free" title=http://www.ja-sig.org/products/cas/server/cluster/index.html href="http://www.ja-sig.org/products/cas/server/cluster/index.html" rel=nofollow><u><font color=#0000ff>http://www.ja-sig.org/products/cas/server/cluster/index.html</font></u></a>
    <li>Set up real certificates </li>
</ul>
<p>Also, check the references at the end of the article for more information. </p>
<a name=Troubleshooting></a>
<h2>Troubleshooting </h2>
<p>If you created a cert with the %FILE_NAME%, you'll probably run into problems. Here are 2 commands to delete the tomcat alias from the keystore so you can start fresh: </p>
<pre>keytool -delete -alias tomcat -keystore %JAVA_HOME%/jre/lib/security/cacerts
keytool -delete -alias tomcat -file server.cert
</pre>
<ul lastCheckbox="null">
    <li>You may not be able to get <a class="external free" title=https://localhost:8443/cas href="https://localhost:8443/cas" rel=nofollow><u><font color=#800080>https://localhost:8443/cas</font></u></a> up and running after the cert key generation. If so, skip the test and try it after you've finished all the steps. If you can't login at that point, you've probably generated your cert incorrectly.
    <li>I've had problems with certs on IE7, make sure you try it out on Firefox and Opera. </li>
</ul>
<ul>
    <li>Your certificate must be trusted. If you created a self-signed certificate, you must add it to your truststore. I mistakenly thought I could define the truststore settings on my Tomcat SSL Connector. That didn't work because CAS was redirecting (after logging in) to a non-SSL page. Since the HTTP connector didn't know to trust the self-signed certificate, I got the 'sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target' error. My solution was to follow the guidelines in the <a class="external text" title=http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#CreateKeystore href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#CreateKeystore" rel=nofollow><u><font color=#0000ff>JSSE Reference Guide</font></u></a> and define the truststore in the JAVA_OPTS (-Djavax.net.ssl.trustStore=/path/to/custom/truststore). I created both a custom keystore (needed by the SSL Connector and specified either in the Connector config or the JAVA_OPTS) and custom truststore. </li>
</ul>
<a name=References></a>
<h2>References </h2>
<ul>
    <li>Lifecast: <a class="external text" title=http://www.liferay.com/web/guest/devzone/lifecast href="http://www.liferay.com/web/guest/devzone/lifecast" rel=nofollow><u><font color=#0000ff>CAS Setup</font></u></a> - Integrate Liferay Portal with a CAS server to access multiple applications with a single sign on. </li>
</ul>
<ul>
    <li>A short article regarding CAS, Active Directory and an example&nbsp;: <a class="external free" title=http://www-128.ibm.com/developerworks/web/library/wa-singlesign/ href="http://www-128.ibm.com/developerworks/web/library/wa-singlesign/" rel=nofollow><u><font color=#0000ff>http://www-128.ibm.com/developerworks/web/library/wa-singlesign/</font></u></a> </li>
</ul>
<!-- Saved in parser cache with key wikidb:pcache:idhash:1512-0!1!0!0!!en!2 and timestamp 20070528213528 -->
<div class=printfooter>Retrieved from "<a href="http://wiki.liferay.com/index.php/Single_SignOn_-_Integrating_Liferay_With_CAS_Server"><u><font color=#800080>http://wiki.liferay.com/index.php/Single_SignOn_-_Integrating_Liferay_With_CAS_Server</font></u></a>"</div>
<img src ="http://www.blogjava.net/junky/aggbug/120724.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-29 17:07 <a href="http://www.blogjava.net/junky/archive/2007/05/29/120724.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>liferay Portal 二次开发指南</title><link>http://www.blogjava.net/junky/archive/2007/05/28/120397.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Mon, 28 May 2007 02:01:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/28/120397.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/120397.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/28/120397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/120397.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/120397.html</trackback:ping><description><![CDATA[文档说明
<p>&nbsp;<br>参与人员：<br>&nbsp;<br>作者 网名 联络 <br>柯自聪 eamoi&nbsp;&nbsp; educhina <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#97;&#109;&#111;&#105;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;">eamoi@163.com</a>（技术） <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#99;&#107;&#101;&#48;&#55;&#50;&#56;&#64;&#104;&#111;&#116;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">zcke0728@hotmail.com</a>（版权） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;<br>发布记录：<br>&nbsp;<br>版本 日期 作者 说明 <br>1.0 2005-10-20 柯自聪 创建，第一版 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;<br>链接：<br>&nbsp;<br>类别 网址 <br>Blog <a href="http://www.blogjava.net/eamoi/">http://www.blogjava.net/eamoi/</a> <br>MSN-Space <a href="http://spaces.msn.com/members/eamoi/">http://spaces.msn.com/members/eamoi/</a> </p>
<p>&nbsp;<br>&nbsp;<br>OpenDoc版权说明：<br>本文档版权归原作者所有。<br>在免费、且无任何附加条件的前提下，可在网络媒体中自由传播。<br>如需部分或者全文引用，请事先征求作者意见。<br>如果本文对您有些许帮助，表达谢意的最好方式，是将您发现的问题和文档改进意见及时反馈给作者。当然，倘若有时间和能力，能为技术群体无偿贡献自己的所学为最好的回馈。<br>&nbsp;<br>序... 5<br>第一部分 Liferay Portal 架构解析... 6<br>第一章 Liferay Portal. 6<br>第一节 Portal规范... 6<br>1.1.1 JSR168. 6<br>1.1.2 WSRP. 6<br>第二节 什么是Portal7<br>1.2.1 Portal 服务器... 7<br>1.2.2 Portlet容器... 7<br>第三节 什么是Portlet8<br>1.3.1 Portlet8<br>1.3.2 Portlet与Servlet的关系... 8<br>1.3.3 Portlet的生命周期... 9<br>第四节 Liferay Portal工作原理... 9<br>1.4.1 Portlet 样式以及窗口状态... 10<br>1.4.2 Portal页面... 11<br>第二章Liferay Portal的使用... 13<br>第一节 Liferay Portal安装... 13<br>第二节 Liferay Portal的用户策略... 14<br>2.2.1 定义用户... 14<br>2.2.2 添加用户... 15<br>2.2.3 修改用户... 15<br>2.2.4 定义用户组... 18<br>2.2.5 新增、重命名用户组... 19<br>2.2.6 修改用户组... 19<br>2.2.7 定义角色... 21<br>2.2.8 新增、重命名角色... 21<br>2.2.9 修改用户组角色... 21<br>2.2.10 定义Portlet的角色... 22<br>第三节 Liferay Portal内容和布局... 24<br>2.3.1 什么是布局... 24<br>2.3.2 什么是内容... 26<br>2.3.3 内容布局与Portlet的关系... 27<br>2.3.4 选择内容和布局... 28<br>第四节 Liferay Portal的桌面... 28<br>2.4.1 什么是桌面... 28<br>2.4.2 定义个性化的桌面... 29<br>第五节 Liferay Portal的品质... 29<br>2.5.1 什么是品质... 30<br>2.5.2 品质和Portlet、Portal的关系... 30<br>2.5.3 定义个性化的品质... 30<br>第六节 Liferay Portal的部署描述文件... 31<br>2.6.1 web.xml31<br>2.6.2 portlet.xml32<br>2.6.3 liferay-Portlet.xml33<br>2.6.4 liferay-display.xml34<br>2.6.5 liferay-layout-templates.xml35<br>2.6.7 liferay-look-and-feel。xml35<br>第二部分 Liferay Portal 二次开发... 36<br>第三章开发自己的Portlet. 36<br>第一节 重要的基类：GenericPortlet36<br>第二节 Portlet标签... 37<br>3.2.1 defineObjects标签... 37<br>3.2.2 renderURL标签... 37<br>3.2.3 actionURL标签... 38<br>3.2.4 param标签... 38<br>3.2.5 namespace标签... 38<br>第三节 Portal的对象... 38<br>3.3.1 Request对象... 39<br>3.3.2 Response对象... 41<br>3.3.3 PortletConfig对象... 41<br>3.3.4 Session对象... 41<br>3.3.5 Preference对象... 43<br>第四节 编写自己的Portlet类... 44<br>3.4.1 开发环境... 44<br>3.4.2 准备工作... 44<br>3.4.3 HelloWorldPortlet46<br>3.4.4 HelloJSPPortlet47<br>第五节 修改Web部署描述文件... 48<br>第六节 创建Liferay Portal部署描述文件... 49<br>第三部分 Liferay Portal部署... 54<br>第四章部署自己的Portlet. 54<br>第一节 手动部署... 54<br>第二节 Ant自动部署... 55<br>第三节 加入Liferay Portal自有列表... 55<br>第四节 普通Java Web应用转化为Portlet应用... 56<br>第四部分附录... 58<br>第五章相关资源... 58<br>第一节资源网站... 58<br>第二节 示例... 58<br>第六章参考资料... 59<br>后序<br>&nbsp;<br>第一部分 Liferay Portal 架构解析<br>本部分主要内容<br>Portal 服务器 Portal 容器 Portlet<br>第一章 Liferay Portal<br>作为一个开源Portal产品，Liferay Portal提供对多个独立系统的内容集成，帮助多个组织实现更有效的合作。与其他商业的Portal产品相比，Liferay Portal有着一系列的优良特性，而且不需要付费。<br>第一节 Portal规范<br>随着Portal的兴起，越来越多的公司开始涉足Portal产品开发，并组建各自的Portal组件和基于其的产品，比如IBM、BEA、MicroSoft、SAP、Apache等。各个厂商的接口互不兼容，给软件开发商以及开发人员带来诸多不便。<br>1.1.1 JSR168<br>为此，JCP组织发布了JSR168(Java Specification Request)，Portlet Specification V1.0，用来提供不同的Portal和Portlet之间的互通性。只要开发的Portlet遵循JSR168，则就可以在所有遵循JSR168的Portal上部署运行。<br>JSR168中定义了Portal的实现规范和接口，并对理想的Portlet进行了详细的规划和描述。<br>1.1.2 WSRP<br>WSRP是OASIS Web Service for&nbsp;Remote Portlet的缩写。WSRP是Web Service的一种新的商业应用，一种新的标准，主要用来简化Portal对于各种资源或者程序整合的复杂度，可以避免编程带来的整合麻烦和问题。而且Portal管理员可以从海量的WSRP服务中选择需要的功能用以整合到目前所用的Portal中。它有三种角色：<br>①、生产者 &#224; 提供Portlet<br>②、消费者 &#224; 使用Portlet<br>③、终端用户 &#224; 最终用户<br>它的特点在于生产者将消费者所需要的信息通过WSRP返回给消费者，这些信息是相对标记片断，例如HTML、XHTML等，可以直接嵌入用户的页面中，而不用像Web Service一样开发用户端接口。<br>实现这个规范，Portal可以跟各式各样的数据源打交道，彻底终结信息孤岛的窘境。<br>第二节&nbsp; 什么是Portal<br>Portal是基于Web的，以&#8220;应用整合&#8221;和&#8220;消除信息孤岛&#8221;为最终目的，提供单点登录、内容聚合、个性化门户定制等功能的综合信息系统。<br>完整的Portal通常由Portal服务器、Portlet容器、Portlet构成。<br>1.2.1 Portal 服务器<br>Portal服务器是容纳Portlet容器，支持Portlet呈现的普通或者特殊Web服务器。Portal服务器通常会提供个性化设置、单点登录、内容聚合、信息发布、权限管理等功能，支持各种信息数据来源，并将这些数据信息放在网页中组合而成，提供个性化的内容定制，不同权限的浏览者能够浏览不同的信息内容。通常，Portal提供以下功能:<br>单点登录：Portal通常采用ACL、SSL、LDAP等业界标准的安全技术，提供对所有现有应用系统的安全集成，只需在Portal的唯一入口上登录一次，就可以访问所有应用系统和数据。对于安全性要求较高的应用系统，如电子商务平台、交易系统等，通过扩展接口传递用户身份信息，如数字证书信息、数字签名信息等，进行二次身份认证，保证单点登陆的安全性。<br>权限控制:系统采用LDAP对用户资源进行统一的管理，同时提供二次开发接口，可以与其他应用系统的用户管理模块对接，并能随相关业务系统实时更新访问权限。通过完善的授权机制及存取控制，用户访问权限控制到字段级别，确保用户只能访问具有权限的应用系统及相关信息。<br>内容管理: 实现应用系统之间实时交换信息。采用多种缓存机制，保证内容交换的性能和准确性。采用基于XML的Rich Site Summary (RSS)标准，迅速在各应用系统之间传播最新变化。<br>信息发布: 实现信息门户内容的动态维护。动态网站系统可与OA协同办公系统、知识管理系统等集成，网站信息须经OA系统的审批流程流转通过后或知识管理平台设置具有外部共享权限后才可正式发布，真正实现内外信息发布的同步。<br>文件管理: 系统实现无缝集成多种数据源，包括：数据库、文档（Office文档、PDF、AutoCAD、甚至ZIP文档）、Web网页、FTP站点等，并对数据按业务要求和职务特点加以分析整理，通过统一Web界面主动推送(Push)至用户的门户桌面，帮助用户做出及时、正确的决策。<br>1.2.2&nbsp; Portlet容器<br>Portlet容器提供Portlet执行的环境，包含很多Portlet并管理它们的生命周期，保存Portlet的定制信息。<br>一个Portal容器接收到来自Portal的请求后，接着将这个请求传递给存在Portal容器的Portlet 执行。Portlet容器没有义务去组合Portlet 产生的信息內容，这个工作必须由Portal来处理。Portal和 Portal容器可以放在一起视为同一个系统的组件，或者分开成为两个独立的组件。<br>Portlet容器是普通Web Servlet容器的扩展，所以一个Portlet容器可以构建于一个已经存在的Servlet容器或者可能实现全部Web Servlet容器的全部功能。无论Portlet容器怎么实现，它的运行环境总是假定它支持Servlet2.3规范。<br>通常，Portlet容器扩展自普通的Servlet容器。<br>&nbsp;<br>第三节&nbsp; 什么是Portlet<br>Portlet是Portal中最重要的组件，负责在Portal中呈现信息内容，有相应的生命周期。通过自定义Portlet，用户很容易定义个性化的Portal页面。Portlet由Portlet容器负责管理、处理请求并返回动态页面，可以作为Portal的可即插即用的界面组件。<br>1.3.1 Portlet<br>一个Portlet是以Java技术为技术的Web组件，由Portlet容器所管理，专门处理客户的信息请求以及产生各种动态的信息内容。Portlet 为可插式的客户界面组件，提供呈现层成为一个信息系统。<br>这些由Portlet产生的内容也被称为片段，而片段是具有一些规则的标记( HTML、XHTML、WML )，而且可以和其他的片段组合而成一个复杂的文件。一个或多个 Portlet 的内容聚合而成为一个 Portal 网页。而 Portlet 的生命周期是被 Portlet 容器所管理控制的。<br>客户端和Portlet的互动是由Portal通过典型的请求/响应方式实现，正常来说，客户会和Portlet所产生的内容互动，举例来说，根据下一步的连接或者是确认送出的表单，结果 Portal将会接收到Portlet的动作，将这个处理状况转向到目标Portlet。这些Portlet 内容的产生可能会因为不同的使用者而有不同的变化，完全是根据客户对于这个Portlet的设置。<br>1.3.2 Portlet与Servlet的关系<br>Portlet被定义成为一个新的组件，具有新的明确的界面与行为。为了尽可能与现有的 Servlet 结合达到重复使用的目的，Portlet 的规范利用了 Servlet 的规范，许多观念都很相似的，结合 Portlet、Servlet 及 Jsp 在同一个网站系统中，我们称为Portlet 应用 。在同一个 Portlet 应用 中，他们将分享同一个类加载器(ClassLoader)，上下文(Context) 及 Session。 <br>①、Portlet 和 Servlet 的相似之处<br>@ Portlet 也是 Java 技术的 web 组件<br>@ Portlet 也是有特定的 container 在管理<br>@ Portlet 可以动态产生各种内容<br>@ Portlet 的生命周期由 container 所管理<br>@ Portlet 和客户端的互动是通过 request/response 的机制 <br>②、Portlet 和 Servlet 也有一些不同<br>@ Portlet 只产生 markup 信息片段，不是完整的网页文件。而 Portal 会将所有的 Portlet markup 信息片段放到一个完整的 Portal 网页。<br>@ Portlet 不会和 URL 有直接的关系<br>@ 客户端必须通过 portal 系统才能和 Portlet 互动<br>@ Portlet 有一些定义好的 request 处理，action request 以及 render request。<br>@ Portlet 默认定义 Portlet modes 及窗口状态可以指出在网页中该 Portlet 的哪个功能正在执行及现在的 状态。<br>@ Portlet 可以在同一个 portal 网页之中存在多个。 <br>③、Portlet 有一些附加的功能是 Servlet 所没有的<br>@ Portlet 能够存取及储存永久配置文件及定制资料。<br>@ Portlet 可以存取使用者数据<br>@ Portlet 具有 URL 的重写功能在文件中去动态建立连结，允许 portal server 不用去知道如何在网页的片 段之中建立连结及动作。<br>@ Portlet 可以储存临时性的数据在 Portlet session 之中，拥有两个不同的范围：<br>application-wide scope 及 Portlet private scope 。<br>④、Portlet 不具有一些功能， 但是 Servlet 却有提供<br>@ Servlet 具有设置输出的文字编码( character set encoding)方式<br>@ Servlet可以设置 HTTP 输出的 header<br>@ Servlet才能够接收客户对于 portal 发出的 URL 请求<br>1.3.3 Portlet的生命周期<br>一个Portlet有着良好的生命周期管理，定义了怎样装载，实例化和初始化，怎样响应来自客户端的请求及怎样送出服务。这个Portlet生命周期由Portlet接口的init，processAction，render和destroy方法来表达。<br>载入和实例化:Portlet容器负责载入和实例化Portlet。当Portlet容器运行Portlet应用或者延迟到Portlet需要服务使用者的请求时，Portlet就会被载入并实例化。载入Portlet类后，Portlet类随即被实例化。<br>初始化:Portlet类实例化后，Portlet容器还需要初始化Portlet。以调用Portlet去响应客户端的请求。Portlet容器呼叫Portlet接口中的init方法初始化Portlet。扩展自PortletConfig的类可以取出定义在部署描述文件中的初始化参数，以及Resource Bundle。<br>初始化异常:在 Portlet初始化期间，Portlet可能会丟出 UnavailableException 或 PortletException 异常。此时，Portlet容器不能把 Portlet置入已启动的服务，并且 Portlet容器必需释放这个 Portlet。 destory方法不能被呼叫，因为初始化被认为执行失败。发生 失败后，Portlet容器会尝试着重新实例化及初始化 Portlet。这个异常处理的规则是：由一个UnavailableException 指定一个不能执行的最小时间，当此异常发生时，Portlet容器必需等到指定时间过去后才产生并且初始化一个新的 Portlet。<br>在初始化过程中所丟出的 Runtime Exception异常，被当作 PortletException 来处理。<br>第四节 Liferay Portal工作原理<br>Portal系统根据需要由一个或者多个Portal页面组成，每个Portal页面包含零个或者多个的Portlet。每个Portlet呈现自己的信息内容，以此实现内容聚合。通过定义每个Portlet的可用权限，实现个性化的桌面信息定制。<br>1.4.1 Portlet 样式以及窗口状态</p>
<p>JCP组织提出的JSR168规范定义了Portlet的实现标准。每个Portlet对外表现为一个小窗口，有自己的默认样式和窗口状态。如上图，Portlet有自己的标题，浏览状态下支持编辑、关闭、上移、下移、最大化、最小化功能，编辑状态下支持返回和关闭功能。从各种数据来源提取的信息以Portlet内容的形式呈现在Portal中。<br>Portlet样式指出 Portlet正处于什么模式，Portlet通常会根据所处的模式而执行不同的工作并产生不同的内容。<br>Portlet模式让 Portlet决定它该显示什么内容和执行什么动作。调用一个 Portlet的时候，Portlet 容器会提供一个 Portlet模式给那个 Portlet。当在处理一个请求动作时，Portlet 的模式是可以用程序来改变的。<br>JSR168规范定义了三个Portlet模式： 浏览、编辑和帮助，Liferay Portal支持其中的全部三个模式。同时Portal是可以根据使用者的角色，来决定是要提供(显示)哪几个 Portlet 模式给使用者操作。<br>例如，匿名使用者可以操作浏览和帮助等 Portlet 模式的内容， 而只有授权过的使用者可以操作编辑这个 Portlet 模式所提供的内容或动作。<br>在浏览这个Portlet模式里，所被期望要提供的功能是产生标记语言来表现此时 Portlet的状态。 举例来说， Portlet的 浏览 模式可以包含一个或多个画面让使用者可以浏览与互动， 或是一些不需要与使用者互动的静态内容。 <br>&nbsp;&nbsp; 在编辑这个Portlet模式里， Portlet 需要提供内容和逻辑来让使用者定制 Portlet 的行为。典型的说，编辑模式的 Portlet 会设定或更新 Portlet 的参数设定值。<br>在帮助这个模式里，Portlet应该提供有关这个 Portlet的帮助信息。这个帮助信息可以是有关这个 Portlet的简单且条理清楚的视窗说明或是详细的说明整个来龙去脉。所有的Portlet并不需要都提供帮助这个模式。<br>一个 Portlet可以根据窗口状态来决定在一个页面里该占多少空间。当调用一个 Portlet时， Portlet容器 需要告诉该 Portlet目前的窗口状态。 此时 Portlet可以根据窗口状态来决定它该对多少信息作处理。在处理请求的过程中， Portlet可以通过程序的方式来改变窗口状态。<br>1.4.2 Portal页面</p>
<p><br>每个Portal页面包含零个或者多个Portlet小窗口，构成一个完整的信息呈现页面。Portal在启动之后根据Portlet配置文件等信息，给Portlet的标题等属性赋值，赋予Portlet编辑、关闭等各种控制按钮，使Portlet成为一个标准的Portlet窗口。Portlet合并这些Portlet窗口，组成一个完整的文档，即Portal页面。每个Portlet都处于相应的布局当中，呈现事先定义的内容，表现Portal公共的品质。而且Portlet可以在不同的布局之间切换。Portlet响应客户端的请求，并将请求提交到相应的URL进行逻辑处理。<br>Portlet开发完毕之后，部署到Portal服务器，由Portal服务器负责组织、权限控制和呈现。Portal页面创建过程如下:<br>Portlet 在 Portlet容器内执行，Portlet容器接收 Portlet产生的内容。通常 Portlet容器将这些内容提交给 Portlet服务器，Portlet服务器依照这些内容建立Portal页面，然后将它传给客户端呈现。具体流程如下图:</p>
<p><br>Portal页面的请求过程如下:<br>使用者经由客户端设备（例如浏览器）存取 Portal，Portal 根据接收到的请求决定哪些 Portlet 需要被执行以满足需求。Portal 通过Portlet容器呼叫 Portlet，然后由 Portlet产生的片段建立Portal页面，再传回客户端呈现给使用者。具体流程如下图:</p>
<p><br>第二章Liferay Portal的使用<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Liferay Portal分为Professional 和 Enterprise两个版本。<br>Liferay Portal支持多个应用服务器和Servlet容器。Liferay Portal Ent版本需要一个健壮的J2EE服务器，而Pro版本只要一个普通的Servlet服务器就可以运行。如果需要运行EJB，建议使用Pro版本。两个版本的源码和应用接口都是一样的。<br>默认的，Pro版本分别集成Tomcat / Jetty / Resin作为Web服务器，采用Struts作为Web框架，实现轻量级的系统架构。Enterprise集成JBoss作为Web服务器，采用Spring作为Web框架，兼顾EJB。<br>Liferay Portal默认集成HSQL数据库，来持久化保存用户自定义的数据。通过修改集成在Liferay Portal的Tomcat的部署描述文件，用户可以更改数据源。Liferay Portal官方网站提供了数据库表的生成脚本。<br>下面以Pro版本(Tomcat服务器)为例，讲述Liferay Portal的用户策略、内容布局、桌面和品质。<br>第一节 Liferay Portal安装<br>由于Liferay Portal Pro版本集成了Tomcat服务器V5，所以只要把应用包下载解压就可以直接运行。<br>1、从 <a href="http://www.iferay.om/web/guest/downloads/portal_pro">http://www.iferay.om/web/guest/downloads/portal_pro</a> 下载Pro版本zip包， 解压到目录{PORTAL_HOME}， 目录结构相对普通的Tomcat增加了Liferay文件夹。Liferay是默认的Web应用。<br>2、正确安装JDK1.4或者JDK1.5，并在环境变量里面正确配置JAVA_HOME变量。</p>
<p><br>3、从命令行启动{PORTAL_HOME}/bin/startup.bat，启动Liferay Portal。<br>4、在浏览器地址栏输入<a href="http://localhost/">http://localhost</a> ，访问Portal首页。<br>5、用Login为<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#116;&#101;&#115;&#116;&#64;&#108;&#105;&#102;&#101;&#114;&#97;&#121;&#46;&#99;&#111;&#109;">test@liferay.com</a>密码为test的用户登录Portal系统，得到的是一个Demo的首页。</p>
<p><br>如果启动呈现异常，请查看Tomcat控制台查找原因。<br>Liferay Portal启动之后，HSQL数据库自动启动。<br>登录系统后，点击右上角&#8220;My Account&#8221;链接，在&#8220;Display&#8221;选项卡中将Language改为&#8220;Chinese(China)&#8221;，以便中文化Portal界面。<br>第二节 Liferay Portal的用户策略<br>Liferay Portal通过定义严谨的用户策略、灵活的可个性化定制的内容和布局以及丰富可定制的品质策略，实现灵活的可定制的产品理念。<br>Liferay Portal采用用户－用户组－角色－Portlet的关联方式来实现用户权限的管理。用户录属于用户组（也可以单独存在），该用户组具有某种（多种）角色，角色分配给用户组，也可以直接分配给用户。而操作某个Portlet 需要具有其指定的角色。下面通过实例操作，来了解和体验一下Liferay Portal的用户管理策略。<br>2.2.1 定义用户<br>Liferay Portal的用户管理在系统管理的Portlet中。缺省只有系统管理员才能使用。登录Portal后，可以在默认的桌面上找到&#8220;系统管理&#8221;Portlet。如果没有，从页面底部的选择框中选择&#8220;系统管理&#8221;添加上。也可以通过右上角&#8220;CMS&#8221;桌面的&#8220;内容和布局&#8221;页面找到管理入口。<br>从&#8220;系统管理&#8221;Portlet中选择&#8220;用户&#8221;项，进入用户管理界面。</p>
<p><br>2.2.2 添加用户<br>图2.2.1-2所示页面右边为&#8220;新增用户&#8221;列，填入你所要增加的用户名称，姓氏，用户标识（可自动生成），邮件地址，密码（可自动生成）等。可以修改该用户所具有的用户组和角色信息（也可创建之后再修改）。用户标识必须是系统唯一的，所以请确保你所输入的用户标识与已有的不冲突。<br>点击&#8220;新增用户&#8221;，我们成功增加一位用户标示为&#8220;educhina&#8221;的用户，如图2.2.1-2所示。左侧列表中新增一项&#8220;educhina eamoi&#8221;。然后我们就可修改这位用户的用户组，角色，个人档案等信息了。<br>2.2.3 修改用户<br>选择用户列表中一项，然后点击底部的三个编辑按钮，就可以分别编辑该用户的用户组、角色、档案等信息了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此处我们选择用户&#8220;educhina eamoi&#8221;，然后选择&#8220;编辑档案&#8221;，出现档案编辑页面。如图2.2.3-3所示。填写你想要修改的信息，点击对应的&#8220;更新&#8221;按钮即可完成修改。需要注意的是整个档案页面分成几个部分，需要分别修改更新。<br>选择用户&#8220;educhina eamoi&#8221;，然后选择&#8220;编辑角色&#8221;，进入角色编辑页面，如图2.2.3-4所示。左侧列表框为当前该用户所具有的角色，右侧列表为所有可用的角色。要赋给用户新角色，则从右侧选择一项或多项，通过中间的转移按钮，从右侧添加至左侧。要删减用户角色，则从左侧移至 <br></p>
<img src ="http://www.blogjava.net/junky/aggbug/120397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-28 10:01 <a href="http://www.blogjava.net/junky/archive/2007/05/28/120397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat下配置liferay portal （专业配置）</title><link>http://www.blogjava.net/junky/archive/2007/05/28/120396.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Mon, 28 May 2007 02:00:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/28/120396.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/120396.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/28/120396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/120396.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/120396.html</trackback:ping><description><![CDATA[<font size=2>1. 下载安装JDK 1.4.2。设置环境变量命名为%JAVA_HOME% 并让它指向你的目录。<br>2. 下载安装Tomcat5.0.x<br>3. 创建 /conf/Catalina/localhost/liferay.xml<br>&lt;Context path="" docBase="../liferay" debug="0" reloadable="true" crossContext="true"&gt;<br>&nbsp;&lt;Resource name="jdbc/LiferayPool" auth="Container" type="javax.sql.DataSource" /&gt;<br>&nbsp;&lt;ResourceParams name="jdbc/LiferayPool"&gt;<br>&nbsp;&nbsp;&lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&lt;name&gt;driverClassName&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/parameter&gt;<br>&nbsp;&nbsp;&lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&lt;name&gt;url&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;jdbc:hsqldb:test&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/parameter&gt;<br>&nbsp;&nbsp;&lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&lt;name&gt;username&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;sa&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/parameter&gt;<br>&nbsp;&nbsp;&lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&lt;name&gt;password&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/parameter&gt;<br>&nbsp;&nbsp;&lt;parameter&gt; <br>&nbsp;&nbsp;&nbsp;&lt;name&gt;maxActive&lt;/name&gt; <br>&nbsp;&nbsp;&nbsp;&lt;value&gt;20&lt;/value&gt; <br>&nbsp;&nbsp;&lt;/parameter&gt;<br>&nbsp;&lt;/ResourceParams&gt;<br>&nbsp;&lt;Resource name="mail/MailSession" auth="Container" type="javax.mail.Session" /&gt;<br>&nbsp;&lt;ResourceParams name="mail/MailSession"&gt;<br>&nbsp;&nbsp;&lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&lt;name&gt;mail.smtp.host&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&lt;value&gt;localhost&lt;/value&gt;<br>&nbsp;&nbsp;&lt;/parameter&gt;<br>&nbsp;&lt;/ResourceParams&gt;<br>&nbsp;&lt;Realm<br>&nbsp;&nbsp;className="org.apache.catalina.realm.JAASRealm"<br>&nbsp;&nbsp;appName="PortalRealm"<br>&nbsp;&nbsp;userClassNames="com.liferay.portal.jaas.PortalPrincipal"<br>&nbsp;&nbsp;roleClassNames="com.liferay.portal.jaas.PortalRole"<br>&nbsp;&nbsp;debug="99"<br>&nbsp;&nbsp;useContextClassLoader="false"<br>&nbsp;/&gt;<br>&lt;/Context&gt;<br>4. 下载 liferay-portal-pro-3.6.1.war。<br>5. 编辑 /conf/catalina.properties。<br>common.loader=<br>&nbsp;&nbsp;&nbsp; ${catalina.home}/common/classes,\<br>&nbsp;&nbsp;&nbsp; ...\在这段最后加入<br>&nbsp;&nbsp;&nbsp; ${catalina.home}/common/lib/ext/*.jar<br>6. 创建/conf/Catalina/localhost/tunnel.xml。<br>&lt;Context path="/tunnel"&gt;<br>&nbsp;&lt;Realm<br>&nbsp;&nbsp;className="org.apache.catalina.realm.JAASRealm"<br>&nbsp;&nbsp;appName="PortalRealm"<br>&nbsp;&nbsp;userClassNames="com.liferay.portal.jaas.PortalPrincipal"<br>&nbsp;&nbsp;roleClassNames="com.liferay.portal.jaas.PortalRole"<br>&nbsp;&nbsp;debug="99"<br>&nbsp;&nbsp;useContextClassLoader="false"<br>&nbsp;/&gt;<br>&lt;/Context&gt;<br>7. 创建/conf/jaas.config。<br>PortalRealm {<br>&nbsp;&nbsp;&nbsp; com.liferay.portal.jaas.PortalLoginModule required;};<br>8. 编辑/bin/catalina.bat<br>在rem ----- Execute...中加入：</font>
<p><font size=2>set JAVA_OPTS=%JAVA_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config<br>9. 解压liferay-portal-pro-3.6.1.war：创建到%CATALINA_HOME%/liferay目录地下（%CATALINA_HOME%为任意目录，最好不带中文）<br>10. 移动%CATALINA_HOME%/liferay/WEB-INF/lib 下除util-taglib.jar之外的所有.jar包放入/common/lib/ext。<br>11. 启动Tomcat，在浏览器地址栏上输入</font><a href="http://localhost/"><font color=#0066cc size=2><u>http://localhost</u></font></a><font size=2>就能看见登录界面，用户名输入：</font><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#116;&#101;&#115;&#116;&#64;&#108;&#105;&#102;&#101;&#114;&#97;&#121;&#46;&#99;&#111;&#109;"><font color=#0066cc size=2><u>test@liferay.com</u></font></a><font size=2>,密码：test.</font></p>
<p><font size=2>疑难：<br>1. 此方法只适应Tomcat5.0.x 和 jdk1.4.2，其他版本搭配，并不一定使用；<br>2. liferay-portal-pro-3.6.1.war用WinRAR解压即可；<br>3. 在安装Tomcat时应注意，不要让别的程序占用了8080端口，如果占用，可以在安装的时候修改端口，也可以修改<br>/conf/server.xml，使port="8082"或其他端口。<br>&nbsp;&nbsp;&nbsp; &lt;Connector&nbsp;<br>port="8080"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" redirectPort="8443" acceptCount="100"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; debug="0" connectionTimeout="20000" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; disableUploadTimeout="true" /&gt;<br>4.安装完毕，打开地址时可能报 java.lang.OutOfMemoryError，设置JVM的内存为-Xmx512m。<br>附原安装文件：</font></p>
<p><font size=2>Tomcat 5.0.x/5.5.x</font></p>
<p><font size=2>Expert</font></p>
<p><br><font size=2>Download and install JDK 1.4.2 . Set an environment variable</font></p>
<p><font size=2>If you are using Tomcat 5.5.x, you must download and install<br>JDK 5.</font></p>
<p><font size=2>Download and install Tomcat.</font></p>
<p><font size=2>You can download Tomcat 5.0.x or&nbsp;Tomcat 5.5.x. This<br>documentation assumes that you are using Tomcat<br>5.0.x but will also give special instructions for&nbsp;usage with<br>Tomcat 5.5.x.</font></p>
<p><font size=2>Create /conf/Catalina/localhost/liferay.xml to set up the<br>portal web application.</font></p>
<p><font size=2>&lt;Context<br>&nbsp;&nbsp;&nbsp; path=""<br>&nbsp;&nbsp;&nbsp; docBase="../liferay"<br>&nbsp;&nbsp;&nbsp; debug="0"<br>&nbsp;&nbsp;&nbsp; reloadable="true"<br>&nbsp;&nbsp;&nbsp; crossContext="true"&gt;<br>&lt;/Context&gt;</font></p>
<p><font size=2>For&nbsp;Tomcat 5.5.x, edit /conf/Catalina/localhost/ROOT.xml.<br>You must also remove the reference to<br>path="" in the XML.</font></p>
<p><font size=2>Download liferay-portal-pro-3.6.1.war.</font></p>
<p><font size=2>Populate your database with the portal schema and default<br>data.</font></p>
<p><br><font size=2>Edit /conf/catalina.properties.</font></p>
<p><br><font size=2>common.loader=<br>&nbsp;&nbsp;&nbsp; ${catalina.home}/common/classes,\<br>&nbsp;&nbsp;&nbsp; ...\<br>&nbsp;&nbsp;&nbsp; ${catalina.home}/common/lib/ext/*.jar</font></p>
<p><br><font size=2>Configure data sources for&nbsp;your database. Make sure the JDBC<br>driver for&nbsp;your database is accessible by Tomcat.</font></p>
<p><br><font size=2>Create a mail session bound to mail/MailSession. You only<br>need to set the locations of the IMAP, POP3,<br>and SMTP servers.</font></p>
<p><br><font size=2>Edit /conf/Catalina/localhost/liferay.xml and configure a<br>mail session. For&nbsp;Tomcat 5.5.x, edit<br>/conf/Catalina/localhost/ROOT.xml.</font></p>
<p><br><font size=2>&lt;Context...&gt;<br>&nbsp;&nbsp;&nbsp; &lt;Resource<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="mail/MailSession"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; auth="Container"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="javax.mail.Session"<br>&nbsp;&nbsp;&nbsp; /&gt;<br>&nbsp;&nbsp;&nbsp; &lt;ResourceParams name="mail/MailSession"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;mail.store.protocol&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;imap&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;mail.transport.protocol&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;smtp&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;mail.imap.host&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;localhost&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;mail.pop3.host&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;localhost&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parameter&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;mail.smtp.host&lt;/name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;localhost&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/parameter&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/ResourceParams&gt;<br>&lt;/Context&gt;</font></p>
<p><br><font size=2>Configure JAAS.</font></p>
<p><font size=2>Edit /conf/Catalina/localhost/liferay.xml and configure a<br>security realm. For&nbsp;Tomcat 5.5.x, edit<br>/conf/Catalina/localhost/ROOT.xml.</font></p>
<p><br><font size=2>&lt;Context...&gt;<br>&nbsp;&nbsp;&nbsp; &lt;Realm<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; className="org.apache.catalina.realm.JAASRealm"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appName="PortalRealm"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>userClassNames="com.liferay.portal.jaas.PortalPrincipal"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; roleClassNames="com.liferay.portal.jaas.PortalRole"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; debug="99"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useContextClassLoader="false"<br>&nbsp;&nbsp;&nbsp; /&gt;<br>&lt;/Context&gt;</font></p>
<p><font size=2>Repeat this step for&nbsp;a file called<br>/conf/Catalina/localhost/tunnel.xml if you want to enable<br>Liferay's<br>HTTP tunneling.</font></p>
<p><font size=2>Create /conf/jaas.config.</font></p>
<p><br><font size=2>PortalRealm {<br>&nbsp;&nbsp;&nbsp; com.liferay.portal.jaas.PortalLoginModule required;};</font></p>
<p><font size=2>Edit /bin/catalina.bat so that Tomcat can reference the<br>login module.</font></p>
<p><br><font size=2>...</font></p>
<p><font size=2>rem ----- Execute...</font></p>
<p><font size=2>set JAVA_OPTS=%JAVA_OPTS%<br>-Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.<br>config</font></p>
<p><br><font size=2>Deploy liferay-portal-pro-3.6.1.war.</font></p>
<p><br><font size=2>Unpack liferay-portal-pro-3.6.1.war to<br>%CATALINA_HOME%/liferay.</font></p>
<p><font size=2>Move every jar except util-taglib.jar from<br>%CATALINA_HOME%/liferay/WEB-INF/lib to /common/lib/ext.<br>This step is only necessary if you plan to hot deploy<br>portlet WARs.</font></p>
<p><br><font size=2>Start Tomcat.</font></p>
<p><font size=2>If you get a java.lang.OutOfMemoryError&nbsp;exception while<br>starting up Tomcat, give your JVM more memory<br>by setting -Xmx512m.</font></p>
<p><br><font size=2>Open your browser to </font><a href="http://localhost/"><font color=#0066cc size=2><u>http://localhost</u></font></a><font size=2>. Click on My Liferay<br>at the upper right hand corner to enter the<br>login screen. Your login is </font><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#116;&#101;&#115;&#116;&#64;&#108;&#105;&#102;&#101;&#114;&#97;&#121;&#46;&#99;&#111;&#109;"><font color=#0066cc size=2><u>test@liferay.com</u></font></a><font size=2> and your<br>password is test.<br></font></p>
<img src ="http://www.blogjava.net/junky/aggbug/120396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-28 10:00 <a href="http://www.blogjava.net/junky/archive/2007/05/28/120396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Portal Framework介绍（第一部分）</title><link>http://www.blogjava.net/junky/archive/2007/05/28/120394.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Mon, 28 May 2007 01:59:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/05/28/120394.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/120394.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/05/28/120394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/120394.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/120394.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 目 录&nbsp;&nbsp;1 概述... 32 基本概念... 32.1 Portal定义... 32.2 Portlet定义... 42.3 Portal页面的元素... 52.4 Portlet生命周期... 62.5 Portlet标签库... 72.6 JSR168和WSRP. 73 Portal的功能... 84 部分开源Portal框...&nbsp;&nbsp;<a href='http://www.blogjava.net/junky/archive/2007/05/28/120394.html'>阅读全文</a><img src ="http://www.blogjava.net/junky/aggbug/120394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-05-28 09:59 <a href="http://www.blogjava.net/junky/archive/2007/05/28/120394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>