??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久亚洲AV成人无码,亚洲国产成人高清在线观看 ,国产亚洲?V无码?V男人的天堂http://www.tkk7.com/junky/category/22839.htmlzh-cnFri, 15 Jun 2007 04:31:35 GMTFri, 15 Jun 2007 04:31:35 GMT60Lq行Java Portlets--开发基于JSR 168的开发和部v(?http://www.tkk7.com/junky/archive/2007/06/15/124442.htmljunkyjunkyFri, 15 Jun 2007 02:39:00 GMThttp://www.tkk7.com/junky/archive/2007/06/15/124442.htmlhttp://www.tkk7.com/junky/comments/124442.htmlhttp://www.tkk7.com/junky/archive/2007/06/15/124442.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/124442.htmlhttp://www.tkk7.com/junky/services/trackbacks/124442.htmlPrakash Malani


  Portlet是生成片D(遵守特定规范的标记语aQ如HTML、XMLQ的片段Q的Weblg。片D再合成一个完整的文档。本文介l了关于Java Portlet的Java Specification Request (JSR) 168规范。它说明了如何用BEA WebLogic Workshop 8.1 SP2来创建Java PortletQ以及如何将q些portlet部v到BEA WebLogic Portal 8.1 Sp2上。我介l一些关键概念,如门戗桌面和portletQƈ详细描述多种portlet模式和窗口状态。我q将介绍如何使用Workshop来设计、实现、配|和执行portlet?br>

  JSR 168定义了有关Java Portlet的规范。门h一个Web应用E序和一个portlet的聚合。Portlet容器q行portletQƈ理它们的生命周期。JSR 168定义了portlet与portlet容器之间的契U,它没有定义portlet容器与门户之间的契约。门L实现留给了门户供应商?br>
  BEA WebLogic门户
  BEA WebLogic Portal (8.1 SP2)的当前版本支持不同类型的portletQJSP/HTML portlet、Java PageFlow portlet、Struts portlet和Java portletQ将来还会支持其他portletQ如Web Services for Remote Portlets (WSRP)。我们将着重介lJava portlet?br>
  WebLogic Portal提供了JSR 168中未描述的门户功能,包括但不限于Q书和页面中portlet的组l、多渠道支持和用skin、skeleton和shell定制?br>
  Z能够l箋下去Q在q行下一部分之前Q请先完成以下内容:
   ·使用WebLogic Domain Configuration Wizard创徏一个门户域Q如JSR168PortalDomainQ?
   ·使用WebLogic Workshop创徏一个用上面所建立域的门户应用E序Q如JSR168PortalAppQ?
   ·在门户应用程序内创徏一个门户Web目Q如JSR168PortalWebProjectQ?
   ·在门户Web目中创Z个WebLogic Portal .portal文gQ如JSR168.portalQ?
   ·启动服务器实例?

  创徏您的W一个Java Portlet
  下面的步骤描qC如何创徏您的W一个JSR 168 portlet?br>  ·在门户Web目Q如JSR168PortalWebProjectQ中Q用WebLogic Workshop为portletQ入FirstPortletQ创Z个新文g夏V?
  ·在新文g夹内使用Wizard通过创徏相应?portlet文g创徏一个新portletQ如FirstportletQ?br>  ·选择portletcd为Java Portlet?
  ·指定标题Q如FirstQ?
  ·指定定义标签Q如firstQ?br>  ·指定cdUͼ如com.malani.examples.portlets.jsr168.FirstPortletQ?
  ·打开门户Q如JSR168.portalQ?
  ·portletQ如FirstportletQ拖攑ֈ门户中的面上(如JSR168.portalQ?
  ·q行.portal文gq行试?

  您的W一个JSR 168 portlet已经成功q行了!但向导在背后作了些什么呢Q?br>  ·它创Z一个特定于WebLogic Workshop和WebLogic Portal?portlet文g?portlet文g构成了与特定于Workshop和WebLogic Portal?portal文g的契U?
  ·向导创徏了一?java文gQ如com.malani.examples.portlets.jsr168.FirstPortlet.javaQ,该文件放|在WEB-INF/src目录中?br>  ·向导创徏了一个WEB-INF/portlet.xml配置文gQƈ为portlet在文件中插入了一个条目。该portlet的条目看上去如下Q?br>
<portlet>
<description>Description goes here</description>
<portlet-name>first</portlet-name>
<portlet-class>com.malani.examples.portlets.jsr168.FirstPortlet
</portlet-class>
<portlet-info>
<title>First</title>
</portlet-info>
</portlet>


  Java Portletc?/strong>
  在该CZ中,向导生成的Portlet Java文g扩展了javax.portlet.GenericPortletcRGenericPortletcdCjavax.portlet.Portlet接口。图1是一个Unified Modeling Language (UML)cdQ描qCq些关系。通过直接实现portlet接口Q可以编写一个portlet。然而,GenericPortlet是一个创建portlet的更方便Ҏ。首先,我们看一下portlet生命周期、portlet模式和window状态?


?1

  Portlet生命周期
  Z成功地创建portletQ您必须늅portlet生命周期。javax.portlet.Portlet接口中的Ҏ定义了该生命周期Q这些生命周期方法是init()、render()、processAction()和destroy()。当部vportlet的实例时调用init()Ҏ。它用于获得所需的Q何昂贵资源(如后台连接)Qƈ执行其他一ơ性活动。当portlet的实例被撤销部vӞ使用destroy()Ҏ来释放这些资源?br>
  Portlet规范清晰区别renderh和动作请求。图2描述了portleth和响应的一个UMLcd。门户页面上的renderh会导致对所面上的每个portlet上调用render()ҎQ当用户在特定portlet上调用某个动作(通常是HTML表单提交Q时Q将会调用该portlet的processAction()Ҏ。这P用户的动作请求{换ؓprocessAction()Ҏ的一ơ调用和render()Ҏ的多ơ调用?/p>


?2

  ?是一个序列图Q说明了调用processAction()Ҏ的效果,以及为同一面上的portletq行后箋render()Ҏ的调用。关于更多信息,请参阅关于处理动作的一节?/p>


?3

  有两U重载的init()ҎQ一个没有参敎ͼ另一个有一个javax.portlet.PortletConfigcȝ实例。注意:关于init(PortletConfig)有一个特D的caveat。调用super.init(aPortletConfig)p|导致一个NullPointerException。所包含的源代码CZ中的Init portlet说明了这U行为(源代码可以在www.sys-con.com/weblogic/source.cfm中找刎ͼ?br>
  Portlet模式
  JSR 168定义了三UPortlet模式QVIEW、EDIT和HELP。一个portlet实例在Q何时候都可以恰y在一U portlet模式下。其他自定义portlet模式Q如配置和源Q都是可能的。VIEW模式是默认的模式。Portlet规范EDIT模式允许portlet用户定制portlet实例Q以及HELP模式昄关于portlet的用法信息。Portlet必须支持VIEW模式Q但在portlet中对EDIT模式和HELP模式的支持是可选的。例如,portlet First portletCZ不支持EDIT模式和HELP模式?br>
  window状?/strong>
  JSR 168定义了三UWindow状态:NORMAL、MINIMIZED和MAXIMIZED。Portlet实例M时候都可以恰好是一Uwindow状态。其他自定义window状态(如半)也是可能的。在NORMAL状态下Qportlet占了屏幕区的一部分。屏q状态与其他portlet׃n。在MINIMIZED状态下Qportlet的内容被隐藏。在MAXIMIZED状态下Qportlet的内容占屏幕区的大部分。其他共享同一面的portlet在MAXIMIZED状态下被隐藏。例如,portlet FirstCZ支持所有三Uwindow状态?br>
  GenericPortletc?/strong>
  您创建的大多数portlet会扩展javax.portlet.GenericPortletc,而不是直接实现javax.portlet.Portlet接口。GenericPortletcdCrender()Ҏ。如果portlet的window状态被最化Q那么render()Ҏ不能做Q何事情。如果portlet的window状态不是最化Q那么render()Ҏ讄在portlet.xml文g中指定的标题Qƈ调用doDispatch()Ҏ。根据Portlet模式Q?doDispatch()Ҏ适当地调用doView()、doEdit()和doHelp()Ҏ。这P׃GenericPortletcd助实现render()ҎQƈ且提供doView()、doEdit()和doHelp()Ҏ来覆盖,因此GenericPortletcLPortlet接口更便于扩展?

  考虑一下First portletCZ。FirstPortletcL展了GenericPortletQFirstPortlet改写了doView()Ҏ?br>
public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
response.getWriter().write("<p>Hello World</p>");
}


  注意Q调用setContentType()Ҏ前调用getWriter()Ҏ会导致java.lang.IllegalStateException?br>
  实现Portlet模式
  VIEW模式是强制的Q但EDIT和HELP模式是可选的。ؓ了实现EDIT和HELP portlet模式Q需要在portletcM实现适当的doEdit()和doHelp()Ҏ。请参考包含在源代码示例(本文的源代码可以在www.sys-con.com/wldj/sourcec.cfm扑ֈQ中的portlet Mode。此外,必须在portlet.xml中如下配|各模式Q?br>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>edit</portlet-mode>
<portlet-mode>help</portlet-mode>
</supports>


  注意Q修改portlet.xml配置文gQ但不实现portletcM的相应方法,会导致javax.portlet.PortletException?br>
  实现window状?/strong>
  JSR 168没有描述用window状态支持的Ҏ。然而,WebLogic Portal实现了对它们的禁用。ؓ了禁用portlet对window状态的支持Q需要在weblogic-portlet.xml文g中排除window状态:

<portlet>
<portlet-name>state</portlet-name>
<supports>
<mime-type>text/html</mime-type>
<excluded-window-state>minimized</excluded-window-state>
<excluded-window-state>maximized</excluded-window-state>
</supports>
</portlet>


  请参考源代码CZ中的portlet State?br>
  包含JavaServer Pages (JSPs)
  考虑portlet First的doView()ҎQ该Ҏ获得了Writer的实例,q直接输出HTML片段。由于多U原因(如ؓ了达到Java逻辑与HTML视图表现的分)Q往往不推荐输出直接的HTML片段。推荐的Ҏ是用JSP来显C图。portletcM的方法执行业务逻辑、设|render参数以及包含JSP。ؓ了包含一个特定的JSPQ应首先获得PortletContext。从PortletContext实例中,通过调用getRequestDispatcher()Ҏ获得一个PortletRequestDispatcher的实例。通过调用include()Ҏ来包含JSP。例如:

// execute the necessary logic here...
PortletRequestDispatcher aDispatcher =
getPortletContext().getRequestDispatcher(
"/IncludePortlet/includeView.jsp"
);
aDispatcher.include(aRequest, aResponse);


  注意Q在执行render()ҎӞportlet可能只用一个PortletRequestDispatcher对象?br>  请参考包含在源代码中的portlet Include。JSP面Q如includeView.jspQ不包含根HTML标签Q如<html>?lt;title>?lt;body>Q,因ؓq些标签由门h架提供。JSP面只包含显Cportlet所必需的HTML片段?br>
  处理动作
  在一个标准的Web应用E序中,一个HTML表单提交导致执行一些业务逻辑。业务处理的l果Q要么作为属性而被讄在请求或会话中ƈ转发Q要么包含到下一个JSP?br>
  在一个JSR 168 portlet中,一个HTML表单的动作URL应该是什么样呢?JSR 168定义了一个JSP标签库,UCؓportlet taglib。HTML表单的动作URL可以使用actionURL portlet标签生成。例如(请参考favoriteColorEdit.jsp文gQ:

<form action="<portlet:actionURL/>" method="post">
...
</form>


  提交该HTML表单会D调用portlet的processAction(ActionRequest aRequest, ActionResponse aResponse)Ҏ。像通常一P可以通过调用request对象的getParameter()Ҏ来获得表单参数。注意:通过提交表单调用动作Q但portlet中却没有processAction()ҎQ将会导致javax.portlet.PortletException?br>
  processAction()Ҏ讄response对象中的倹{不要用ActionRequest或ActionResponse对象的setAttribute()Ҏ。g会从processAction()传递到render()ҎQ而且在JSP中是不可用的。相反要使用ActionResponse对象的setRenderParameter()Ҏ。这些render参数对所有后lrenderh可用Q这一点与典型的Web应用E序h属性很不相同。典型的Web applicationh属性只对于一个请求可用。另一斚wQrenderh参数对于许多后箋renderh可用。render参数保持可用直到D动作的重新执行显式地修改或删除?br>
  考虑portlet FavoriteColor。它在VIEW模式昄了一个用户偏好的颜色Q但是可以在EDIT模式下更攏V在EDIT模式下提交偏好的颜色选择调用processAction()Ҏ。该Ҏ获得偏好的颜色请求参敎ͼq将其设|ؓrender参数。这P偏好的的颜色render参数在所有后lrenderh中都可用?br>
  所呈现的参数是怎样昄在JSP上的呢?应用来自portlet标签库的defineObjects标签来定义portlet对象。该标签使renderRequest、renderResponse和portletConfig portlet对象在页面中可用。参数通过调用renderRequest对象的getParameter()Ҏ来显C。请参考与所包含的源代码CZ中的favoriteColorView.jsp?br>
  portlet FavoriteColor也展CZ其他概念。第一个是如何在processAction()Ҏ中用~程的方法改变portlet模式。调用ActionResponse对象的setPortletMode()Ҏ来修改portlet模式。第二个概念是如何用一个HTML链接来修改portlet模式。该链接使用来自portlet标签库的renderURL标签生成。根据希望的portlet模式指定portletMode属性的倹{请参考源代码CZ中的FavoriteColorPortletcdfavoriteColorView.jsp面?

  Portlet Preferences
  Portlet PreferencesQPortlet首选项Q是portlet的基本配|数据。一个preference是一?#8220;名称和?#8221;寏V名U的cd是一个字W串Q而值的cd是字W串或字W串数组。Portlet Preference不适于存储L数据。portlet容器为portlet preferences提供持久性。在WebLogic Portal中,preference的持久性只在下面两个条仉为真时才起作用:
  ·门户q行在桌面中Q而不是DOT门户模式?br>  ·用户已经d?br>
  桌面与DOT门户模式
  在WebLogic Workshop中创?portal文gӞ像书、页面和portlet{项都可以被拖放?portal文g中,.portal文g能够直接从Workshop内运行。然而,某些功能Q如preferences的存储,在这UDOT门户模式下运行时是不可用的(DOT门户模式也称为单文g模式QSingle File ModeQ)?

  其他模式UCؓ桌面模式。创Z个门h使用Portal Administrator。在门户内,一个桌面被创徏。像图书、页面和portlet{项被创建,q放|在桌面中。在q种模式下,某些功能Q像preferences的存储,是可用的Q桌面模式也被称为流模式QStreamed ModeQ)?br>
在l讨论前Q先创徏一个桌面:
  启动Portal AdministrationQ譬如,http://localhost:7001/JSR168PortalAppAdmin/Q。一U启动Portal Administration的方法是直接从Workshop中启动。选择Portal菜单Q选中Portal Administration菜单V?
  ·dqPortal Administration?br>  ·创徏一个新门户Q譬如,JSR168Q?
  ·在门户中Q创Z个新桌面Q如d1Q?
  ·LoginPortletd到桌面的一个页面中?
  ·ContactPortletd到桌面的一个文件中?

  Portlet PreferencesCZ
  Contact portlet演示了Portlet Preferences。Portlet Preferences可以是静态的或动态的。静?preferences与portlet一起在portal.xml文g中指定。例如,ContactPortleth一个成为contact-preference?preferences。contact-preference的默认g被指定:

<portlet-preferences>
<preference>
<name>contact-preference</name>
<value>Email</value>
</preference>
</portlet-preferences>


  动?preferences不在portlet.xml配置文g中预定义。当portletq行Ӟq些preferences被存储和d。在q行期间Q一个javax.portlet.PortletPreferences接口的实例包含这些preferences。该实例通过调用PortletRequest对象的getPreferences()Ҏ获得。特定preferences的值通过调用preferences实例上的getValue()Ҏ来获得?

  调用preferences实例的setValue()Ҏ会更C个preferences倹{然而,需要一个额外的步骤来提交这些修攏Vpreferences实例的store()Ҏ被调用来使preferences持久化。preferences只能在processAction()Ҏ中进行修攏V如果在processAction()Ҏ中没有调用store()ҎQQ何对preferences实例的修攚w会被丢弃。注意:如前面提到的,如果用户没有d或门户处于DOT门户模式Q那么调用store()Ҏ会D一个运行时异常?br>
  在portlet和servlet之间有很多相似点。然而,它们也存在着重要区别。portlet规范建立在servlet规范之上。portlet容器存在于servlet容器中。就像servlet部v在一个Web应用E序中,portlet也是如此。Servlet和Web应用E序使用portlet.xml文gq行配置。一个servleth昑ּ的生命周期:init()、doGet()、doPost(){。类似地Q一个portlet也具有显式的生命周期QdoView()、doEdit()、processAction(){。servlet和portletcȝҎ必须以安全线E的方式~码?br>
  然而,也存在着重要的区别。Servlet被允许进行include、forward和redirect操作Q然而portlet只被允许q行include操作。Servlet能够呈现一个完整的面Q但portlet只提交页面片Dcportleth严格定义的portlet模式和Window状态,q方面不像servlet。Portleth更正式的hQ对renderh和动作请求进行处理,它们也具有preferences。portletq不是servletQ?br>
  l束?/strong>
  本文通过使用一个简单的向导描述portlet的创开始,q说明了portlet的生命周期以及portletcd现的内部工作方式Q描qCportlet.xml配置文g和相应的weblogic-portlet.xml配置文g的结构和语义。对各种概念Q如portlet模式和window状态,本文也进行了解释。本文演CZportlet标签库的用法和portlet中的表单处理。最后,我介l了如何使用portletpreferences。理解了本文所介绍的这些知识和概念Q您可以在创徏和部|自q强大portlet的道路上前进了?br>
  致谢
  感谢Subbu Allamaraju、Max Cooper、Steve Ditlinger、David Lu、Roshni Malani和Alex ToussaintQ他们仔l阅Mq篇文章Qƈ提供了有价值的反馈意见?br>
  参考资?/strong>
  · 要讨文章、ƈ提问问题Q从q里开始: www.bartssandbox.com。需要免Ҏ员资根{?
  · 下蝲、阅读JSR 168Q?a target=_blank>www.jcp.org/en/jsr/detail?id=168
  · WebLogic Portal文档的v始点Q?a target=_blank>e-docs.bea.com/wlp/docs81/index.html
  · 建立Workshop Help的Java Portlet部分Q?a target=_blank>e-docs.bea.com/workshop/docs81/doc/en/core/index.html
  · 用WebLogic Portal 8.1开发JSR 168 PortletQ?a target=_blank>dev2dev.bea.com/products/wlportal81/articles/JSR168.jsp
  · Web Services for Remote Portlets (WSRP)规范Q?a target=_blank>www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
  · 试一下WSRPQ?a target=_blank>dev2dev.bea.com/codelibrary/code/wsrp_supportkit.jsp
  · Single File Mode和Streamed Rendering ModeQ?a target=_blank>单击q里Q?br>  · 有关Portlet规范上的文章Q?br>- 介绍Portlet规范Q第1部分Q?br>www.javaworld.com/javaworld/jw-08-2003/jw-0801-portlet_p.html
-介绍Portlet规范Q第2部分Q?br>www.javaworld.com/javaworld/jw-09-2003/jw-0905-portlet2_p.html
  · 对JSR 168白皮书的介绍Q单击这里!
  · Java Passion Portlet演讲W记Q?a target=_blank>www.javapassion.com/j2eeadvanced/Portlet4.pdf

  源代?/strong>
  源代?Zip文g
  英文原文Q?a target=_blank>http://www.sys-con.com/story/?storyid=45565&DE=1

 作者简?/span>
icon
Prakash Malani
Prakash Malani 在架构、设计和开发Y件方面经验丰富。他在许多应用领域从事过软g开发,比如׃、金融、零售、医学、通信和交互式电视。他喜欢实践和研I先q的技术,比如Java 2 Enterprise Edition (J2EE)、Unified Modeling Language (UML)和eXtensible Markup Language (XML)。他q在加利尼亚州立理工大学L莫那校区{机构讲授最佛_践和设计模式。他在业界的著名出版物上发表q许多文章,比如JavaWorld和WebLogic Developers Journal。当前,他正在帮助组lLos Angeles BEA Users Group (LABEAUG)?/td>
dot dot dot

dot
  作者其它文?/span>

junky 2007-06-15 10:39 发表评论
]]>
liferay权限开发(一Q?/title><link>http://www.tkk7.com/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.tkk7.com/junky/archive/2007/06/06/122347.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/122347.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2007/06/06/122347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/122347.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/122347.html</trackback:ping><description><![CDATA[<p><span>HOWTO</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span>liferay</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>权限开发(一Q?/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>首先Q我们来看看l自q</span><span>portlet</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>加上权限控制Q主要要完成以下四步操作Q?/span><span>DRAC</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span>:</span></p> <p align=left><span>1.</span><span> Define all resources and their permissions.</span></p> <p><span>先定义所有所需要的权限Q包?/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??>Q?/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 “adding resources.”</span></p> <p><span>当定义完权限后,我们需要把权限的定义注册到权限pȝ中,x权限相关信息保存到数据库?/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> </p> <p><span>在解析上面四个步骤以前,有两个定义是非常重要的:</span></p> <p><span><span>1Q?span>               </span></span></span><span>Resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q在</span><span>portal</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>pȝ中,可以单的认ؓ</span><span>Resource</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>是一个个可以操作的实体对象。D个例子:一?/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??>Q如Q?/span><span>Message Boards</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span>Calendar</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span> etc</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q,</span><span>java</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>c(如:</span><span>Message Board Topics</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span>Calendar Events</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span> etc</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q还?/span><span>flies</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q如Q?/span><span>documents</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span>images</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span><span>etc</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q?/span></p> <p><span><span>2Q?span>               </span></span></span><span>Permission</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>Q一个个可运行的权限动作Q都已经?/span><span>resourcez</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>中定义了。D个例子:“查看</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??>”q个权限动作已经通过</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??>的权限系l中定义</span></p> <p> </p> <p><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>下面来简单解析一下开发权限的四个步骤Q?/span></p> <p align=left><span>一Q?/span><strong><span>Defining Resources and Actions</span></strong></p> <p align=left><span><span>       </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??>文g?/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><</span><span>resource-action-mapping</span><span>></span><span>  </span></span> <li><span>  </span> <li><span>    </span><span><</span><span>portlet-resource</span><span>></span><span>  </span> <li><span>  </span> <li><span>       </span><span><</span><span>portlet-name</span><span>></span><span>8</span><span><span>portlet-name</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>supports</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>ADD_EVENT</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>CONFIGURATION</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>supports</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>community-defaults</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>        </span><span><span>community-defaults</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>guest-defaults</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>guest-defaults</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>guest-unsupported</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>ADD_EVENT</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>guest-unsupported</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>    </span><span><span>portlet-resource</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>    </span><span><</span><span>model-resource</span><span>></span><span>  </span> <li><span>  </span> <li><span>       </span><span><</span><span>model-name</span><span>></span><span>com.liferay.portlet.calendar.model.CalEvent</span><span><span>model-name</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>portlet-ref</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>portlet-name</span><span>></span><span>8</span><span><span>portlet-name</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>portlet-ref</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>supports</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>DELETE</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>PERMISSIONS</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>UPDATE</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>        </span><span><span>supports</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>community-defaults</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>community-defaults</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>guest-defaults</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>guest-defaults</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><</span><span>guest-unsupported</span><span>></span><span>  </span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>UPDATE</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>       </span><span><span>guest-unsupported</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span>    </span><span><span>model-resource</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span><span>resource-action-mapping</span><span>></span><span>  </span> </span> <li><span>  </span> </li> </ol> </div> <p align=left> </p> <p align=left><span>首先Q我们的权限定义?/span><span>root Element</span><span>?/span><span Courier New?; mso-font-kerning: 0pt?><</span><span Courier New?; mso-font-kerning: 0pt?>resource-action-mapping</span><span Courier New?; mso-font-kerning: 0pt?>></span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>Q所有的权限定义都必d含在里面</span></p> <p align=left><span>接着Q我们可以看?/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?><</span><span Courier New?; mso-font-kerning: 0pt?>portlet-resource</span><span Courier New?; mso-font-kerning: 0pt?>></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?><</span><span Courier New?; mso-font-kerning: 0pt?>model-resource</span><span Courier New?; mso-font-kerning: 0pt?>></span><span mso-hansi-font-family: Courier New?; mso-font-kerning: 0pt; mso-bidi-font-family: ?Courier New??>两种Q?/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??>中定义的Q我们可以在q里看到Q?/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??>的查看,配置权限Q还有就是可以控制按钮一c设|的权限</span></p> <p align=left> </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><</span><span>community-defaults</span><span>></span><span>  </span></span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span><span>community-defaults</span><span>></span><span>  </span> </span></li> </ol> </div> <p align=left>q里告诉我们当一?span>community</span><span>拥有q个</span><span>portlet</span><span>的时候所h的权限?/span></p> <p align=left>  </p> <div> <div></div> <ol> <li><span><span><</span><span>guest-defaults</span><span>></span><span>  </span></span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>VIEW</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span><span>guest-defaults</span><span>></span><span>  </span> </span></li> </ol> </div> <p align=left> </p> <p align=left></p> <span>?/span><span>guest</span><span>用户可以看到q个</span><span>portlet</span><span>的时候默认具有的权限Q这里都为查看?/span> <p> </p> <p align=left>  </p> <div> <div></div> <ol> <li><span><span><</span><span>guest-unsupported</span><span>></span><span>  </span></span> <li><span>  </span> <li><span>           </span><span><</span><span>action-key</span><span>></span><span>ADD_EVENT</span><span><span>action-key</span><span>></span><span>  </span> </span> <li><span>  </span> <li><span><span>guest-unsupported</span><span>></span><span>  </span> </span></li> </ol> </div> <p align=left> </p> <p align=left></p> <span Times Roman?; mso-hansi-font-family: ?Times New Roman??>q里?/span><span>guest</span><span Times Roman?; mso-hansi-font-family: ?Times New Roman??>用户不提供的权限</span> <p> </p> <p align=left> </p> <p align=left><span>上面的这些设|的权限都可以在q行的时候修?/span></p> <p align=left> </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??>q类的定义,都已l在</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> </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> </p> <p align=left></p> <p> </p> <div>xml 代码</div> <div> <div></div> <ol> <li><span><span><</span><span>resource-action-mapping</span><span>></span><span>  </span></span> <li><span>  </span> <li><span>    </span><span><</span><span>resource</span> <span>file</span><span>=</span><span>"resource-actions/portal.xml"</span> <span>/></span><span>  </span> <li><span>  </span> <li><span>    </span><span><</span><span>resource</span> <span>file</span><span>=</span><span>"resource-actions/calendar.xml"</span> <span>/></span><span>  </span> <li><span>  </span> <li><span>    </span><span><</span><span>resource</span> <span>file</span><span>=</span><span>"resource-actions/communities.xml"</span> <span>/></span><span>  </span> <li><span>  </span> <li><span>    </span><span><</span><span>resource</span> <span>file</span><span>=</span><span>"resource-actions/imagegallery.xml"</span> <span>/></span><span>  </span> <li><span>  </span> <li><span>    </span><span><</span><span>resource</span> <span>file</span><span>=</span><span>"resource-actions/wiki.xml"</span> <span>/></span><span>  </span> <li><span>  </span> <li><span>    </span><span><</span><span>resource</span> <span>file</span><span>=</span><span>"emsp-resource-actions/default.xml"</span> <span>/></span><span>  </span> <li><span>  </span> <li><span><span>resource-action-mapping</span><span>></span><span>  </span> </span></li> </ol> </div> <p align=left> </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> </p> <p align=left><span>完成的上q工作后Q我们需要在</span><span>liferay</span><span>的权限系l中把这些信息注册到数据库中Q待l)</span></p> </span></span> <img src ="http://www.tkk7.com/junky/aggbug/122347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2007-06-06 13:50 <a href="http://www.tkk7.com/junky/archive/2007/06/06/122347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>liferay portlet配置文g介绍http://www.tkk7.com/junky/archive/2007/05/31/121151.htmljunkyjunkyThu, 31 May 2007 06:09:00 GMThttp://www.tkk7.com/junky/archive/2007/05/31/121151.htmlhttp://www.tkk7.com/junky/comments/121151.htmlhttp://www.tkk7.com/junky/archive/2007/05/31/121151.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/121151.htmlhttp://www.tkk7.com/junky/services/trackbacks/121151.html关键?   liferay 配置文g    

portlet.xml

portlet定义描述文gQ它描述portlet的类型,支持Mode, preferenes和role{,遵@JSR168标准实现Q以便于ULQ需要针Ҏ的做一些小改过Q?/font>

下面是一个简单的定义:

 〈portlet?br>  〈portlet-name??portlet-name?br>  〈display-name〉My Account?display-name?br>  ?-- portlet的实现类 --?br>  〈portlet-class〉com.liferay.portlet.StrutsPortlet?portlet-class?br>  〈init-param?br>   〈name〉view-action?name?br>   〈value?my_account/view?value?br>  ?init-param?br>  〈expiration-cache??expiration-cache?br>  〈supports?br>   〈mime-type〉text/html?mime-type?br>  ?supports?br>  〈resource-bundle〉com.liferay.portlet.StrutsResourceBundle?resource-bundle?br> ?portlet?/font>

在JSR168标准中,定义了view/edit/help三种模式Q?br>liferay对其q行了扩展,增加了config/about/preview/print{模式?/font>

liferay-portlet.xml

liferay的portlet定义描述文gQ是liferay对portlet.xml的扩展描qͼ允许我们对portlet的呈现、功能和行ؓq行更深入的定制?br>它与com.liferay.portal.model.Portletcd应,

下面是一个较l的liferay-portlet定义Q?br> 〈portlet?br>  〈portlet-name?9?portlet-name?br>                ?-- struts路径 --?br>  〈struts-path〉message_boards?struts-path?br>                ?-- 配置路径 --?br>  〈configuration-path?message_boards/edit_configuration?configuration-path?br>                ?-- lucene索引c?--?br>  〈indexer-class〉com.liferay.portlet.messageboards.util.Indexer?indexer-class?br>                ?-- url处理c?--?br>  〈portlet-url-class〉com.liferay.portlet.messageboards.MBFriendlyPortletURL?portlet-url-class?br>                ?-- 友好url插gc?--?br>  〈friendly-url-plugin-class〉com.liferay.portlet.messageboards.MBFriendlyURLPortletPlugin?friendly-url-plugin-class?nbsp;              
  〈preferences-unique-per-layout〉false?preferences-unique-per-layout?br>  〈use-default-template〉false?use-default-template?br>  〈restore-current-view〉false?restore-current-view?br>  〈private-request-attributes〉false?private-request-attributes?br> ?portlet?/font>

portletcM常用的属?

// strtus 路径Q对portlet的请求应该限制在q个路径?
private String _strutsPath; 

// 配置路径Q即action定义
private String _configurationPath;

// portlet实现c?br>private String _portletClass;

// lucene索引c?br>private String _indexerClass;

// schedulerc?br>private String _schedulerClass;

// portletURL处理c?br>private String _portletURLClass;

// friendURL插g
private String _friendlyURLPluginClass;

// 默认的preferences
private String _defaultPreferences;

// preferences的验证类
private String _prefsValidator;

// 是否实例化,为true时可d多个portlet到layout?br>private boolean _instanceable;

// 是否为系lportletQ?br>private boolean _system;

// 初始化参?br>private Map _initParams;

// portlet支持的模?br>private Map _portletModes;

// portlet支持的语a
private Set _supportedLocales;

// PortletInfo
private PortletInfo _portletInfo;

// 是否静态portlet, 静态portlet不能Ud.
private boolean _staticPortlet;

// 是否为开始的静态portlet.
private boolean _staticPortletStart;

portlet解析

 com.liferay.portal.service.impl.PortletLocalServiceImpl

 public void initEAR(String[] xmls) {
  String scpId = PortletServiceImpl.class.getName() + "." + _SHARED_KEY;

  Map portletsPool = (Map)SimpleCachePool.get(scpId);

  if (portletsPool == null) {
   portletsPool = CollectionFactory.getSyncHashMap();
   SimpleCachePool.put(scpId, portletsPool);
  }

  try {
   List servletURLPatterns = _readWebXML(xmls[4]);

   Set portletIds =
    _readPortletXML(xmls[0], portletsPool, servletURLPatterns);
   portletIds.addAll(
    _readPortletXML(xmls[1], portletsPool, servletURLPatterns));

   Set liferayPortletIds =
    _readLiferayPortletXML(xmls[2], portletsPool);
   liferayPortletIds.addAll(
    _readLiferayPortletXML(xmls[3], portletsPool));

   // Check for missing entries in liferay-portlet.xml
   // 查在liferay-portlet中丢qportlet实体...

   // Remove portlets that should not be included
   // Ud不应该包括的portlet实体...
  }
  catch (Exception e) {
   _log.error(StackTraceUtil.getStackTrace(e));
  }
 }

 // 解析portlet.xml
 private Set _readPortletXML(
   String servletContextName, String xml, Map portletsPool,
   List servletURLPatterns)
  throws DocumentException, IOException {

  Set portletIds = new HashSet();

  if (xml == null) {
   return portletIds;
  }

  SAXReader reader = SAXReaderFactory.getInstance();

  Document doc = reader.read(new StringReader(xml));

  Element root = doc.getRootElement();

  Set userAttributes = new HashSet();

  Iterator itr1 = root.elements("user-attribute").iterator();
  // 用户属性处?..

  itr1 = root.elements("portlet").iterator();

  while (itr1.hasNext()) {
   Element portlet = (Element)itr1.next();

   String portletId = portlet.elementText("portlet-name");

   if (servletContextName != null) {
    portletId =
     portletId + Portlet.WAR_SEPARATor + servletContextName;
   }

   portletId = PortalUtil.getJsSafePortletName(portletId);

   if (_log.isDebugEnabled()) {
    _log.debug("Reading portlet " + portletId);
   }

   portletIds.add(portletId);

   Portlet portletModel = (Portlet)portletsPool.get(portletId);

   if (portletModel == null) {
    portletModel = new Portlet(
     new PortletPK(portletId, _SHARED_KEY));

    portletsPool.put(portletId, portletModel);
   }

   if (servletContextName != null) {
    portletModel.setWARFile(true);
   }

   if (servletURLPatterns != null) {
    portletModel.setServletURLPatterns(servletURLPatterns);
   }

   portletModel.setPortletClass(portlet.elementText("portlet-class"));

   Iterator itr2 = portlet.elements("init-param").iterator();
   // 初始化参数处?..

   Element expirationCache = portlet.element("expiration-cache");
   // cacheq期处理...

   itr2 = portlet.elements("supports").iterator();
   // 支持模式处理...

   Set supportedLocales = portletModel.getSupportedLocales();
     // 支持语言处理...

     // 资源
   portletModel.setResourceBundle(
    portlet.elementText("resource-bundle"));

   Element portletInfo = portlet.element("portlet-info");
     // portlet-info处理...

   Element portletPreferences = portlet.element("portlet-preferences");
   // preferences处理...

 
   Set unlikedRoles = portletModel.getUnlinkedRoles();
   itr2 = portlet.elements("security-role-ref").iterator();
   // role处理...

   portletModel.getUserAttributes().addAll(userAttributes);
  }

  return portletIds;
 }

 // 解析liferay-portlet.xml
 private Set _readLiferayPortletXML(
   String servletContextName, String xml, Map portletsPool)
  throws DocumentException, IOException {

  Set liferayPortletIds = new HashSet();

  if (xml == null) {
   return liferayPortletIds;
  }

  SAXReader reader = SAXReaderFactory.getInstance();

  Document doc = reader.read(new StringReader(xml));

  Element root = doc.getRootElement();

  Map roleMappers = new HashMap();

  Iterator itr1 = root.elements("role-mapper").iterator();
  // role-mapper处理...

  Map customUserAttributes = new HashMap();

  itr1 = root.elements("custom-user-attribute").iterator();
  // 定制用户属性处?..

  Map friendlyURLPlugins = _getFriendlyURLPlugins();

  itr1 = root.elements("portlet").iterator();

  while (itr1.hasNext()) {
   Element portlet = (Element)itr1.next();

   String portletId = portlet.elementText("portlet-name");

   if (servletContextName != null) {
    portletId =
     portletId + Portlet.WAR_SEPARATor + servletContextName;
   }

   portletId = PortalUtil.getJsSafePortletName(portletId);

   if (_log.isDebugEnabled()) {
    _log.debug("Reading portlet extension " + portletId);
   }

   liferayPortletIds.add(portletId);

   Portlet portletModel = (Portlet)portletsPool.get(portletId);

   if (portletModel != null) {
    // 讄portlet属?..

    // 处理FriendURL插g
    portletModel.setFriendlyURLPluginClass(GetterUtil.getString(
     portlet.elementText("friendly-url-plugin-class"),
     portletModel.getFriendlyURLPluginClass()));

    if (Validator.isNull(
      portletModel.getFriendlyURLPluginClass())) {

     friendlyURLPlugins.remove(portletId);
    }
    else {
     friendlyURLPlugins.put(
      portletId, portletModel.getFriendlyURLPluginClass());
    }

    // l定role.
    portletModel.getRoleMappers().putAll(roleMappers);
    portletModel.linkRoles();

    portletModel.getCustomUserAttributes().putAll(
     customUserAttributes);
   }
  }

  return liferayPortletIds;
 }

从上面的代码可看出,liferayportlet的描q定义存储在一个Map?

liferay-display.xml

portlet的类别定义文Ӟ下面是一个简单的例子:

 〈category name="category.admin"?br>  〈portlet id="9" /?br>  〈portlet id="40" /?br>  〈portlet id="79" /?br>  〈portlet id="80" /?br> ?category?/font>

要注意的是,在portlet.xml/liferay-portlet.xml/liferay-display.xml三个文g中的portlet-name, portlet-id必须是一致的?/font>

liferay-layout-templates.xml

layout模板定义文g.

liferay-look-and-feel.xml

主题定义文g.

portlet的web.xml

如果以war的方式发布portletQ那么它的web.xml也要q行一些特定的说明,

下面是liferay中sample-jsp-portletCZ的web.xml:
〈web-app?br> 〈display-name〉sample-jsp-portlet?display-name?br> 〈context-param?br>  〈param-name〉company_id?param-name?br>  〈param-value〉liferay.com?param-value?br> ?context-param?br> 〈listener?br>  〈listener-class〉com.liferay.portal.kernel.servlet.PortletContextListener?listener-class?br> ?listener?br> 〈servlet?br>  〈servlet-name〉sample_jsp_portlet?servlet-name?br>  〈servlet-class〉com.liferay.portal.kernel.servlet.PortletServlet?servlet-class?br>  〈init-param?br>   〈param-name〉portlet-class?param-name?br>   〈param-value〉com.sample.jsp.portlet.JSPPortlet?param-value?br>  ?init-param?br>  〈load-on-startup??load-on-startup?br> ?servlet?br> 〈servlet-mapping?br>  〈servlet-name〉sample_jsp_portlet?servlet-name?br>  〈url-pattern?sample_jsp_portlet/*?url-pattern?br> ?servlet-mapping?br> 〈taglib?br>  〈taglib-uri〉http://java.sun.com/portlet?taglib-uri?br>  〈taglib-location?WEB-INF/tld/liferay-portlet.tld?taglib-location?br> ?taglib?br>?web-app?br>上面的listener是必ȝQ它用于通知liferayq行热部|?
portlet-class指定Portlet的实现类Q它必须遵@JSR168标准Q直接或间接的从javax.portlet.GenericPortletl承?br>
相关文章:

  • liferay中的囄处理
  • 使用liferay中的struts+tiles来开发portlet(一)
  • Liferay中外部war方式整合portlet的处理流E?/a>
  • liferay中layout的处?/a>


  • junky 2007-05-31 14:09 发表评论
    ]]>
    关于Liferay的配|文?—?ZStruts开发Portlethttp://www.tkk7.com/junky/archive/2007/05/31/121147.htmljunkyjunkyThu, 31 May 2007 06:00:00 GMThttp://www.tkk7.com/junky/archive/2007/05/31/121147.htmlhttp://www.tkk7.com/junky/comments/121147.htmlhttp://www.tkk7.com/junky/archive/2007/05/31/121147.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/121147.htmlhttp://www.tkk7.com/junky/services/trackbacks/121147.htmll合Liferay实例sample-struts-portletQ基于Struts开发Portlet一般具有以下配|文Ӟ
    • liferay-display.xml
    • liferay-portlet.xml
    • portlet.xml
    • struts-config.xml
    • tiles-defs.xml
    • web.xml


    Q?Qliferay-display.xml Q定义Portal 中Portlet 理的目录结构)
            配置在Portlet 的显C名Uͼ以及该portlet 在显C列表中所在的目录。值得注意的是该处q没有直接给出在Portlet 昄列表中的昄名字Q而是l出了Portlet IDQ根据在porlet.xml 中portlet ID与Name 的关联,可得到该Portlet 的显C名字?br>
            <display>
                <category name="category.test">
                    <portlet id="sample_struts_portlet" />
                </category>
            </display>

            效果Q?/span>dporlet 内容Ӟ也就是在点击“add content” Ӟ名叫sample_struts_portlet 的portlet 在目录中的test 下昄?br>
    Q?Qliferay-portlet.xml Q定义基于Liferay Portal 下的Portlet 的特有属性)
        该配|文件定义portlet 属性和角色Q该配置文g对基于JSR168?portlet.xml 的属性进行扩展?br>
            <liferay-portlet-app>
            <portlet>
                <!-- 配置portlet 名,该名应对应于liferay-display.xml ?/span>portlet 的id 属?-->
                <portlet-name>sample_struts_portlet</portlet-name>
                <!-- 配置portlet 的实现类Q该cd应该portlet 的请求,实现功能  -->
                <portlet-url-class>
                        com.liferay.portal.apache.bridges.struts.LiferayStrutsPortletURLImpl
                </portlet-url-class>

                <use-default-template>true</use-default-template>
                <restore-current-view>true</restore-current-view>
            </portlet>
            <!-- 配置该portlet 的角Ԍ以及角色的显C名字,角色名role-name 是由portlet.xml 中进行定?-->
            <role-mapper>
                <role-name>administrator</role-name>
                <role-link>Administrator</role-link>
            </role-mapper>
            <role-mapper>
                <role-name>guest</role-name>
                <role-link>Guest</role-link>
            </role-mapper>
            <role-mapper>
                <role-name>power-user</role-name>
                <role-link>Power User</role-link>
            </role-mapper>
            <role-mapper>
                <role-name>user</role-name>
                <role-link>User</role-link>
            </role-mapper>
        </liferay-portlet-app>

        效果Q?/span>该portlet ?span style="COLOR: rgb(0,0,0)">com.liferay.portal.apache.bridges.struts.LiferayStrutsPortletURLImpl cȝ实例q行处理Q允怋用模版和实时h面。可配置administratorQguestQpower-userQuser 四种角色对其拥有不同的权限?/span>

    Q?Qportlet.xml QPortlet 的标准属性,该配|文件中的各属性符合JSR168 标准Qƈ非Liferay专用Q?/span>
           该配|文件设|Portlet的各个属性,该各属性在Portlet初始化时得以加蝲?/span>

    <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">

        <portlet>
            <portlet-name>sample_struts_portlet</portlet-name>

           <!-- display-name 即ؓ该Portlet昄的名字,liferay-display.xml 中配|了Portlet  idQ关联该配置文g可找到其昄的名字,如下“Sample Struts Portlet" -->
            <display-name>Sample Struts Portlet</display-name>

          
    <!-- ׃在开发Portlet 时必ȝ承Portlet 的基c,而此处是ZStruts 开发Portlet 时可l承该类  -->
            <portlet-class>org.apache.portals.bridges.struts.StrutsPortlet</portlet-class>
           
          
    <!-- init-param 标签表示Portlet 的初始化参数 Q由name 标签?value 标签指明其名字和值的一Ҏ?-->
            <init-param>
                <name>ServletContextProvider</name>
               
    <!-- 其gؓ该Portlet 可接收响应的URL或者类QURL 对应的类是哪个由Struts-config.xml 定义-->
                <value>com.liferay.util.apache.bridges.struts.LiferayServletContextProviderWrapper</value>
            </init-param>
            <init-param>
                <name>EditPage</name>
                <value>/portlet_action/sample_struts_portlet/edit</value>
            </init-param>
            <init-param>
                <name>HelpPage</name>
                <value>/portlet_action/sample_struts_portlet/help</value>
            </init-param>
            <init-param>
                <name>ViewPage</name>
                <value>/portlet_action/sample_struts_portlet/view</value>
            </init-param>


            <expiration-cache>0</expiration-cache>

          
    <!-- 定义该Portlet 所支持的功能,体现在每个Portlet 的展现模?-->
            <supports>
                <mime-type>text/html</mime-type>
                <portlet-mode>edit</portlet-mode>
                <portlet-mode>help</portlet-mode>
            </supports>


            <portlet-info>
                <title>Sample Struts Portlet</title>
                <short-title>Sample Struts Portlet</short-title>
                <keywords>Sample Struts Portlet</keywords>
            </portlet-info>

           
    <!-- 指明对该Portlet 可能拥有权限的角Ԍ该角色定义决定了liferay-portlet.xml 所配置的角色名  -->
            <security-role-ref>
                <role-name>administrator</role-name>
            </security-role-ref>
            <security-role-ref>
                <role-name>guest</role-name>
            </security-role-ref>
            <security-role-ref>
                <role-name>power-user</role-name>
            </security-role-ref>
            <security-role-ref>
                <role-name>user</role-name>
            </security-role-ref>
        </portlet>
    </portlet-app>

    效果Q?/span>定义了Portlet 的基本信息,展现方式Q以及对该Portlet 可能分配权限的用戯艌Ӏ?span style="COLOR: rgb(0,0,0)">


    Q?Qstruts-config.xml Q该配置文g为Struts 的配|文ӞqLiferay 专用Q?/span>
    <struts-config>

        <!-- Forms Beans -->
        <form-beans>
            <form-bean name="subscribeForm" type="com.sample.struts.struts.form.SubscribeForm" />
            <form-bean name="unsubscribeForm" type="com.sample.struts.struts.form.UnsubscribeForm" />
            <form-bean name="uploadForm" type="com.sample.struts.struts.form.UploadForm" />
        </form-beans>

        <!-- Action Mappings -->

        <action-mappings>

            <!-- Sample Struts -->

            <action path="/sample_struts_portlet/edit" forward="portlet.sample_struts_portlet.edit" />

            <action path="/sample_struts_portlet/help" forward="portlet.sample_struts_portlet.help" />

            <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">
                <forward name="/sample_struts_portlet/subscribe_success" path="/portlet_action/sample_struts_portlet/subscribe_success" redirect="true" />
            </action>

                <!--
                ……
                该处省略的雷同的讄代码
                 ……
                -->

        <!-- Custom Request Processor -->

        <controller processorClass="org.apache.portals.bridges.struts.PortletTilesRequestProcessor" />

        <!-- Message Resources -->

        <message-resources parameter="content.test.Language" />

        <!-- Tiles Plugin -->

        <plug-in className="org.apache.struts.tiles.TilesPlugin" >
            <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
            <set-property property="moduleAware" value="true" />
            <set-property property="definitions-parser-validate" value="true" />
        </plug-in>

        <!-- Validator Plugin -->

        <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
            <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
        </plug-in>
    </struts-config>
    效果Q?/span>此处可与其它ZStruts 应用开发同样配|,与Liferay 怺独立?br>

    Q?Qtiles-defs.xml Q该配置文g是利用Tile q行面的布局理Qƈ非Liferay 专用Q?/span>

    <tiles-definitions>


        <!-- 关于面的布局定义Q表C当h的Url?/span> portlet.sample_struts_portlet 则以路径path参数指定?/html/portlet/sample_struts_portlet/template.jsp 面q行响应-->
        <definition name="portlet.sample_struts_portlet" path="/html/portlet/sample_struts_portlet/template.jsp" />
        <!-- 关于面的布局定义Q表C名?/span> portlet.sample_struts_portlet.edit Url 的页面嵌套页?/portlet/sample_struts_portlet/edit.jsp -->
        <definition name="portlet.sample_struts_portlet.edit" extends="portlet.sample_struts_portlet">
            <put name="portlet_content" value="/portlet/sample_struts_portlet/edit.jsp" />
        </definition>
       
        <!--
                ……
                该处省略的雷同的讄代码
                 ……
          -->

       
    <tiles-definitions>
      
    效果Q?/span>此处可与其它ZTiles 应用开发同样配|,与Liferay 怺独立?br>

    Q?Qweb.xml Q该配置文g为Tomcat 的应用配|文ӞqLiferay 专用Q?/span>
    <web-app>
        <!-- 注意Q?/span>此处的display-name与portlet.xml 中的display-name 含义不同Q此处仅标识在Tomcat 下的应用~写此不得与其它Portlet 和发布的其他应用标识重名 -->
        <display-name>sample-struts-portlet</display-name>

        <context-param>
            <param-name>company_id</param-name>
            <param-value>liferay.com</param-value>
        </context-param>

        <listener>
            <listener-class>com.liferay.portal.kernel.servlet.PortletContextListener</listener-class>
        </listener>

        <servlet>
            <servlet-name>sample_struts_portlet</servlet-name>
            <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
            <init-param>
                <param-name>portlet-class</param-name>
                <param-value>org.apache.portals.bridges.struts.StrutsPortlet</param-value>
            </init-param>
            <load-on-startup>0</load-on-startup>
        </servlet>
        <servlet>
            <servlet-name>PortletActionServlet</servlet-name>
            <servlet-class>com.liferay.util.apache.bridges.struts.LiferayPortletServlet</servlet-class>
            <init-param>
                <param-name>config</param-name>
                <param-value>/WEB-INF/struts-config.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet>
            <servlet-name>TestSessionServlet</servlet-name>
            <servlet-class>com.sample.struts.servlet.TestSessionServlet</servlet-class>
            <load-on-startup>2</load-on-startup>
        </servlet>

        <servlet-mapping>
            <servlet-name>sample_struts_portlet</servlet-name>
            <url-pattern>/sample_struts_portlet/*</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>PortletActionServlet</servlet-name>
            <url-pattern>/portlet_action/*</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>TestSessionServlet</servlet-name>
            <url-pattern>/test_session/*</url-pattern>
        </servlet-mapping>

        <taglib>
            <taglib-uri>http://java.sun.com/portlet</taglib-uri>
            <taglib-location>/WEB-INF/tld/liferay-portlet.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>http://struts.apache.org/tags-bean</taglib-uri>
            <taglib-location>/WEB-INF/tld/struts-bean.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>http://portals.apache.org/bridges/struts/tags-portlet-html</taglib-uri>
            <taglib-location>/WEB-INF/tld/struts-portlet-html.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>http://struts.apache.org/tags-logic</taglib-uri>
            <taglib-location>/WEB-INF/tld/struts-logic.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>http://struts.apache.org/tags-nested</taglib-uri>
            <taglib-location>/WEB-INF/tld/struts-nested.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>http://struts.apache.org/tags-tiles</taglib-uri>
            <taglib-location>/WEB-INF/tld/struts-tiles.tld</taglib-location>
        </taglib>
    </web-app>

    效果Q?/span>此处可与其它ZTomcat 应用开发同样配|,但与Liferay 不完全独立?/span>


    junky 2007-05-31 14:00 发表评论
    ]]>
    Liferay的授权与内容理(?http://www.tkk7.com/junky/archive/2007/05/31/121146.htmljunkyjunkyThu, 31 May 2007 05:55:00 GMThttp://www.tkk7.com/junky/archive/2007/05/31/121146.htmlhttp://www.tkk7.com/junky/comments/121146.htmlhttp://www.tkk7.com/junky/archive/2007/05/31/121146.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/121146.htmlhttp://www.tkk7.com/junky/services/trackbacks/121146.htmlLiferay的授权与内容理

     

    本节主要内容?span>Liferay的授权操作以及内容管理,在介l授权早作的同时结合上一的内容Q探讨程序背后的执行程Q也会凸现出在进行自qportlet开发时所要注意的权限相关代码Qؓportlet的开发打下基?/span>

     

     liferay-portal-4.1.2的权限管理主要有2部分构成Q?span>

    1Q?/span>user的部门归?/span>

    2Q?/span>对单?span>portlet的授?/span>

     

    用户登陆pȝ后,进入超U用L理界面Q管理界面d?span>Guest?span>Private?span>CMS?span>Support 四层l成Q即?span>Myplace中的4U视?span>, 现对其进行介l?span>.

    Guest视图Q?/span>主要理普通用L所讉K的主内容,在此视图中可以管理展现在主页上的各个portletQ管?span>portlet中展现的内容以及portlet的展现Ş式以及方位?span>Portlet的内容管理放在稍后的视图中详l讲解,portlet的方位以及显CŞ式后可以通过面上直接的拖放q行讄?/span>

          默认情况下,我们所列的portlet是匿名用户所看到的门P在每?span>portlet的设|中Q我们还看到了权限的讄Q可以将q个portlet的配|,查看{权限(每个portlet的权限不相同Q每个都有配|、查看权限,但是有个复杂?span>portlet如用L理的有更多的如d用户、删除用L权限Q授予用Pq里权限的授予分6U,直接授予用户Q授予组l、授予地炏V授予用L、授予社和授予客hQ用L和社是自定义的Q?span>Liferay的用h制ؓ公司—地点—组l—个人,所以授予某一高的组Q下挂的用户都会自动获得权限。在我的应用中,我将WIKI加入了门户首,同时察看与删除授予匿名用户Q所以,首页拥有了一个大家参与修改的区域WIKI了!

    Private 视图Q这个是用户的私人界面,q里特别分析了几个简?span>portlet的权限管理的实现?/span>

    HelloWorldPortlet?/span>位置TestQ?span>>helloworld q个portlet是最单的一个展C,而且仅仅只有view的功能,所以这个权限管理就是能否在用户的视图中昄p了,代码中的权限代码无,只是?span>layout调用HelloWorldPortlet。注Q这里是通过讄直接调用HelloWorldPortletQ没有经q?span>Struts框架Q所以代码直接?span>GenericPortletQ不能由路径讉K?/span>

    Announcements?/span>位置Q这?span>portlet中访问\径由struts配置文g指定Q这?span>portlet代码ViewActionl承PortletActionQ?span>PortletActionl承的是Struts Action.?span>portlet.xml中,

    <name>view-action</name>

    <value>/wiki/view</value>

    指定了这?span>portlet?span>view所调用的\径,portal容器会根?span>struts的配|调用指定的Action。在q行action调用Ӟ很显焉过?span>Liferay扩展?/span>PortalRequestProcessorQ上一提刎ͼQ也p行了权限查。配|?/span>Announcements的\径在liferayQ?span>portlet.xml中配|,?span>/announcements/edit_configurationQ同栯也是一?span>struts路径Q她的权限管理也?span>view一P?/span>PortalRequestProcessor中完成?/span>

    IFramePortlet?/span>q个portlet也是一个简单标{使用例子。在q个portlet中,?strong>HelloWorldPortlet相同Q也没有Struts的\径配|,而是直接?span>portlet.xml中定义了接受h?span>ActionQ所l承?span>StrutsPortlet׃不是?span>struts Action而是GenericPortlet扩展而来Q所以在讉K的时候没有通过PortalRequestProcessorQ所以其内部明确调用?span>liferay的权限管理代码:

    PermissionChecker checker =

                 PermissionThreadLocal.getPermissionChecker();

     

    ׃面我们所分析的几个简单的portlet来看Q以后在q行portlet开发时?span>2U选择Q当逻辑比较时Q我们可以象IFramePortlet一P通过?span>StrutsPortlet的承完成。当业务逻辑比较复杂Ӟ多个路径Q,采用Strutsq行路径配置Ӟ最好同Announcements一P通过l承PortletAction来将自n开发的portletU_liferay的权限管理框架中?/span>

     

    CMS视图Q?/span>明显Q这个层q行文档理Q用q?span>Guest视图可以知道门L所有的新闻文章都在journal中进行管理,对它的用网上有很多很有用的文章Q多用几ơ也q悉了Q强大的文本、图像编辑功能可以就q用而不再用自己~码Q肯定也是很愉快的了Q)

     

    Support视图Q?/span>q个视图也是其他用户Q非理员用P登陆后的定制面Q由理员进行定Ӟ主要操作和上面一致?/span>



    junky 2007-05-31 13:55 发表评论
    ]]>
    Liferay 安全理(?http://www.tkk7.com/junky/archive/2007/05/31/121139.htmljunkyjunkyThu, 31 May 2007 05:45:00 GMThttp://www.tkk7.com/junky/archive/2007/05/31/121139.htmlhttp://www.tkk7.com/junky/comments/121139.htmlhttp://www.tkk7.com/junky/archive/2007/05/31/121139.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/121139.htmlhttp://www.tkk7.com/junky/services/trackbacks/121139.html企业应用整合成ؓ了越来越多的企、事业单位的当务之急,我所处环境也不可避免的遇到这个棘手的问题Q各U技术的交集使得portal技术有了大显n手之处。可?span>IBM?span>BEA的高额费用让我们望而却步,自然Q开源的portal成ؓ了首选,Liferay是开源社区里一个非常活跃的目Q)而且重要的是其技术架构如?span>1Q也和我们现在的技术\U相q,所以我们决定采?span>LiferayQ版本:liferay-portal-src-4.1.2Q?/span>作ؓ基础来进行应用开发和pȝ整合?/span>

    ? Liferay技术架?/strong>

     
     

    要用好这个基q_Q必要对她的自w实现原理有个比较清晰的认识Q以下文章ؓ我在研究Liferay原理时所做的一些笔讎ͼ现整理和分nQ由于笔记带有强烈的个h思想Q有错误再所隑օQ希望能对进一步的分析做ؓ铺垫Q更Ƣ迎批评指正Q?/span>

     

    Liferay Portal

    Liferay ?span>JAAS权限理

    Liferay的业务逻辑理

    Liferay二次开?/span>

    Liferay WSRP

     

    Liferay的权限管理实C一个典型的JAAS理{略Q所以在分析其本w前Q在此首先介l?span>JAAS的验证原理和Tomcat上如何开发标?span>JAAS应用?/span>

     JAAS验证原理

    JAAS的核心类和接口可以被分ؓ三种cdQ大多数都在javax.security.auth包中。在J2SE 1.4中,q有一些接口的实现cdcom.sun.security.auth包中Q如下所C:

    & #61557;       普通类 SubjectQ?/span>PrincipalQ?/span>Credential(凭证)

     SubjectcM表了一个验证实体,它可以是用户、管理员?/span>Web服务Q设备或者其他的q程。该cd含了三中cd的安全信息:

    1)        w䆾Q?/span>IdentitiesQ:׃个或多个Principal对象表示

    2)        公共凭证Q?/span>Public credentialsQ:例如名称或公共密?/span>

    3)        U有凭证Q?/span>Private credentialsQ:例如口o或私有密?/span>

      Principal对象代表?/span>Subject对象的n份。它们实Cjava.security.Principal?/span>java.io.Serializable接口。在PrincipalcMQ最重要的方法是getNameQ)。该Ҏq回一个n份名U。在Subject对象中包含了多个Principal对象Q因此它可以拥有多个名称。由于登录名U、n份证号和Email地址都可以作为用Lw䆾标识Q可见拥有多个n份名U的情况在实际应用中是非常普遍的情况?/span>

    在上面提到的凭证q不是一个特定的cL借口Q它可以是Q何对象。凭证中可以包含M特定安全pȝ需要的验证信息Q例如标{(ticketQ,密钥或口令?/span>Subject对象中维护着一l特定的U有和公有的凭证Q这些凭证可以通过Subject ҎgetPrivateCredentialsQ)?/span>getPublicCredentialsQ)获得。这些方法通常在应用程序层中的安全子系l被调用?/span>

    & #61557;       验证 LoginContextQ?/span>LoginModuleQ?/span>CallBackHandlerQ?/span>Callback

    验证Q?/span>LoginContext

      在应用程序层中,你可以?/span>LoginContext对象来验?/span>Subject对象?/span>LoginContext对象同时体现?/span>JAAS的动态可插入性(Dynamic PluggabilityQ,因ؓ当你创徏一?/span>LoginContext的实例时Q你需要指定一个配|?/span>LoginContext通常从一个文本文件中加蝲配置信息Q这些配|信息告?/span>LoginContext对象在登录时使用哪一?/span>LoginModule对象?/span>

      下面列出了在LoginContext中经怋用的三个ҎQ?/span>

    & #61550;         login () q行d操作。该ҎȀzM配置中制定的所?/span>LoginModule?/span> 象。如果成功,它将创徏一个经q了验证?/span>Subject对象Q否则抛?/span>LoginException异常?/span>

    & #61550;         getSubject () q回l过验证?/span>Subject对象

    & #61550;         logout () 注销Subject对象Q删除与之相关的Principal对象和凭?/span>

      验证Q?/span>LoginModule

      LoginModule是调用特定验证机制的接口?/span>J2EE 1.4中包含了下面几种LoginModule的实现类Q?/span>

    & #61550;         JndiLoginModule 用于验证?/span>JNDI中配|的目录服务

    & #61550;         Krb5LoginModule 使用Kerberos协议q行验证

    & #61550;         NTLoginModul 使用当前用户?/span>NT中的用户信息q行验证

    & #61550;         UnixLoginModule 使用当前用户?/span>Unix中的用户信息q行验证

     

      同上面这些模块绑定在一Lq有对应?/span>Principal接口的实现类Q例?/span>NTDomainPrincipal?/span>UnixPrincipal。这些类?/span>com.sun.security.auth包中?/span>

     

      LoginModule接口中包含了五个ҎQ?/span>

    1)        initialize () 当创ZLoginModule实例时会被构造函数调?/span>

    2)        login () q行验证,通常会按照登录条件生成若q个Principal对象

    3)        commit () q行Principal对象验,按照预定?/span>Principal条g?/span>Login生成?/span>Principal对象Q所有需要的条g均符合后Q把若干个生成的Principal对象付给Subject对象Q?/span>JAAS架构负责回传l?/span>LoginContext.

    4)        abort () 当Q何一?/span>LoginModule对象验证p|旉会调用该Ҏ。Q何已l和Subject对象l定?/span>Principal对象都会被解除绑定?/span>

    5)        logout () 删除?/span>Subject对象兌?/span>Principal对象和凭证,消除Subject,Principal{认证对象?/span>

     验证Q?/span>CallbackHandler?/span>Callback

      CallbackHandler?/span>Callback对象可以?/span>LoginModule对象从系l和用户那里攉必要的验证信息,同时独立于实际的攉信息时发生的交互q程?/span>

      

      JAAS?/span>javax.sevurity.auth.callback包中包含了七?/span>Callback的实现类和两?/span>CallbackHandler的实现类Q?/span>ChoiceCallback?/span>ConfirmationCallback?/span>LogcaleCallback?/span>NameCallback?/span>PasswordCallback?/span>TextInputCallback?/span>TextOutputCallback?/span>DialogCallbackHandler?/span>TextCallBackHandler?/span>Callback接口只会在客L会被使用到。我在后面介绍如何~写你自qCallbackHandlercR?/span>

     

    授权 PolicyQ?/span>AuthPermissionQ?/span>PrivateCredentialPermission

    要了?span>LiferayQ?span>tomcat版本Q的权限理Q必首先了?span>JAAS?span>tomcat上的应用?/span>

     

    u          Tomcat服务?span>JAAS配置Ҏ

      和在应用E序q行JAAS不同的是Q配|?/span>JAASҎ会有很不一栗我们用的?/span>Tomcat 5.0.x 应用服务器,它的JAAS配置Ҏ有数U,分别?/span>

    & #61557;       JAASRealm

    & #61557;       JDBCRealm

    & #61557;       DataSourceRealm

    & #61557;       JNDIRealm

    & #61557;       MemoryRealm

    JAASRealm

     

    1.         把自定义 LoginModule?/span>User?/span>Role{相关类攑օTomcat ?/span> classpath

    2.         把自定义login.config JAAS配置文g配置q?/span>JVM环境Q例如: JAVA_OPTS=-DJAVA_OPTS=-Djava.security.auth.login.config==$CATALINA_HOME/conf/jaas.config

    3.         web.xml里的 security-constraints 标签讑֮需要保护的资源

    4.         ?/span>$CATALINA_HOME/conf/server.xml?/span>engine标签里设|?/span>JAASRealm标签

    以下?/span>JAASRealm标签的详l说?/span>

    属?/span>

    描述

    className

    只需要指?/span> org.apache.catalina.realm.JAASRealm

    debug

    debugU别Q默认ؓ不设|?/span>0

    appName

    JAAS配置文g应用?/span>

    userClassNames

    自定?/span>user Principals

    roleClassNames

    自定?/span> role Principals

    useContextClassLoader

    默认?/span>true, Z向后兼容c装载方式,使用Tomcat4以上版本ContextLoader装蝲方式

     

    以下是完整的tomcat服务器配|例子:

    ?/span>%TOMCAT_HOME%/config/server.xml 中添加以下段?/span>

    <Realm className="org.apache.catalina.realm.JAASRealm"            

                    appName="MyFooRealm"      

        userClassNames="org.foobar.realm.FooUser"      

         roleClassNames="org.foobar.realm.FooRole"

                          debug="99"/>

    上面介绍?span>tomcat的应用,?span>liferayQ?span>tomcat版本Q也是利用了q种标准?span>tomcat?span>JAAS实现?/span>

    与权限管理、用戯证的主要cd为:

    com.liferay.portal.security.auth.*

    com.liferay.portal.service.permission

    com.liferay.portal.struts.PortalRequestProcessor

     

    Liferay关于JAAS的实现包都在com.liferay.portal.security.auth.*下,?span>$catalina_home/conf/jaas.conf中定义了Liferay实现?span>loginModuleQ在我用的版本中,PortalLoginModule首先通过对象池取Z个自定义Liferay用户自定义的实现Q即也可以在portal中再ơ自定义loginModule。显Ӟ如果没有自定义的实现Q将Ҏ用户所使用的服务器自动q行选择默认实现?/span>

    Liferay自n所实现?/span>user Principals?span>role Principals也仅仅是保存了用LuseridQ以其作w标识,在登陆成功时赋予了所有用?#8220;users”角色Q?/span>

    PortalRole role = new PortalRole("users");

    getSubject().getPrincipals().add(role);

    Liferay?span>PortalRequestProcessor扩展?span>TilesRequestProcessorQ实C自定义的h处理程。在h程中复写了processRolesQ)Q在q个函数中进行了用户权限的判断,从而达C?span>web资源的保护?/span>

    Permission?span>Liferay定义的用戯问的权限判断Q由processRoles调用q行讉K控制?/span>

    值得一提的是,Liferay本n也含有登陆模块,q个登陆模块所做的主要工作为通过认证定用户的登陆信息正,q过用户的登陆信息取得用?span>userid存放?span>session中,?span>JAAS的登陆模块提供基Q即通过登陆的正用?span>id与密码)。登陆的用户默认?span>LDAP登陆Q但是ؓ默认用Q所以用戯?span>Liferay都通过一个数据库的认证实现在loginAction中进行的用户判断Q取Zuserid?span>password存放?span>session中?/span>

    整个q程如下Q?/span>

     

    如上图所C,触发JAAS的登陆模块的是在登陆成功后{向了/c/portal/protectedQ而此路径?span>tomcat的安全域Q所?span>tomcat调用用戯定义的登陆模块进行用戯证,通过认证后通过对用戯色的ҎQ来判断用户是否允许讉K?/span>

     ? Liferay认证程

      

     

    副录Q帮助进行相关类查看

    SecureFilter->q行讉K地址限制和是使用安全q接转换?/span>

    PropsUtil?span>?/span>portal-ejb.jar里的portal.property

    MainServlet 扩展Struts?span>action ServerletQ进行映?/span>



    junky 2007-05-31 13:45 发表评论
    ]]>
    Single SignOn - Integrating Liferay With CAS Serverhttp://www.tkk7.com/junky/archive/2007/05/29/120724.htmljunkyjunkyTue, 29 May 2007 09:07:00 GMThttp://www.tkk7.com/junky/archive/2007/05/29/120724.htmlhttp://www.tkk7.com/junky/comments/120724.htmlhttp://www.tkk7.com/junky/archive/2007/05/29/120724.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/120724.htmlhttp://www.tkk7.com/junky/services/trackbacks/120724.htmlIntroduction

    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.

    Setting up CAS server

    We will begin with setting up JA-SIG CAS server on Tomcat 5.x.x.

    Download cas-server WAR from Liferay's download page or the whole distribution from here 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.

    We'll need to edit the server.xml file in tomcat and uncomment the SSL section to open up port 8443.

    <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" />
    

    Setting up the CAS client

    Next we need to download the Yale CAS client from here. Get cas-client-2.0.11. Place the casclient.jar in ROOT/web-inf/lib of the Liferay install.

    Generate the SSL cert with Java keytool

    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 here

    But I found some typos and errors on that page. So following the instructions below should get you what you need.

    In any directory ( I use my root ) enter the command:

    keytool -genkey -alias tomcat -keypass changeit -keyalg RSA

    Answer the questions: (note that your firstname and lastname MUST 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)

    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
    

    Then enter the command:

    keytool -export -alias tomcat -keypass changeit -file %FILE_NAME%
    

    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\<username>\.keystore)

    Finally import the cert into Java's keystore with this command. Tomcat uses the keystore in your JRE (%JAVA_HOME%/jre/lib/security/cacerts)

    keytool -import -alias tomcat -file %FILE_NAME% -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts
    

    Startup the CAS server

    Now you are ready to startup your CAS server. Simply startup Tomcat and access CAS with https://localhost:8443/cas You should see the CAS login screen and no errors in your catalina logs.

    Setting up Liferay Portal

    web.xml

    Note: 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.

    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.


    <filter>
    <filter-name>CAS Filter</filter-name>
    <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
    <init-param>
    <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
    <param-value>https://localhost:8443/cas-web/login</param-value>
    </init-param>
    <init-param>
    <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
    <param-value>https://localhost:8443/cas-web/proxyValidate</param-value>
    </init-param>
    <init-param>
    <param-name>edu.yale.its.tp.cas.client.filter.serviceUrl</param-name>
    <param-value>http://localhost:8080/c/portal/login</param-value>
    </init-param>
    </filter>
    

    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:

       <init-param>
    <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
    <param-value>localhost:8080</param-value>
    </init-param>
    


    <filter-mapping>
    <filter-name>CAS Filter</filter-name>
    <url-pattern>/c/portal/login</url-pattern>
    </filter-mapping>
    


    Then add the following to the rest of the auto login filters

    <filter-mapping>
    <filter-name>Auto Login Filter</filter-name>
    <url-pattern>/c/portal/login</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    system-ext.properties

    Note: this is only needed in Liferay 4.2

    Set the com.liferay.filters.sso.cas.CASFilter setting to true.

    Place the following in system-ext.properties:

       #
    # The CAS filter will redirect the user to the CAS login page for SSO. See
    # http://www.ja-sig.org/products/cas for more information.
    #
    com.liferay.filters.sso.cas.CASFilter=true
    

    portal-ext.properties

    Put this in portal-ext.properties.

    ##
    ## Auto Login
    ##
    
    #
    # 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
    

    Comment the first auto.login.hooks property and uncomment the second to add CASAutoLogin to the list of AutoLogin implementations.

    Startup Liferay and Test

    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.

    Next steps

    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.

    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:

    • To authenticate with LDAP: The CAS server includes an authentication handler for LDAP. You can read about it in http://www.ja-sig.org/products/cas/server/ldapauthhandler/index.html. If this option is chosen it is recommended that you also configure Liferay to authenticate against LDAP using the instructions in: LDAP. Then you'll need to provide some way to synchronized the users between LDAP and Liferay's database. Two options are:
      • Set up the automatic importer (see LDAP, available since v4.2)
      • Develop an extension to CASAutoLogin that upon successful login, if the user does not exist it is created with the user from LDAP (see this mb thread for details)
    • 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.
    • 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.

    Some other steps that you might want to follow are:

    Also, check the references at the end of the article for more information.

    Troubleshooting

    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:

    keytool -delete -alias tomcat -keystore %JAVA_HOME%/jre/lib/security/cacerts
    keytool -delete -alias tomcat -file server.cert
    
    • You may not be able to get https://localhost:8443/cas 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.
    • I've had problems with certs on IE7, make sure you try it out on Firefox and Opera.
    • 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 JSSE Reference Guide 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.

    References

    • Lifecast: CAS Setup - Integrate Liferay Portal with a CAS server to access multiple applications with a single sign on.


    junky 2007-05-29 17:07 发表评论
    ]]>
    liferay Portal 二次开发指?/title><link>http://www.tkk7.com/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.tkk7.com/junky/archive/2007/05/28/120397.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/120397.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2007/05/28/120397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/120397.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/120397.html</trackback:ping><description><![CDATA[文档说明 <p> <br>参与人员Q?br> <br>作?|名 联络 <br>柯自?eamoi   educhina <a href="mailto:eamoi@163.com">eamoi@163.com</a>Q技术) <a href="mailto:zcke0728@hotmail.com">zcke0728@hotmail.com</a>Q版权) <br>      </p> <p> <br>发布记录Q?br> <br>版本 日期 作?说明 <br>1.0 2005-10-20 柯自?创徏Q第一?<br>        </p> <p> <br>链接Q?br> <br>cd |址 <br>Blog <a href="http://www.tkk7.com/eamoi/">http://www.tkk7.com/eamoi/</a> <br>MSN-Space <a >http://spaces.msn.com/members/eamoi/</a> </p> <p> <br> <br>OpenDoc版权说明Q?br>本文档版权归原作者所有?br>在免贏V且无Q何附加条件的前提下,可在|络媒体中自׃播?br>如需部分或者全文引用,请事先征求作者意见?br>如果本文Ҏ有些许帮助,表达谢意的最好方式,是将您发现的问题和文档改q意见及时反馈给作者。当Ӟ倘若有时间和能力Q能为技术群体无偿A献自q所学ؓ最好的回馈?br> <br>?.. 5<br>W一部分 Liferay Portal 架构解析... 6<br>W一?Liferay Portal. 6<br>W一?Portal规范... 6<br>1.1.1 JSR168. 6<br>1.1.2 WSRP. 6<br>W二?什么是Portal7<br>1.2.1 Portal 服务?.. 7<br>1.2.2 Portlet容器... 7<br>W三?什么是Portlet8<br>1.3.1 Portlet8<br>1.3.2 Portlet与Servlet的关p?.. 8<br>1.3.3 Portlet的生命周?.. 9<br>W四?Liferay Portal工作原理... 9<br>1.4.1 Portlet 样式以及H口状?.. 10<br>1.4.2 Portal面... 11<br>W二章Liferay Portal的?.. 13<br>W一?Liferay Portal安装... 13<br>W二?Liferay Portal的用L?.. 14<br>2.2.1 定义用户... 14<br>2.2.2 d用户... 15<br>2.2.3 修改用户... 15<br>2.2.4 定义用户l?.. 18<br>2.2.5 新增、重命名用户l?.. 19<br>2.2.6 修改用户l?.. 19<br>2.2.7 定义角色... 21<br>2.2.8 新增、重命名角色... 21<br>2.2.9 修改用户l角?.. 21<br>2.2.10 定义Portlet的角?.. 22<br>W三?Liferay Portal内容和布局... 24<br>2.3.1 什么是布局... 24<br>2.3.2 什么是内容... 26<br>2.3.3 内容布局与Portlet的关p?.. 27<br>2.3.4 选择内容和布局... 28<br>W四?Liferay Portal的桌?.. 28<br>2.4.1 什么是桌面... 28<br>2.4.2 定义个性化的桌?.. 29<br>W五?Liferay Portal的品?.. 29<br>2.5.1 什么是品质... 30<br>2.5.2 品质和Portlet、Portal的关p?.. 30<br>2.5.3 定义个性化的品?.. 30<br>W六?Liferay Portal的部|描q文?.. 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>W二部分 Liferay Portal 二次开?.. 36<br>W三章开发自qPortlet. 36<br>W一?重要的基c:GenericPortlet36<br>W二?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>W三?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>W四?~写自己的Portletc?.. 44<br>3.4.1 开发环?.. 44<br>3.4.2 准备工作... 44<br>3.4.3 HelloWorldPortlet46<br>3.4.4 HelloJSPPortlet47<br>W五?修改Web部v描述文g... 48<br>W六?创徏Liferay Portal部v描述文g... 49<br>W三部分 Liferay Portal部v... 54<br>W四章部|自qPortlet. 54<br>W一?手动部v... 54<br>W二?Ant自动部v... 55<br>W三?加入Liferay Portal自有列表... 55<br>W四?普通Java Web应用转化为Portlet应用... 56<br>W四部分附录... 58<br>W五章相兌?.. 58<br>W一节资源网?.. 58<br>W二?CZ... 58<br>W六章参考资?.. 59<br>后序<br> <br>W一部分 Liferay Portal 架构解析<br>本部分主要内?br>Portal 服务?Portal 容器 Portlet<br>W一?Liferay Portal<br>作ؓ一个开源Portal产品QLiferay Portal提供对多个独立系l的内容集成Q帮助多个组l实现更有效的合作。与其他商业的Portal产品相比QLiferay Portal有着一pd的优良特性,而且不需要付贏V?br>W一?Portal规范<br>随着Portal的兴P来多的公司开始涉Portal产品开发,q组建各自的Portallg和基于其的品,比如IBM、BEA、MicroSoft、SAP、Apache{。各个厂商的接口互不兼容Q给软g开发商以及开发h员带来诸多不ѝ?br>1.1.1 JSR168<br>为此QJCPl织发布了JSR168(Java Specification Request)QPortlet Specification V1.0Q用来提供不同的Portal和Portlet之间的互通性。只要开发的Portlet遵@JSR168Q则可以在所有遵循JSR168的Portal上部|运行?br>JSR168中定义了Portal的实现规范和接口Qƈ对理想的Portletq行了详l的规划和描q?br>1.1.2 WSRP<br>WSRP是OASIS Web Service for Remote Portlet的羃写。WSRP是Web Service的一U新的商业应用,一U新的标准,主要用来化Portal对于各种资源或者程序整合的复杂度,可以避免~程带来的整合麻烦和问题。而且Portal理员可以从量的WSRP服务中选择需要的功能用以整合到目前所用的Portal中。它有三U角Ԍ<br>①、生产?à 提供Portlet<br>②、消费?à 使用Portlet<br>③、终端用?à 最l用?br>它的特点在于生者将消费者所需要的信息通过WSRPq回l消费者,q些信息是相Ҏ记片断,例如HTML、XHTML{,可以直接嵌入用户的页面中Q而不用像Web Service一样开发用L接口?br>实现q个规范QPortal可以跟各式各L数据源打交道Q彻底终l信息孤岛的H境?br>W二?nbsp; 什么是Portal<br>Portal是基于Web的,?#8220;应用整合”?#8220;消除信息孤岛”为最l目的,提供单点d、内容聚合、个性化门户定制{功能的l合信息pȝ?br>完整的Portal通常由Portal服务器、Portlet容器、Portlet构成?br>1.2.1 Portal 服务?br>Portal服务器是容纳Portlet容器Q支持Portlet呈现的普通或者特DWeb服务器。Portal服务器通常会提供个性化讄、单点登录、内容聚合、信息发布、权限管理等功能Q支持各U信息数据来源,q将q些数据信息攑֜|页中组合而成Q提供个性化的内容定Ӟ不同权限的浏览者能够浏览不同的信息内容。通常QPortal提供以下功能:<br>单点dQPortal通常采用ACL、SSL、LDAP{业界标准的安全技术,提供Ҏ有现有应用系l的安全集成Q只需在Portal的唯一入口上登录一ơ,可以访问所有应用系l和数据。对于安全性要求较高的应用pȝQ如电子商务q_、交易系l等Q通过扩展接口传递用戯n份信息,如数字证书信息、数字签名信息等Q进行二ơn份认证,保证单点登陆的安全性?br>权限控制:pȝ采用LDAP对用戯源进行统一的管理,同时提供二次开发接口,可以与其他应用系l的用户理模块ҎQƈ能随相关业务pȝ实时更新讉K权限。通过完善的授权机制及存取控制Q用戯问权限控制到字段U别Q确保用户只能访问具有权限的应用pȝ及相关信息?br>内容理: 实现应用pȝ之间实时交换信息。采用多U缓存机Ӟ保证内容交换的性能和准性。采用基于XML的Rich Site Summary (RSS)标准Q迅速在各应用系l之间传播最新变化?br>信息发布: 实现信息门户内容的动态维护。动态网站系l可与OA协同办公pȝ、知识管理系l等集成Q网站信息须lOApȝ的审ҎE流转通过后或知识理q_讄h外部׃n权限后才可正式发布,真正实现内外信息发布的同步?br>文g理: pȝ实现无缝集成多种数据源,包括Q数据库、文档(Office文档、PDF、AutoCAD、甚至ZIP文档Q、Web|页、FTP站点{,q对数据按业务要求和职务特点加以分析整理Q通过l一Web界面d推?Push)至用L门户桌面Q帮助用户做出及时、正的决策?br>1.2.2  Portlet容器<br>Portlet容器提供Portlet执行的环境,包含很多Portletq管理它们的生命周期Q保存Portlet的定制信息?br>一个Portal容器接收到来自Portal的请求后Q接着这个请求传递给存在Portal容器的Portlet 执行。Portlet容器没有义务ȝ合Portlet 产生的信息內容,q个工作必须由Portal来处理。Portal?Portal容器可以攑֜一赯为同一个系l的lgQ或者分开成ؓ两个独立的组件?br>Portlet容器是普通Web Servlet容器的扩展,所以一个Portlet容器可以构徏于一个已l存在的Servlet容器或者可能实现全部Web Servlet容器的全部功能。无论Portlet容器怎么实现Q它的运行环境L假定它支持Servlet2.3规范?br>通常QPortlet容器扩展自普通的Servlet容器?br> <br>W三?nbsp; 什么是Portlet<br>Portlet是Portal中最重要的组Ӟ负责在Portal中呈C息内容,有相应的生命周期。通过自定义PortletQ用户很Ҏ定义个性化的Portal面。Portlet由Portlet容器负责理、处理请求ƈq回动态页面,可以作ؓPortal的可x即用的界面组件?br>1.3.1 Portlet<br>一个Portlet是以Java技术ؓ技术的WeblgQ由Portlet容器所理Q专门处理客L信息h以及产生各种动态的信息内容。Portlet 为可插式的客L面组Ӟ提供呈现层成Z个信息系l?br>q些由Portlet产生的内容也被称为片D,而片D|h一些规则的标记( HTML、XHTML、WML )Q而且可以和其他的片段l合而成一个复杂的文g。一个或多个 Portlet 的内容聚合而成Z?Portal |页。?Portlet 的生命周期是?Portlet 容器所理控制的?br>客户端和Portlet的互动是由Portal通过典型的请?响应方式实现Q正常来_客户会和Portlet所产生的内容互动,举例来说Q根据下一步的q接或者是认送出的表单,l果 Portal会接收到Portlet的动作,这个处理状况{向到目标Portlet。这些Portlet 内容的生可能会因ؓ不同的用者而有不同的变化,完全是根据客户对于这个Portlet的设|?br>1.3.2 Portlet与Servlet的关p?br>Portlet被定义成Z个新的组Ӟh新的明确的界面与行ؓ。ؓ了尽可能与现有的 Servlet l合辑ֈ重复使用的目的,Portlet 的规范利用了 Servlet 的规范,许多观念都很怼的,l合 Portlet、Servlet ?Jsp 在同一个网站系l中Q我们称为Portlet 应用 。在同一?Portlet 应用 中,他们分享同一个类加蝲?ClassLoader)Q上下文(Context) ?Session?<br>①、Portlet ?Servlet 的相g?br>@ Portlet 也是 Java 技术的 web lg<br>@ Portlet 也是有特定的 container 在管?br>@ Portlet 可以动态生各U内?br>@ Portlet 的生命周期由 container 所理<br>@ Portlet 和客L的互动是通过 request/response 的机?<br>②、Portlet ?Servlet 也有一些不?br>@ Portlet 只?markup 信息片段Q不是完整的|页文g。?Portal 会将所有的 Portlet markup 信息片段攑ֈ一个完整的 Portal |页?br>@ Portlet 不会?URL 有直接的关系<br>@ 客户端必通过 portal pȝ才能?Portlet 互动<br>@ Portlet 有一些定义好?request 处理Qaction request 以及 render request?br>@ Portlet 默认定义 Portlet modes 及窗口状态可以指出在|页中该 Portlet 的哪个功能正在执行及现在?状态?br>@ Portlet 可以在同一?portal |页之中存在多个?<br>③、Portlet 有一些附加的功能?Servlet 所没有?br>@ Portlet 能够存取及储存永久配|文件及定制资料?br>@ Portlet 可以存取使用者数?br>@ Portlet h URL 的重写功能在文g中去动态徏立连l,允许 portal server 不用ȝ道如何在|页的片 D之中徏立连l及动作?br>@ Portlet 可以储存临时性的数据?Portlet session 之中Q拥有两个不同的范围Q?br>application-wide scope ?Portlet private scope ?br>④、Portlet 不具有一些功能, 但是 Servlet 却有提供<br>@ Servlet h讄输出的文字编? character set encoding)方式<br>@ Servlet可以讄 HTTP 输出?header<br>@ Servlet才能够接收客户对?portal 发出?URL h<br>1.3.3 Portlet的生命周?br>一个Portlet有着良好的生命周期管理,定义了怎样装蝲Q实例化和初始化Q怎样响应来自客户端的h及怎样送出服务。这个Portlet生命周期由Portlet接口的initQprocessActionQrender和destroyҎ来表达?br>载入和实例化:Portlet容器负责载入和实例化Portlet。当Portlet容器q行Portlet应用或者gq到Portlet需要服务用者的hӞPortlet׃被蝲入ƈ实例化。蝲入PortletcdQPortletc随卌实例化?br>初始?Portletcd例化后,Portlet容器q需要初始化Portlet。以调用Portletd应客L的请求。Portlet容器呼叫Portlet接口中的initҎ初始化Portlet。扩展自PortletConfig的类可以取出定义在部|描q文件中的初始化参数Q以及Resource Bundle?br>初始化异??Portlet初始化期_Portlet可能会丟?UnavailableException ?PortletException 异常。此ӞPortlet容器不能?Portlet|入已启动的服务Qƈ?Portlet容器必需释放q个 Portlet?destoryҎ不能被呼叫,因ؓ初始化被认ؓ执行p|。发?p|后,Portlet容器会尝试着重新实例化及初始?Portlet。这个异常处理的规则是:׃个UnavailableException 指定一个不能执行的最时_当此异常发生ӞPortlet容器必需{到指定旉q去后才产生q且初始化一个新?Portlet?br>在初始化q程中所丟出?Runtime Exception异常Q被当作 PortletException 来处理?br>W四?Liferay Portal工作原理<br>PortalpȝҎ需要由一个或者多个Portal面l成Q每个Portal面包含零个或者多个的Portlet。每个Portlet呈现自己的信息内容,以此实现内容聚合。通过定义每个Portlet的可用权限,实现个性化的桌面信息定制?br>1.4.1 Portlet 样式以及H口状?/p> <p>JCPl织提出的JSR168规范定义了Portlet的实现标准。每个Portlet对外表现Z个小H口Q有自己的默认样式和H口状态。如上图QPortlet有自q标题Q浏览状态下支持~辑、关闭、上UR下UR最大化、最化功能Q编辑状态下支持q回和关闭功能。从各种数据来源提取的信息以Portlet内容的Ş式呈现在Portal中?br>Portlet样式指出 Portlet正处于什么模式,Portlet通常会根据所处的模式而执行不同的工作q生不同的内容?br>Portlet模式?Portlet军_它该昄什么内容和执行什么动作。调用一?Portlet的时候,Portlet 容器会提供一?Portlet模式l那?Portlet。当在处理一个请求动作时QPortlet 的模式是可以用程序来改变的?br>JSR168规范定义了三个Portlet模式Q?览、编辑和帮助QLiferay Portal支持其中的全部三个模式。同时Portal是可以根据用者的角色Q来军_是要提供(昄)哪几?Portlet 模式l用者操作?br>例如Q匿名用者可以操作浏览和帮助{?Portlet 模式的内容, 而只有授权过的用者可以操作编辑这?Portlet 模式所提供的内Ҏ动作?br>在浏览这个Portlet模式里,所被期望要提供的功能是产生标记语言来表现此?Portlet的状态?举例来说Q?Portlet?览 模式可以包含一个或多个画面让用者可以浏览与互动Q?或是一些不需要与使用者互动的静态内宏V?<br>   在编辑这个Portlet模式里, Portlet 需要提供内容和逻辑来让使用者定?Portlet 的行为。典型的_~辑模式?Portlet 会设定或更新 Portlet 的参数设定倹{?br>在帮助这个模式里QPortlet应该提供有关q个 Portlet的帮助信息。这个帮助信息可以是有关q个 Portlet的简单且条理清楚的视H说明或是详l的说明整个来龙去脉。所有的Portletq不需要都提供帮助q个模式?br>一?Portlet可以ҎH口状态来军_在一个页面里该占多少I间。当调用一?PortletӞ Portlet容器 需要告诉该 Portlet目前的窗口状态?此时 Portlet可以ҎH口状态来军_它该对多信息作处理。在处理h的过E中Q?Portlet可以通过E序的方式来改变H口状态?br>1.4.2 Portal面</p> <p><br>每个Portal面包含零个或者多个Portlet窗口,构成一个完整的信息呈现面。Portal在启动之后根据Portlet配置文g{信息,lPortlet的标题等属性赋|赋予Portlet~辑、关闭等各种控制按钮QPortlet成ؓ一个标准的PortletH口。Portlet合ƈq些PortletH口Q组成一个完整的文档Q即Portal面。每个Portlet都处于相应的布局当中Q呈C先定义的内容Q表现Portal公共的品质。而且Portlet可以在不同的布局之间切换。Portlet响应客户端的hQƈ请求提交到相应的URLq行逻辑处理?br>Portlet开发完毕之后,部v到Portal服务器,由Portal服务器负责组l、权限控制和呈现。Portal面创徏q程如下:<br>Portlet ?Portlet容器内执行,Portlet容器接收 Portlet产生的内宏V通常 Portlet容器这些内Ҏ交给 Portlet服务器,Portlet服务器依照这些内容徏立Portal面Q然后将它传l客L呈现。具体流E如下图:</p> <p><br>Portal面的请求过E如?<br>使用者经由客L讑֤Q例如浏览器Q存?PortalQPortal Ҏ接收到的h军_哪些 Portlet 需要被执行以满需求。Portal 通过Portlet容器呼叫 PortletQ然后由 Portlet产生的片D徏立Portal面Q再传回客户端呈现给使用者。具体流E如下图:</p> <p><br>W二章Liferay Portal的?br>       Liferay Portal分ؓProfessional ?Enterprise两个版本?br>Liferay Portal支持多个应用服务器和Servlet容器。Liferay Portal Ent版本需要一个健壮的J2EE服务器,而Pro版本只要一个普通的Servlet服务器就可以q行。如果需要运行EJBQ徏议用Pro版本。两个版本的源码和应用接口都是一L?br>默认的,Pro版本分别集成Tomcat / Jetty / Resin作ؓWeb服务器,采用Struts作ؓWeb框架Q实现轻量的系l架构。Enterprise集成JBoss作ؓWeb服务器,采用Spring作ؓWeb框架Q兼EJB?br>Liferay Portal默认集成HSQL数据库,来持久化保存用户自定义的数据。通过修改集成在Liferay Portal的Tomcat的部|描q文Ӟ用户可以更改数据源。Liferay Portal官方|站提供了数据库表的生成脚本?br>下面以Pro版本(Tomcat服务?ZQ讲qLiferay Portal的用L略、内容布局、桌面和品质?br>W一?Liferay Portal安装<br>׃Liferay Portal Pro版本集成了Tomcat服务器V5Q所以只要把应用包下载解压就可以直接q行?br>1、从 <a >http://www.iferay.om/web/guest/downloads/portal_pro</a> 下蝲Pro版本zip包, 解压到目录{PORTAL_HOME}Q?目录l构相对普通的Tomcat增加了Liferay文g夏VLiferay是默认的Web应用?br>2、正安装JDK1.4或者JDK1.5Qƈ在环境变量里面正配|JAVA_HOME变量?/p> <p><br>3、从命o行启动{PORTAL_HOME}/bin/startup.batQ启动Liferay Portal?br>4、在览器地址栏输?a href="http://localhost/">http://localhost</a> Q访问Portal首页?br>5、用Login?a href="mailto:test@liferay.com">test@liferay.com</a>密码为test的用L录PortalpȝQ得到的是一个Demo的首c?/p> <p><br>如果启动呈现异常Q请查看Tomcat控制台查扑֎因?br>Liferay Portal启动之后QHSQL数据库自动启动?br>dpȝ后,点击右上?#8220;My Account”链接Q在“Display”选项卡中Language改ؓ“Chinese(China)”Q以便中文化Portal界面?br>W二?Liferay Portal的用L?br>Liferay Portal通过定义严}的用L略、灵zȝ可个性化定制的内容和布局以及丰富可定制的品质{略Q实现灵zȝ可定制的产品理念?br>Liferay Portal采用用户Q用LQ角ԌPortlet的关联方式来实现用户权限的管理。用户录属于用户l(也可以单独存在)Q该用户l具有某U(多种Q角Ԍ角色分配l用LQ也可以直接分配l用戗而操作某个Portlet 需要具有其指定的角艌Ӏ下面通过实例操作Q来了解和体验一下Liferay Portal的用L理策略?br>2.2.1 定义用户<br>Liferay Portal的用L理在pȝ理的Portlet中。缺省只有系l管理员才能使用。登录Portal后,可以在默认的桌面上找?#8220;pȝ理”Portlet。如果没有,从页面底部的选择框中选择“pȝ理”d上。也可以通过右上?#8220;CMS”桌面?#8220;内容和布局”面扑ֈ理入口?br>?#8220;pȝ理”Portlet中选择“用户”,q入用户理界面?/p> <p><br>2.2.2 d用户<br>?.2.1-2所C页面右边ؓ“新增用户”列,填入你所要增加的用户名称Q姓氏,用户标识Q可自动生成Q,邮g地址Q密码(可自动生成){。可以修改该用户所h的用L和角色信息(也可创徏之后再修改)。用h识必Lpȝ唯一的,所以请保你所输入的用h识与已有的不冲突?br>点击“新增用户”Q我们成功增加一位用hCZؓ“educhina”的用P如图2.2.1-2所C。左侧列表中新增一?#8220;educhina eamoi”。然后我们就可修改这位用L用户l,角色Q个人档案等信息了?br>2.2.3 修改用户<br>选择用户列表中一,然后点击底部的三个编辑按钮,可以分别编辑该用户的用L、角艌Ӏ档案等信息了?br>       此处我们选择用户“educhina eamoi”Q然后选择“~辑档案”Q出现档案编辑页面。如?.2.3-3所C。填写你惌修改的信息,点击对应?#8220;更新”按钮卛_完成修改。需要注意的是整个档案页面分成几个部分,需要分别修Ҏ新?br>选择用户“educhina eamoi”Q然后选择“~辑角色”Q进入角色编辑页面,如图2.2.3-4所C。左侧列表框为当前该用户所h的角Ԍ右侧列表为所有可用的角色。要赋给用户新角Ԍ则从右侧选择一Ҏ多项Q通过中间的{UL钮,从右侧添加至左侧。要删减用户角色Q则从左侧移?<br></p> <img src ="http://www.tkk7.com/junky/aggbug/120397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2007-05-28 10:01 <a href="http://www.tkk7.com/junky/archive/2007/05/28/120397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat下配|liferay portal Q专业配|)http://www.tkk7.com/junky/archive/2007/05/28/120396.htmljunkyjunkyMon, 28 May 2007 02:00:00 GMThttp://www.tkk7.com/junky/archive/2007/05/28/120396.htmlhttp://www.tkk7.com/junky/comments/120396.htmlhttp://www.tkk7.com/junky/archive/2007/05/28/120396.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/120396.htmlhttp://www.tkk7.com/junky/services/trackbacks/120396.html1. 下蝲安装JDK 1.4.2。设|环境变量命名ؓ%JAVA_HOME% q让它指向你的目录?br>2. 下蝲安装Tomcat5.0.x
    3. 创徏 /conf/Catalina/localhost/liferay.xml
    <Context path="" docBase="../liferay" debug="0" reloadable="true" crossContext="true">
     <Resource name="jdbc/LiferayPool" auth="Container" type="javax.sql.DataSource" />
     <ResourceParams name="jdbc/LiferayPool">
      <parameter>
       <name>driverClassName</name>
       <value>org.hsqldb.jdbcDriver</value>
      </parameter>
      <parameter>
       <name>url</name>
       <value>jdbc:hsqldb:test</value>
      </parameter>
      <parameter>
       <name>username</name>
       <value>sa</value>
      </parameter>
      <parameter>
       <name>password</name>
       <value></value>
      </parameter>
      <parameter>
       <name>maxActive</name>
       <value>20</value>
      </parameter>
     </ResourceParams>
     <Resource name="mail/MailSession" auth="Container" type="javax.mail.Session" />
     <ResourceParams name="mail/MailSession">
      <parameter>
       <name>mail.smtp.host</name>
       <value>localhost</value>
      </parameter>
     </ResourceParams>
     <Realm
      className="org.apache.catalina.realm.JAASRealm"
      appName="PortalRealm"
      userClassNames="com.liferay.portal.jaas.PortalPrincipal"
      roleClassNames="com.liferay.portal.jaas.PortalRole"
      debug="99"
      useContextClassLoader="false"
     />
    </Context>
    4. 下蝲 liferay-portal-pro-3.6.1.war?br>5. ~辑 /conf/catalina.properties?br>common.loader=
        ${catalina.home}/common/classes,\
        ...\在这D|后加?br>    ${catalina.home}/common/lib/ext/*.jar
    6. 创徏/conf/Catalina/localhost/tunnel.xml?br><Context path="/tunnel">
     <Realm
      className="org.apache.catalina.realm.JAASRealm"
      appName="PortalRealm"
      userClassNames="com.liferay.portal.jaas.PortalPrincipal"
      roleClassNames="com.liferay.portal.jaas.PortalRole"
      debug="99"
      useContextClassLoader="false"
     />
    </Context>
    7. 创徏/conf/jaas.config?br>PortalRealm {
        com.liferay.portal.jaas.PortalLoginModule required;};
    8. ~辑/bin/catalina.bat
    在rem ----- Execute...中加入:

    set JAVA_OPTS=%JAVA_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config
    9. 解压liferay-portal-pro-3.6.1.warQ创建到%CATALINA_HOME%/liferay目录CQ?CATALINA_HOME%ZQ意目录,最好不带中文)
    10. Ud%CATALINA_HOME%/liferay/WEB-INF/lib 下除util-taglib.jar之外的所?jar包放?common/lib/ext?br>11. 启动TomcatQ在览器地址栏上输入
    http://localhostp看见d界面Q用户名输入Q?/font>test@liferay.com,密码Qtest.

    疑难Q?br>1. 此方法只适应Tomcat5.0.x ?jdk1.4.2Q其他版本搭配,q不一定用;
    2. liferay-portal-pro-3.6.1.war用WinRAR解压卛_Q?br>3. 在安装Tomcat时应注意Q不要让别的E序占用?080端口Q如果占用,可以在安装的时候修改端口,也可以修?br>/conf/server.xmlQport="8082"或其他端口?br>    <Connector 
    port="8080"               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                   enableLookups="false" redirectPort="8443" acceptCount="100"
                   debug="0" connectionTimeout="20000"
                   disableUploadTimeout="true" />
    4.安装完毕Q打开地址时可能报 java.lang.OutOfMemoryErrorQ设|JVM的内存ؓ-Xmx512m?br>附原安装文gQ?/font>

    Tomcat 5.0.x/5.5.x

    Expert


    Download and install JDK 1.4.2 . Set an environment variable

    If you are using Tomcat 5.5.x, you must download and install
    JDK 5.

    Download and install Tomcat.

    You can download Tomcat 5.0.x or Tomcat 5.5.x. This
    documentation assumes that you are using Tomcat
    5.0.x but will also give special instructions for usage with
    Tomcat 5.5.x.

    Create /conf/Catalina/localhost/liferay.xml to set up the
    portal web application.

    <Context
        path=""
        docBase="../liferay"
        debug="0"
        reloadable="true"
        crossContext="true">
    </Context>

    For Tomcat 5.5.x, edit /conf/Catalina/localhost/ROOT.xml.
    You must also remove the reference to
    path="" in the XML.

    Download liferay-portal-pro-3.6.1.war.

    Populate your database with the portal schema and default
    data.


    Edit /conf/catalina.properties.


    common.loader=
        ${catalina.home}/common/classes,\
        ...\
        ${catalina.home}/common/lib/ext/*.jar


    Configure data sources for your database. Make sure the JDBC
    driver for your database is accessible by Tomcat.


    Create a mail session bound to mail/MailSession. You only
    need to set the locations of the IMAP, POP3,
    and SMTP servers.


    Edit /conf/Catalina/localhost/liferay.xml and configure a
    mail session. For Tomcat 5.5.x, edit
    /conf/Catalina/localhost/ROOT.xml.


    <Context...>
        <Resource
            name="mail/MailSession"
            auth="Container"
            type="javax.mail.Session"
        />
        <ResourceParams name="mail/MailSession">
            <parameter>
                <name>mail.store.protocol</name>
                <value>imap</value>
            </parameter>
            <parameter>
                <name>mail.transport.protocol</name>
                <value>smtp</value>
            </parameter>
            <parameter>
                <name>mail.imap.host</name>
                <value>localhost</value>
            </parameter>
            <parameter>
                <name>mail.pop3.host</name>
                <value>localhost</value>
            </parameter>
            <parameter>
                <name>mail.smtp.host</name>
                <value>localhost</value>
            </parameter>
        </ResourceParams>
    </Context>


    Configure JAAS.

    Edit /conf/Catalina/localhost/liferay.xml and configure a
    security realm. For Tomcat 5.5.x, edit
    /conf/Catalina/localhost/ROOT.xml.


    <Context...>
        <Realm
            className="org.apache.catalina.realm.JAASRealm"
            appName="PortalRealm"
         
    userClassNames="com.liferay.portal.jaas.PortalPrincipal"
            roleClassNames="com.liferay.portal.jaas.PortalRole"
            debug="99"
            useContextClassLoader="false"
        />
    </Context>

    Repeat this step for a file called
    /conf/Catalina/localhost/tunnel.xml if you want to enable
    Liferay's
    HTTP tunneling.

    Create /conf/jaas.config.


    PortalRealm {
        com.liferay.portal.jaas.PortalLoginModule required;};

    Edit /bin/catalina.bat so that Tomcat can reference the
    login module.


    ...

    rem ----- Execute...

    set JAVA_OPTS=%JAVA_OPTS%
    -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.
    config


    Deploy liferay-portal-pro-3.6.1.war.


    Unpack liferay-portal-pro-3.6.1.war to
    %CATALINA_HOME%/liferay.

    Move every jar except util-taglib.jar from
    %CATALINA_HOME%/liferay/WEB-INF/lib to /common/lib/ext.
    This step is only necessary if you plan to hot deploy
    portlet WARs.


    Start Tomcat.

    If you get a java.lang.OutOfMemoryError exception while
    starting up Tomcat, give your JVM more memory
    by setting -Xmx512m.


    Open your browser to http://localhost. Click on My Liferay
    at the upper right hand corner to enter the
    login screen. Your login is
    test@liferay.com and your
    password is test.



    junky 2007-05-28 10:00 发表评论
    ]]>
    Portal Framework介绍Q第一部分Q?/title><link>http://www.tkk7.com/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.tkk7.com/junky/archive/2007/05/28/120394.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/120394.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2007/05/28/120394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/120394.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/120394.html</trackback:ping><description><![CDATA[     摘要: ??    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?..  <a href='http://www.tkk7.com/junky/archive/2007/05/28/120394.html'>阅读全文</a><img src ="http://www.tkk7.com/junky/aggbug/120394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2007-05-28 09:59 <a href="http://www.tkk7.com/junky/archive/2007/05/28/120394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://jxxitutu.com" target="_blank">jizz߹ۿ</a>| <a href="http://nnlxl.com" target="_blank">AV벻߲</a>| <a href="http://caoliushequ9.com" target="_blank">Ʒѹۿ</a>| <a href="http://0149545.com" target="_blank">˾ҹƵ</a>| <a href="http://aijiu868.com" target="_blank">޹ƷۺϾþþ </a>| <a href="http://gxnnzk.com" target="_blank">һav</a>| <a href="http://amgzh.com" target="_blank">Ʒһ</a>| <a href="http://avyjj.com" target="_blank">avѴƬ߹ۿ</a>| <a href="http://tccqdy.com" target="_blank">AV˾Ʒһ </a>| <a href="http://xbooktxt.com" target="_blank">ϺƷAV߲</a>| <a href="http://laxdz.com" target="_blank">ͺˬӲƵ</a>| <a href="http://ninggelang.com" target="_blank">߹ۿ޵Ӱ</a>| <a href="http://2c06xyz.com" target="_blank">һ</a>| <a href="http://scycho.com" target="_blank">޺ݺady޾Ʒ</a>| <a href="http://gachi1151.com" target="_blank">޾þþþþ</a>| <a href="http://jack-fx.com" target="_blank">޹˾þۺ</a>| <a href="http://tlyihong.com" target="_blank">վ߹ۿ</a>| <a href="http://99rlcf.com" target="_blank">ٸ̫߳ˬ߹ۿ</a>| <a href="http://shaolingtongluo.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://ttvv77.com" target="_blank">eeuss߱ѹۿ</a>| <a href="http://lfpfjc.com" target="_blank">vպv</a>| <a href="http://xxyy66.com" target="_blank">ۺϾþ</a>| <a href="http://caobi97.com" target="_blank">AVɫ߹ۿ</a>| <a href="http://xuanzhicity.com" target="_blank">޾Ʒպ</a>| <a href="http://jlzjjy.com" target="_blank">ۺɫAPP</a>| <a href="http://hairdehf.com" target="_blank">Ƶѿ</a>| <a href="http://pjappuiehjdkhsjkssd2.com" target="_blank">þþþþþۺձ</a>| <a href="http://zjtuhui.com" target="_blank">ԺԺҳ</a>| <a href="http://www-60060.com" target="_blank">޹v߹ۿ</a>| <a href="http://aabbcc567.com" target="_blank">ֻˬƵѿ</a>| <a href="http://91xx8.com" target="_blank">ѹƷƵ</a>| <a href="http://csl-chinga.com" target="_blank">һƬaƵѹۿ</a>| <a href="http://6789311.com" target="_blank">պӰ</a>| <a href="http://nn227.com" target="_blank">޳˸</a>| <a href="http://hivzx.com" target="_blank">޾Ʒ </a>| <a href="http://www9k832.com" target="_blank">ݹѹǹ</a>| <a href="http://f2dai.com" target="_blank">߳ëƬڵƵ</a>| <a href="http://nit8.com" target="_blank">VƬ߹ۿ</a>| <a href="http://0551dfcy.com" target="_blank">պһƵ</a>| <a href="http://8123pp.com" target="_blank">˾Ʒ</a>| <a href="http://jipiao020.com" target="_blank">պһƵ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>