﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Open-Open-随笔分类-Portal</title><link>http://www.blogjava.net/realzar/category/13097.html</link><description>皇家撒拉哥萨</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:58:33 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:58:33 GMT</pubDate><ttl>60</ttl><item><title>Jetspeed-2 心得隨筆(5)(完)-Security </title><link>http://www.blogjava.net/realzar/archive/2006/07/17/58617.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Mon, 17 Jul 2006 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/17/58617.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58617.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/17/58617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58617.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58617.html</trackback:ping><description><![CDATA[
		<span class="javascript" id="text140941">Jetspeed2 Security介紹的官方連結: <br />[url]http://portals.apache.org/jetspeed-2/multiproject/jetspeed-security/[url] <br /><br />J2使用JAAS的來處理security有關的問題。以之前裝在Tomcat上的J2為例，可以由c:\tomcat\conf\Catalina\localhost\jetspeed.xml及C:\tomcat\webapps\jetspeed\WEB-INF\web.xml看到有關JAAS Realm及login的設定。 <br /><br />大致上來說，JAAS包含Principal、Permission、Policy三個概念。在J2中有user、role、group三種Principal。而Permission基本上有page、portlet，tab等等，當然也可以增加自訂的Permission。至於Policy，J2並沒有使用JAAS的policy檔，而是使用自帶的RdbmsPolicy，也就是把Policy的資訊存在資料庫中；而透過"適當"的實作和設定，J2也可以使用相關App Server的JAAS。 <br /><br />底下是官方的security元件架構圖： <br /><img src="http://www.javaworld.com.tw/jute/gallery/d/2/d2F5eW91bmc=/1137159535064.png" border="0" /><br />在J2中，核心的部份就是"J2 Security Coarsed Services"裡的4個Manager元件。J2的JAAS login module實際上是使用UserManager來進行authentication；UserManager透過OJB自資料庫中取出user的資料例如UserPrincipal、Crendential等並進行authorization. <br /><br />當透過UserManager認證完成以後，J2會同時將此User相對應的所有Principal取出並建立此User的Subject。此後，當SecurityValve執行時，就會呼叫JAAS的Subject.doAsPrivileged(Subject,PrivilegedAction,AccessControlContext)進行有關authorization的動作。有興趣的可以參考org.apache.jetspeed.security.impl.AbstractSecurityValve的原始碼。 <br /><br />J2在security的部份也提供了SPI的設計供開發人員加入自訂的認證方式，例如使用LDAP，參考底下官方的連結<a class="ilink" href="http://portals.apache.org/jetspeed-2/multiproject/jetspeed-security/ldap.html" target="_blank">http://portals.apache.org/jetspeed-2/multiproject/jetspeed-security/ldap.html</a>可以知道如何使用LDAP來進行J2上的認證。 <br /><br />關於J2，其實還有很多部份值得介紹，例如Bridge、Profiler等等。可惜這些部份小弟並不是十分的了解，期待日後有更多高手能夠對J2做更多的介紹，小弟在此先向大家跪謝啦!!Orz </span>
		<br />
		<br />
<img src ="http://www.blogjava.net/realzar/aggbug/58617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-17 17:22 <a href="http://www.blogjava.net/realzar/archive/2006/07/17/58617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jetspeed-2 心得隨筆(4)-Portal Page的呈現</title><link>http://www.blogjava.net/realzar/archive/2006/07/17/58610.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Mon, 17 Jul 2006 09:06:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/17/58610.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58610.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/17/58610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58610.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58610.html</trackback:ping><description><![CDATA[
		<span class="javascript" id="text140002">先看一下在JSR168中提到的Portal page，可以了解一個Portal Page上大概有哪些element： <br /><img src="http://www.javaworld.com.tw/jute/gallery/d/2/d2F5eW91bmc=/1136447867343.png" border="0" /><br /><br />OK...進入本次主題 <br /><br /><b>PSML</b>: <br />PSML的全名是Portal Structure Markup Language。J2用PSML來定義Portal內的各種resource，包括Page、Folder、Link、Security、Menus等等，有關J2的PSML詳細介紹在此<a class="ilink" href="http://portals.apache.org/jetspeed-2/guides/guide-psml.html" target="_blank">http://portals.apache.org/jetspeed-2/guides/guide-psml.html</a>。 <br /><br />這裡要特別提一下PSML Page。在J2中，一個PSML Page就代表一個Portal page，其根元素為&lt;page&gt;，裡面指定了這個Portal page所包含的portlet及排列方式(ex: 2行或3行)、這個Portal page所使用的樣板(稍後會提到的<b>layout</b>)還有這個Portal page的外觀(稍後會提到的<b>decoration</b>)等等。 <br /><br />另外一個要特別說明的是在PSML Page中所使用的&lt;fragment&gt;這個tag。fragment有portlet和layout二種，用type這個屬性來區別；&lt;fragment type="portlet"&gt;代表一個portlet，&lt;fragment type="layout"&gt;代表這個page所用的layout；然而不管是哪一種fragment，name屬性的值都應該依照"portlet-app-id::portlet-id"的格式。 <br /><br />以之前範例中的Sample.psml為例，根元素是&lt;page&gt;，所以這是一個PSML Page；第一個&lt;fragment&gt;是layout fragment，指定了這個page所使用的layout，name屬性的值為"jetspeed-layouts::VelocityTwoColumns"。第二個&lt;fragment&gt;就是範例的echo portlet，name屬性的值為"sample::EchoPortlet"，就符合之前所描述的格式。 <br /><br />事實上，layout fragment其實也是portlet。看一下C:\tomcat\webapps\jetspeed\WEB-INF\apps\裡有一個jetspeed-layouts目錄，就是J2內部的一個Portlet application。因此"jetspeed-layouts::VelocityTwoColumns"會對到這個目錄下portlet-id為VelocityTwoColumns的portlet。總之，<b>J2的layout也是portlet</b>，如果再研究一下，其實還是個Velocity Bridge的portlet. <br /><br /><b>layout:</b><br />J2中的<b>layout</b>指的是用來排列Portal page中各個portlet的樣板。預設的情況下，J2用Velocity來實現<b>layout</b>。 <br /><br /><b>decoration:</b><br />J2中的<b>decoration</b>是用來裝飾Portal page和portlet使其美觀，分為layout-decoration和portlet-decoration兩種。layout-decoration負責一整個Portal page(因此叫page-decoration)，而portlet-decoration負責每一個Portlet fragment。預設的情況下，J2用Velocity和CSS來實現<b>decoration</b>。當J2在呈現一Portal page時，會依照這個Portal page指定的<b>layout</b>來排列這個page上的各個portlet，並且使用這個page所指定的layout-decoration和portlet-decoration來美化這個page和所有的portlet。有關<b>decoration</b>的細節可參考<a class="ilink" href="http://portals.apache.org/jetspeed-2/guides/guide-decorators.html" target="_blank">http://portals.apache.org/jetspeed-2/guides/guide-decorators.html</a><br /><br /><b>Aggregator:</b><br />在J2中，一個Portal page的request最後通常會傳給一個<b>Aggregator</b>，然後由<b>Aggregator</b>負責跟Portal page內包含的所有portlet溝通並聚合各個portlet fragment以產生整個Portal page。以之前舉例的<i>jetspeed-pipeline</i>來說(C:\tomcat\webapps\jetspeed\WEB-INF\assembly\pipelines.xml)，可以看到<i>aggregatorValve</i>這個bean被注入了<i>org.apache.jetspeed.aggregator.PageAggregator</i>這個<b>Aggregator</b>；再參考C:\tomcat\webapps\jetspeed\WEB-INF\assembly\aggregation.xml中，可已知道這個bean的實作是org.apache.jetspeed.aggregator.impl.PageAggregatorImpl。 <br /><br />來看一下這個PageAggregatorImpl的中用來產生Portal page的方法(部份省略修改): <br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>void</b></font> build( RequestContext context )<font class="java-bracket">{</font><font class="java-comment">//取得requested page</font>
    ContentPage page=context.getPage();
   
    <font class="java-comment">//取得 root fragment</font>
    ContentFragment root = page.getRootContentFragment();
    
    <font class="java-comment">//aggregate及render各個Portlet，基本上render的結果都寫到context裡</font>
    aggregateAndRender(root, context, page);
 
    <font class="java-comment">//將結果寫入response</font>
    context.getResponse().getWriter().write(root.getRenderedContent());
    
<font class="java-bracket">}</font></pre></td></tr></tbody></table><br /><br />首先要注意一下傳入的是一個J2的RequestContext物件，基本上可以視為是用來存放這次request相關資訊的一個context；此外，可以把ContentFragement物件視為portlet。而其中第6行取得root fragment，實際上就是取得前面所說的layout fragment，也就是"jetspeed-layouts::VelocityTwoColumns"這個portlet。 <br /><br />接著再看一下第9行的aggregateAndRender()方法(部份省略修改)： <br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>protected</b></font><font class="java-reserved_word"><b>void</b></font> aggregateAndRender( ContentFragment f, RequestContext context, ContentPage page )<font class="java-bracket">{</font>
 
    Iterator children = f.getContentFragments().iterator();
    <font class="java-reserved_word"><b>while</b></font> (children.hasNext())<font class="java-bracket">{</font>
        ContentFragment child = (ContentFragment) children.next();
        
        <font class="java-comment">//遞迴</font>
        aggregateAndRender(child, context, page);
    <font class="java-bracket">}</font><font class="java-comment">// 開始真正做render的動作，基本上render的結果都寫到context裡</font>
     renderer.render(f, context);  <font class="java-comment">//renderer是org.apache.jetspeed.aggregator.impl.PortletRendererImpl</font><font class="java-comment">//加上decoration</font>
     addStyle(context, f.getDecorator(),ContentFragment.PORTLET);
       
<font class="java-bracket">}</font></pre></td></tr></tbody></table><br /><br />由上面的code，可以了解到J2先把整個page上所有的portlet由外到內串起來，再由內到外一個一個做render的動作，而每render完一個portlet，就加上對應的decoration，直到做完整個page。 <br /><br />在第12行中，render的動作實際上是renderer透過Pluto來呼叫portlet(實際上是ContentFragment物件被包成portlet window)的render方法。PortletRendererImpl.render()這個方法裡使用了常見的Worker Thread和Observer樣式，以達到render多個portlet的功能，有興趣的不妨研究一下。 <br /><br />那如果想要新加外觀呢??最簡單的方式，就是先參考J2的layout portlet寫自已的layout，然後加入decoration。講起來容易，不過layout可是不太容易寫的，因為牽扯到的技術還蠻多，而且對J2也要有一定了解；但是如果能做出來，安裝就不會太麻煩。也許等以後J2紅起來以後，會有各式各樣的外觀可以玩吧...<img alt="Cool" src="http://www.javaworld.com.tw/jute/images/smiles/smile_cool.gif" width="15" /><br /><br />其他參考資料： <br />Portal Design Doc : <a class="ilink" href="http://portals.apache.org/jetspeed-2/guides/guide-portal-design.html" target="_blank"><font color="#004080">http://portals.apache.org/jetspeed-2/guides/guide-portal-design.html</font></a><br />簡介J2中有關Portal Page的一些概念 <br /><br />Jetspeed Power Tool (JPT) : <a class="ilink" href="http://portals.apache.org/jetspeed-2/guides/guide-jpt.html" target="_blank"><font color="#004080">http://portals.apache.org/jetspeed-2/guides/guide-jpt.html</font></a><br />開發layout和decoration時會用到 </span>
		<br />
<img src ="http://www.blogjava.net/realzar/aggbug/58610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-17 17:06 <a href="http://www.blogjava.net/realzar/archive/2006/07/17/58610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jetspeed-2 心得隨筆(3)-Overview </title><link>http://www.blogjava.net/realzar/archive/2006/07/17/58609.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Mon, 17 Jul 2006 09:05:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/17/58609.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58609.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/17/58609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58609.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58609.html</trackback:ping><description><![CDATA[
		<span class="javascript" id="text137914">Jetspeed1是我接觸到第一個Portal Server。可惜其獨特的架構，我一直沒辦法接受。後來因為工作上的需要，弄了很久的WebSphere Portal Server，卻總是有一種被IBM欺負的感覺。最近和Jetspeed2相處一陣子後，覺得J2蠻不錯的；儘管release的比較慢，可是架構、功能和速度個人都覺得滿意。寫下一些個人心得，希望有更多能人加入J2，一起開發一些有用的元件和管理設定的portlet，讓J2完美。 <br /><br />由衷希望J2能超越WPS...哈哈。 <br /><br />J2的feature很多，請務必連至<a class="ilink" href="http://portals.apache.org/jetspeed-2/features.html" target="_blank">http://portals.apache.org/jetspeed-2/features.html</a>瀏覽一下。另外對Spring、Velocity、JAAS，JSR168的了解是一定要的。 <br /><br />OK，碎碎唸完畢。今天介紹一下J2的一些觀念，如果有錯誤，請大家不吝指正。 <br />(文章中提到的一些檔案路徑，是依照之前寫的範例。) <br /><br />先來一張官方的overview流程 <br /><img src="http://www.javaworld.com.tw/jute/gallery/d/2/d2F5eW91bmc=/1135076743367.gif" border="0" /><br />在這張圖中，J2算是位於Engine的部份，而Container是Pluto Portlet Container，Portlet就是自已寫的Portlet；所以這張圖正好對照JSR168中的Portal--Portlet Container--Portlet的概念。要特別注意的是，圖中在Engine和Container之間有很多個雙向的箭頭，這代表整個流程可能會在這裡來來回回地執行。 <br />至於這圖大概可以這樣說明: <br /><blockquote><font color="#0000a0">1 request送至server後由JetspeedServlet(org.apache.jetspeed.JetspeedServlet)接收 <br /><br />2 JetspeedServlet透過Jetspeed(org.apache.jetspeed.Jetspeed)取得ComponentManager，然後透過ComponentManager取得RequestContextComponent(org.apache.jetspeed.request.JetspeedRequestContextComponent) <br /><br />3 RequestContextComponent會針對這個request建立一個RequestContext(org.apache.jetspeed.JetspeedRequestContext)，並且讓這個request和新建的RequestContext能互相參照 <br /><br />4 呼叫Engine(org.apache.jetspeed.JetspeedEngine)的service()方法，這個方法會把剛剛建立的RequestContext傳入，這樣後面的元件才能使用 <br /><br />5 在service()方法中，Engine會依據request的目標URL來取得相對應的Pipeline(org.apache.jetspeed.pipelineJetspeedPipeline)來處理。Pipeline使用了chain of responsibility的pattern，是由一堆Valve(org.apache.jetspeed.pipeline.valve.Valve)串起來的 <br /><br />6 各個Valve依序執行，其中某些Valve會和Container動作，某些Valve會負責產生要response的portal頁面。在這個過程中，Continer會執行相關的Portlet，並將結果返回至Pipeline，也就是Valve chain中。 <br /><br />7 將產生的portal頁面傳回給user，流程結束</font></blockquote><br /><br />由上面的介紹，應該可以體會到Pipeline在J2中是非常重要的元件。這裡附上Pipeline的官方UML簡圖做參考 <br /><img src="http://www.javaworld.com.tw/jute/gallery/d/2/d2F5eW91bmc=/1135077044603.gif" border="0" /><br /><br />而J2本身是Spring-based的架構，主要的Spring設定檔都在"C:\tomcat\webapps\jetspeed\WEB-INF\assembly"下。JetspeedServlet在init時會建立Spring容器並載入這些設定檔，而之前提到的ComponentManager就可以透過name或class在Spring容器中尋找需要的component。有關J2的component，請務必參考<a class="ilink" href="http://portals.apache.org/jetspeed-2/guides/guide-components.html" target="_blank">http://portals.apache.org/jetspeed-2/guides/guide-components.html</a>及原始碼。 <br /><br />來看一下目錄中的pipelines.xml。這個XML是用來組合各個Pipeline和設定各Pipeline和其對應的URL。先看一下最後一段bean id="pipeline-map"的部份，在這邊可以看到URL和其相對應的Pipeline。另外找到bean id="jetspeed-pipeline"這一段，可以看到這個Pipeline中Valve的組合，而這個Pipeline也是default的Pipeline；有興趣的不妨參考這份XML把這個Pipeline中的Valve的原始碼找到翻一翻，大致了解一下每個Valve在做啥，還蠻有幫助的。 <br /><br />如果依照之前所寫的echo portlet，其FORM的action URL起頭為/portal，而Engine會用此做為key由"pipeline-map"中找到"jetspeed-pipeline"這個Pipeline來處理。 <br /><br />底下這個是J2附的Valve官方簡圖，大家參考一下 <br /><img src="http://www.javaworld.com.tw/jute/gallery/d/2/d2F5eW91bmc=/1135076743390.gif" border="0" /> </span>
		<br />
<img src ="http://www.blogjava.net/realzar/aggbug/58609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-17 17:05 <a href="http://www.blogjava.net/realzar/archive/2006/07/17/58609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jetspeed-2 心得隨筆(2)-開發一個簡單的Portlet</title><link>http://www.blogjava.net/realzar/archive/2006/07/17/58607.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Mon, 17 Jul 2006 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/17/58607.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58607.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/17/58607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58607.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58607.html</trackback:ping><description><![CDATA[
		<span class="javascript" id="text137327">這個portlet有一個text欄位輸入字串，submit後會在上方出現剛剛輸入的字串。 <br /><br />1. 延續之前的設定，將c:\tomcat\shared\lib\portlet-api-1.0.jar加入CLASSPATH <br /><br />2. EchoPortlet.java : <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>package</b></font> sample;
 
<font class="java-reserved_word"><b>import</b></font> java.io.IOException;
 
<font class="java-reserved_word"><b>import</b></font> javax.portlet.ActionRequest;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.ActionResponse;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.GenericPortlet;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.PortletException;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.PortletRequestDispatcher;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.PortletSession;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.RenderRequest;
<font class="java-reserved_word"><b>import</b></font> javax.portlet.RenderResponse;
 
<font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>class</b></font> EchoPortlet <font class="java-reserved_word"><b>extends</b></font> GenericPortlet<font class="java-bracket">{</font><font class="java-reserved_word"><b>protected</b></font><font class="java-reserved_word"><b>void</b></font> doView(RenderRequest renderRequest, RenderResponse renderResponse)<font class="java-reserved_word"><b>throws</b></font> PortletException, IOException <font class="java-bracket">{</font>
        renderResponse.setContentType(<font class="java-string">"text/html"</font>);
        
        String jspName = <font class="java-string">"/jsp/echo.jsp"</font>;
       
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);
        rd.include(renderRequest, renderResponse);
  <font class="java-bracket">}</font>
 
  <font class="java-comment">/* (non-Javadoc)
   * @see javax.portlet.GenericPortlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
   */</font><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>void</b></font> processAction(ActionRequest actionRequest, ActionResponse actionResponse) <font class="java-reserved_word"><b>throws</b></font> PortletException, IOException <font class="java-bracket">{</font>
    PortletSession session=actionRequest.getPortletSession();
    session.setAttribute(<font class="java-string">"LAST_TYPED_STRING"</font>,actionRequest.getParameter(<font class="java-string">"input"</font>)) ;
  <font class="java-bracket">}</font><font class="java-bracket">}</font>
 
</pre></td></tr></tbody></table><br /><br />3. echo.jsp <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre>&lt;%@ page language=<font class="java-string">"java"</font> session=<font class="java-string">"true"</font> import=<font class="java-string">"javax.portlet.PortletSession"</font>%&gt;
&lt;%@ taglib uri=<font class="java-string">'/WEB-INF/portlet.tld'</font> prefix=<font class="java-string">'portlet'</font>%&gt;
&lt;portlet:defineObjects/&gt;
&lt;portlet:actionURL var=<font class="java-string">"action"</font> /&gt;
&lt;p&gt;&lt;/p&gt;
&lt;%
PortletSession  portletSession=renderRequest.getPortletSession();
String lastTypedString=(String)portletSession.getAttribute(<font class="java-string">"LAST_TYPED_STRING"</font>);
<font class="java-reserved_word"><b>if</b></font>(lastTypedString!=null&amp;&amp;lastTypedString.length()&gt;0)<font class="java-bracket">{</font>
%&gt;
  The string you typed is:&lt;b&gt;&lt;%=lastTypedString%&gt;&lt;/b&gt;
  &lt;br/&gt;
&lt;%<font class="java-bracket">}</font>%&gt;
  &lt;form action=<font class="java-string">"&lt;%=action%&gt;"</font> method=<font class="java-string">"post"</font>&gt;
    &lt;input type=<font class="java-string">"text"</font> name=<font class="java-string">"input"</font> id=<font class="java-string">"input"</font> /&gt;
    &lt;input type=<font class="java-string">"submit"</font> value=<font class="java-string">"submit"</font> /&gt;
  &lt;/form&gt;
 
&lt;p&gt;&lt;/p&gt;
</pre></td></tr></tbody></table><br /><br />4. Portlet.xml <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre>&lt;?xml version=<font class="java-string">"1.0"</font> encoding=<font class="java-string">"UTF-8"</font>?&gt;
&lt;portlet-app id=<font class="java-string">"sample"</font>&gt;
        &lt;portlet id=<font class="java-string">"EchoPortlet"</font>&gt;
                &lt;portlet-name&gt;Echo Portlet&lt;/portlet-name&gt;
                &lt;portlet-class&gt;sample.EchoPortlet&lt;/portlet-class&gt;
 
                &lt;expiration-cache&gt;30&lt;/expiration-cache&gt;
                &lt;supports&gt;
                        &lt;mime-type&gt;text/html&lt;/mime-type&gt;
                        &lt;portlet-mode&gt;view&lt;/portlet-mode&gt;
                &lt;/supports&gt;
                &lt;supported-locale&gt;en-US&lt;/supported-locale&gt;
                &lt;portlet-info&gt;
                        &lt;title&gt;EchoPortlet&lt;/title&gt;
                        &lt;short-title&gt;EchoPortlet&lt;/short-title&gt;
                        &lt;keywords&gt;EchoPortlet&lt;/keywords&gt;
                &lt;/portlet-info&gt;
                
        &lt;/portlet&gt;
&lt;/portlet-app&gt;
</pre></td></tr></tbody></table><br /><br />5. web.xml <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre>&lt;?xml version=<font class="java-string">"1.0"</font> encoding=<font class="java-string">"UTF-8"</font>?&gt;
&lt;!DOCTYPE web-app PUBLIC <font class="java-string">"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</font><font class="java-string">"http://java.sun.com/dtd/web-app_2_3.dtd"</font>&gt;
&lt;web-app&gt;
  &lt;display-name&gt;Sample&lt;/display-name&gt;
&lt;/web-app&gt;
</pre></td></tr></tbody></table><br /><br />6. 準備sample.war檔，結構如下 ( portlet.tld 可從c:\tomcat\webapps\jetspeed\WEB-INF 拷貝 ): <br /><br /><img src="http://www.javaworld.com.tw/jute/gallery/d/2/d2F5eW91bmc=/1134626855272.png" border="0" /><br /><br />7. 將sample.war拷到 C:\tomcat\webapps\jetspeed\deploy 下 <br /><br />8. 以admin這個帳號登入Jetspeed，點選左方的"Jetspeed Administrative Portlets" <br /><br />9. 點選上方的"PALM"(Portlet Application Lifecycle Management)，可以看到已經deploy的portlet application， 剛剛的sample應該在也在其中。可以從這裡undeploy / delete 不用的portlet application。 <br /><br />10. 接著點選上方的Portal Site Manager，會出現整個site目前的結構。點選"Root Folder"這個節點，右方會出現"Folder Details"的portlet。 <br /><br />11. 點選下方的"[Add Page]"，然後在"Name"、"Title"、"Short Title"都輸入Sample，然後按"Save"。 <br /><br />12. 回到首頁，應該可以看到多了一個"Sample"的tab；在C:\tomcat\webapps\jetspeed\WEB-INF\pages下也多了一個Sample.psml的檔 <br /><br />13. 編輯Sample.psml如下: <br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre>&lt;?xml version=<font class="java-string">"1.0"</font> encoding=<font class="java-string">"UTF-8"</font>?&gt;
&lt;page id=<font class="java-string">"/Sample.psml"</font> hidden=<font class="java-string">"false"</font> version=<font class="java-string">""</font>&gt;
    &lt;title&gt;Sample&lt;/title&gt;
    &lt;short-title&gt;Sample&lt;/short-title&gt;
    &lt;defaults layout-decorator=<font class="java-string">"tigris"</font> portlet-decorator=<font class="java-string">"tigris"</font>/&gt;
    &lt;fragment id=<font class="java-string">"P-1082c720c8c-10000"</font> type=<font class="java-string">"layout"</font> name=<font class="java-string">"jetspeed-layouts::VelocityTwoColumns"</font>&gt;
    
      &lt;fragment id=<font class="java-string">"28825252"</font> type=<font class="java-string">"portlet"</font> name=<font class="java-string">"sample::EchoPortlet"</font>&gt;
        &lt;property layout=<font class="java-string">"TwoColumns"</font> name=<font class="java-string">"row"</font> value=<font class="java-string">"0"</font> /&gt;
        &lt;property layout=<font class="java-string">"TwoColumns"</font> name=<font class="java-string">"column"</font> value=<font class="java-string">"0"</font> /&gt;
      &lt;/fragment&gt;
      
    &lt;/fragment&gt;
&lt;/page&gt;
 
</pre></td></tr></tbody></table><br /><br />14. 點選那個Sample 的tab，Portlet載入後應該就可以看到了 </span>
		<br />
		<br />
<img src ="http://www.blogjava.net/realzar/aggbug/58607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-17 17:03 <a href="http://www.blogjava.net/realzar/archive/2006/07/17/58607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Portlet API参考实现的秘密</title><link>http://www.blogjava.net/realzar/archive/2006/07/16/58404.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Sun, 16 Jul 2006 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/16/58404.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58404.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/16/58404.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58404.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58404.html</trackback:ping><description><![CDATA[译者:HoleXp<br /><br /><b>概要</b><br />    在Stefan Hepper和Stephan Hesmer的portlet系列文章的第二部分中，作者把着笔点从Portlet API的基础概要介绍转移到了Portlet API的参考实现(RI reference implementation也就是Pluto)的细节描述。作者还提供了一系列portlet的实例来说明怎样扩展Portlet API的标准函数。<br />企业portal提供商使用可插的用户接口组件（portlets）向信息系统提供表示层。不幸的是，以前的提供商都只定义了自己的portlet API，在整个行业之中互不相容。为了标准化整个行业进程，Java团体发布了Java规范要求(JSR)168:Portlet规范。<br />    这篇系列文章的第一部分介绍了JSP 168的细节。第二部分重点放在portlet API的参考实现（RI）上，也就是Pluto。此外还提供了一个portlet的实例，读者可以通过这个实例来学习。<br />    文章第一节描述了RI的体系结构，包括portlet容器的可拆卸性的概念和怎样在其他项目中重用portlet容器。第二节介绍了RI的安装和使用，以及怎样快速配置portlet。其中文章还包括一个逐步深入的实例。<br />注意：你可以通过文章之后的资源链接下载原代码<br /><br /><b>Pluto的体系结构</b><br />    让我们先来看一下Pluto的体系结构和一些基本的概念。我们先简要的说明portal的参考实现和portlet容器在整个portal体系结构中的位置。接下来我们在细节方面研究Pluto的体系结构。最后，我们看一下在portlet容器里很有趣的：portlet 展开。<br /><br /><b>关于portal</b><br />       Pluto一般用来演示Portlet API如何工作以及向开发者提供一个测试portlets的实例平台。然而，如果没有驱动来运行和测试portlet容器有点麻烦。Pluto的简单portal组件只是架构于portlet容器，它只满足了JSR 168的基本要求。（相比之下，Apache的开源项目Jetspeed就要专业的多。Jetspeed将着重中在了portal本身而非portlet容器之上，并且更多的考虑了其他团体的需求。）<br />    图一描述了portal的基本体系结构。Portal的网络应用程序处理客户端请求，从用户的当前页面得到portlets，之后调用portlet容器以获得每个portlet的内容。portal使用Portlet 容器的 Invoker API来访问 portlet容器，从 portal看来，portlet 容器的主要接口是支持基于请求的方法调用 portlets。容器用户要想获得portal的相关信息则必须实现portlet容器的Provider SPI (Service Provider Interface)的callback接口。最终，portlet容器通过portlet API调用所有portlet。<br /><br /><b><a class="wiki_link" title="wiki link" href="http://wiki.matrix.org.cn/Wiki.jsp?page=IMG">IMG</a></b> upload/forum/2003114165017.jpg[/IMG]<br /><br />图一：Pluto中的一个简单的portal的结构<br /><br /><b>Portlet容器</b><br />    <br />     Portlet容器是portlet的运行环境，也是每个portal的组成核心。它需要有关portal本身的信息，且它必须重用自身的公共代码。因此，portlet容器和其他portal组件是完全分离的。这就是说，你可以将独立的portlet容器嵌入任意的portal，只要你满足portlet容器的条件，比方说实现所有的SPI。<br />Portlet容器的 Invoker API，或者叫入口点，扮演了portlet容器的主调用接口的角色。Portlet容器的Invoker API将portlet容器的生存周期（init，destroy）和基于请求的调用方法（initPage（），performTitle（），portletService（）等等）结合了起来。因为portlet容器最后调用portlet的方法名有点类似portlet API的主portlet接口，不同的是是否必须要传递portlet定义符。正是因为这个附加的portlet定义符，portlet容器才能正确的调用portlet。<br />    除了要用API访问portlet容器之外，portal还必须扩展portlet容器定义的SPI。因此，RI引入了容器服务：在容器注册过的可拆卸组件提供基础功能并且可扩充。RI包含如下一些容器内的自建服务（前四个必须在运行portlet容器时实现，最后一个是可选的）：<br />&amp;#61548;             信息提供器：给portlet容器提供portal和portal框架的信息。通过这个接口来获得信息和存储portal信息。这些信息包括导航栏里的URL、portlet上下文、portlet模式和窗口状态控制。<br />        工厂管理器：定义了怎么怎样通过工厂方法来获得一个具体实现。（一个标准的portal应该已经存在一个实现。）<br />&amp;#61548;        日志服务：定义了一个日志工具（一个标准的portal应该已经存在一个实现）。<br />&amp;#61548;        配置服务：定义了怎么样获得配置参数（一个标准的portal应该已经存在一个实现）。<br />&amp;#61548;        属性管理器（可选）：属性管理器接口的实现允许处理JSR168规范中定义的属性。<br />严格的说，portlet对象模型也是SPI中的一部分，只是它在SPI中占有一个特殊的地位。Portlet对象模型处理所有的potlet对象，他由一个交织在一起的接口集合组成。因此，不能把他和容器服务分开来考虑。<br /><br /><b><a class="wiki_link" title="wiki link" href="http://wiki.matrix.org.cn/Wiki.jsp?page=IMG">IMG</a></b> upload/forum/2003114165335.jpg[/IMG]<br /><br />图二：portlet容器结构<br /><br /><b>Portlet的部署</b><br /><br />   portlet 容器 架构在servlet容器之上并且增强了它的功能。为了实现它,portlet 容器将原始servlet 加入每一个portlet应用程序的war文件中,这一点我们在图三3中有所描述。部署portlet组件时，先取得原始的war文件，然后向其中加入一个新的或者修改原有的web.xml，并且加入一个servlet作为一个调用点来包装每个portlet。之后， portlet的部署器（？这个原文是Then the portlet deployment passes the modified war file to the application server deployment）会传递一个修改过的war文件到应用服务器，将其部署到应用服务器系统。在portlet的调用过程中,portlet容器调用添加进去的servlet,作为部署portlet的war文件的入口点。<br /><br /><b><a class="wiki_link" title="wiki link" href="http://wiki.matrix.org.cn/Wiki.jsp?page=IMG">IMG</a></b> upload/forum/2003114165353.jpg[/IMG]<br /><br />图三：RI中portlet的部署<br /><br /><b>Pluto和WSRP标准</b><br /><br />   正像第一部分所描述的那样，JSR 168与远程portlet网络服务（the Web Services for Remote Portlets (WSRP)）标准紧密结合。几乎同时形成的这两种标准发布了开源实现，实现了在各自的规范中描述必要的功能。作为共有的目标，两种标准努力能够在一起更好的合作。现在，portlet容器可以很好的运行WSRP portlet。<br />Pluto可以在一个portal中运行多个portlet容器。从而Pluto的portlet容器可以被初始化多次。更重要的是，可以用不同的方式来初始化它。每一个portlet容器可以使用SPI的不同实现。<br /><br /><b>RI的安装</b><br /><br />   你会发现Pluto的安装过程非常简单。执行install命令，build目录/build下的install.bat或者install.sh。接下来安装程序会提示你指定Tomcat的安装目录。（注意：在MS windows下文件分隔符不是反斜杠。）<br />在这之后，安装进程会创建RI和所有portlet，安装portlet到指定的Tomcat目录。安装完成后请查看文档以确定完成了所有必要的手工设置工作。<br />现在可以启动Tomcat，通过http://localhost:8080/pluto/portal来访问RI了。<br />就是这么简单！<br /><br /><b>怎样部署portlet</b><br />        <br />      在Pluto中部署portlet和它的安装一样的简单。只要记住你必须首先安装了Pluto，它正确的设置了prepareRun.properties。这是部署过程所必须的。在命令提示符下转到build目录，输入命令deployPortlet.bat ， 用portlet war文件做参数，比如：<br />deployPortlet.bat C:\pluto\portlets\bookmark_04\driver\bookmark_04.war<br /><br /><b>Portlet实例</b><br />     我们来看一个portlet的例子，Bookmark。它充分利用了Portlet API并且阐明了我们学到的概念。我们以一个简单的例子开始，我们在每一节一步步扩展这个Bookmark portlet，最后我们将几乎用到所有的portlet API，把它做成一个高级的portlet。<br />Bookmark portlet：版本一<br />第一个Bookmark portlet用到了Portlet API中如下的一些特性：<br />&amp;#61548;        Portlet API 接口The Portlet API interface<br />&amp;#61548;        Java服务器页面（jsp）JavaServer Pages (JSP) pages<br />&amp;#61548;        Portlet API标签库The Portlet API tag libraries<br />&amp;#61548;        部署描述符Deployment descriptors<br />第一个Bookmark portlet的两个JSP页面分别显示和编辑模式。每个JSP页面只是简单的显示了portlet的当前portlet模式和windwos状态。为了显示这些信息，我们用到了Portlet API标签库（只是部分程序代码，请下载全部代码，不然很难理解：译者注）：<br /><br /><pre class="overflow">public void doView (RenderRequest request,<br />RenderResponse response) throws PortletException, IOException {<br />        response.setContentType("text/html");        <br />        String jspName = getPortletConfig().getInitParameter("jspView");<br />PortletRequestDispatcher rd = <br />                getPortletContext().getRequestDispatcher(jspName);<br />        rd.include(request,response);<br />    }</pre><br />接下来的代码是例子中的一个简单的JSP 页面（即view.jsp：译者注）：<br /><pre class="overflow">&lt;%@ page session="false" %&gt;<br />&lt;%@ page import="javax.portlet.*"%&gt;<br />&lt;%@ page import="java.util.*"%&gt;<br />&lt;%@ taglib uri=&amp;#39;/WEB-INF/tld/portlet.tld&amp;#39; prefix=&amp;#39;portlet&amp;#39;%&gt;<br />&lt;portlet:defineObjects/&gt;<br /><br />Hello,&lt;br&gt;<br />I am the bookmark portlet.&lt;br&gt;<br />&lt;br&gt;<br />Current Portlet Mode: &lt;%=portletRequest.getPortletMode()%&gt;&lt;br&gt;<br />Current Window State: &lt;%=portletRequest.getWindowState()%&gt;&lt;br&gt;<br />&lt;br&gt;</pre><br />Bookmark portlet：版本二<br />        第二个Bookmark portlet进一步深入了Portlet API 的概念。除了第一例子所使用到的Portlet API 特性，它增加了：<br />&amp;#61548;        动作处理Action handling<br />&amp;#61548;        Portlet 参数 Portlet preferences<br />&amp;#61548;        验证参数 A preferences validator<br />&amp;#61548;        在部署描述符中预定义参数 Predefined preferences in the deployment descriptor<br />在第二个Bookmark例子里，两个新的JSP页面替代了版本一中的。首先，edit.jsp允许通过portlet动作添加和删除书签。在这个JSP页面中输入的书签将作为portlet参数存放。其次，view.jsp 以超链接显示出作为portlet参数存放的书签。<br />Bookmark portlet：版本三<br />        新增用到的特性：<br />&amp;#61548;        地区性部署描述符 Localizable deployment descriptor<br />&amp;#61548;        资源包ResourceBundles<br />现在部署描述符和JSP页面从资源包里（ResourceBundles）获得可显示的字符集，他们都可以支持英文和德文了。<br />Bookmark portlet：版本四<br />        最终的这个portlet例子通过portlet API传递递交参量（render parameters）示范了导航的概念（the navigational state concept ）。在版本四里有七个书签，但默认一页只显示四个，如图四所示。通过点击next和back的超链接，用户可以导航到向前或者向后的五个书签。初始点将被初始化为递交参量，使得用户可以使用浏览器的刷新、后退和前进按钮。<br /><br /><b><a class="wiki_link" title="wiki link" href="http://wiki.matrix.org.cn/Wiki.jsp?page=IMG">IMG</a></b> upload/forum/2003114165559.jpg[/IMG]<br /><br />Bookmark portlet版本四的界面<br /><br /><b>Portlet复习</b><br />   <br />   象你所看到的那样，portlet规范的参考实现包括两个部分：portal和portlet容器。Portal作为一个简单的运行portlet容器的测试驱动。Portlet容器作为一个能迅速使用到其他portal（比如jetspeed）里的普通组件。<br />    这个portlet实例用到了许多portlet API里的很重要的概念。你可以用所有portlet API和servlet API的特性来扩展这个实例。比方说你可以用一个servlet在新窗口中输出其他有用的信息，如一个打印预览。还可以通过Http会话与portlet进行交互。实际上，因为portlet是一个强大的技术，能用他实现的功能是无穷无尽的。<br /><br /><img src ="http://www.blogjava.net/realzar/aggbug/58404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-16 11:26 <a href="http://www.blogjava.net/realzar/archive/2006/07/16/58404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jetspeed支持中文本地化 </title><link>http://www.blogjava.net/realzar/archive/2006/07/16/58401.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Sun, 16 Jul 2006 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/16/58401.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58401.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/16/58401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58401.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58401.html</trackback:ping><description><![CDATA[ Jetspeed本身已经解决国际化问题。只要按照Jetspeed的国际化要求进行正确的编码设置和配置，所有网页均可以正确显示。<br />本文教会大家怎么样汉化Jetspeed项目。<br /><br />1.让Jetspeed支持中文本地化。<br />Jetspeed中支持多种语言的本地化，偏偏没有提供中文的本地化，不知道是不是Apache开源组织对中国软件水平的歧视。不管怎样，我们中国人还要靠自己的努力来改变世界对中国软件的看法。废话不说，下面列出中文本地化的步骤：<br /><br />（1）增加本地化属性文件<br />在\WEB-INF\classes\org\apache\jetspeed\modules\localization目录下，存放了Jetspeed使用的本地化属性文件，但是还没有中文本地化属性文件。<br />打开JetspeedLocalization.properties，将该属性文件中的属性值翻译为中文，保存文件到新的文件，如1.properties。再使用转码工具（每个jre里都自带了这个工具）native2ascii .exe将翻译完的属性文件转码成ascii编码：<br />native2ascii 1.properties JetspeedLocalization_zh.properties。<br />最后确保将这个本地化属性文件JetspeedLocalization_zh.properties放在该目录下。<br />注：假如你的Jetspeed项目中类结构已经打包部署，请解开这些类结构，部署到classes目录下，方便修改（此时应将原来的jar包从lib目录下移除）。<br /><br />（2）修改Jetspeed的两个配置文件<br />－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />\WEB-INF\conf\TurbineResources.properties<br />找到相应的属性并修改其值：<br />#Velocity service<br />services.Velocity.input.encoding=UTF-8<br />#Localization service<br />locale.default.language=zh<br />locale.default.country=CN<br />locale.default.charset=GBK<br /><br />－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />\WEB-INF\conf\velocity.properties<br />找到相应的属性并修改其值：<br />#template encoding<br />template.encoding=UTF-8<br /><br />（3）执行完以上两步，打开浏览器，设置浏览器的语言首选项，就可以看到不同语种显示的页面。<br /><br />2.让Jetspeed中的所有页面中文化<br />上个步骤只是让Jetspeed支持中文本地化，指的是Jetspeed中采用国际化技术制作的页面可以正常显示中文。<br />但是并非所有的Jetspeed内部页面都已经采用国际化进行处理。我们需要将所有Jetspeed内部已经制作好的页面模板，包括采用JSP技术制作的jsp页面和采用Velocity制作的vm模板，进行国际化处理。就是说，我们需要将这些页面模板中的静态英文字符串采用国际化技术对其进行封装。<br />具体技术如下：<br />－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />JSP页面：<br />页面中确保加入了：<br /><br />将静态英文字符串替换为<br />在默认本地化属性文件JetspeedLocalization.properties文件中加入：<br />key_name=原来的英文字符串<br />在中文本地化属性文件JetspeedLocalization_zh.properties文件中加入：<br />key_name=英文字符串的汉语翻译<br /><br />－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />VM模板：<br />将静态英文字符串替换为$l10n.key_name<br />在默认本地化属性文件JetspeedLocalization.properties文件中加入：<br />key_name=原来的英文字符串<br />在中文本地化属性文件JetspeedLocalization_zh.properties文件中加入：<br />key_name=英文字符串的汉语翻译<br /><br />注意：<br />（1）JetspeedLocalization_zh.properties文件中的值必须通过native2ascii转码，而不是直接写入中文。<br />（2）所有属性文件中的key_name不得重复出现。<br /><br />3.Jetspeed注册文件的汉化<br />这些注册文件包括Jetspeed的实体注册文件（*.xreg）和Jetspeed站点结构描述文件（*.psml）。这些文件的汉化将影响到Jetspeed最终显示页面中的标题和可选择资源名称的显示。<br />很简单：将这些文件的编码格式改为GBK，然后就可以大肆修改文件中的标题、描述等字符串。注意千万不要直接改动关键字段，如名称、id号之类的。<br />这部分的修改涉及到Jetspeed中的具体资源，要谨慎修改，建议先熟悉其深刻含义。<br />(转载文章请保留出处：<a href="http://www.javajia.com/"><font color="#002c99">Java家(www.javajia.com)</font></a>)<img src ="http://www.blogjava.net/realzar/aggbug/58401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-16 11:04 <a href="http://www.blogjava.net/realzar/archive/2006/07/16/58401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jetspeed模块定制 </title><link>http://www.blogjava.net/realzar/archive/2006/07/16/58399.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Sun, 16 Jul 2006 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/16/58399.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58399.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/16/58399.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58399.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58399.html</trackback:ping><description><![CDATA[ 创建jetspeed新模块可以不用写配置文件，只需要用系统提管的功能就可以实现添加模块的全过程 　<br /><br />1，添加一个简单的模块的全过程： <br />(1)写好一个portlet：Test.vm内容为：this is my test <br />(2)以系统管理员登入jetspeed,帐号admin,jetspeed <br />(3)点击Admin菜单<br />--&gt;选择Portlet Browser<br />--&gt;查看portlet模块（在此可以参考现有的模块的配置信息） <br />--&gt;选择Add Portlet添加新模块 <br />--&gt;Name下为新portlet模块命名,如：Test, <br />--&gt;Type选择ref <br />--&gt;Parent选择CustomizerVelocity <br />--&gt;Class Name可不填（添加时会由Parent自动产生,产生CustomizerVelocity的相应ClassName） <br />--&gt;Security可不选（是模块的权限控制） <br />--&gt;Hidden 不选 <br />--&gt;Application 不选 <br />--&gt;Cached on URL可选也可不选然后Insert Portlet添加portlet完成 <br />(4)修改添加好的portlet模块的其他参数添加后的portlet模块在portlet信息面版中以Imformation显示 <br />&lt;1&gt;（添加）修改Media Type <br />--&gt;选择Media Types <br />--&gt;Media Type 下拉框选择html <br />--&gt;Add Media Type <br />&lt;2&gt;（添加）修改模块分类，任意增加 <br />&lt;3&gt;（添加）修改参数,可添加需要的参数参数name为template，其值value为portlets文件下所对应的文件如Test.vm，则value值为Test 参数action为执行所对应的类，这点可参考其他的porlet模块做法。　<br />这样就完成添加新模块的全过程。所做的操作会自动产生配置文件在/web-inf/conf/下面的local-portlets.xreg里面 <br />2，自已定制的portlet模块的全过程不用写psml文件直接用jetspeed本身的模块定制功能即可：以普通用户登入，如：bluesky,bluesky <br />(1)选择右上角的Customize:旁边的html定制网页风格,wml支持无线，手机等设备的网页 <br />&lt;1&gt;增加菜单--&gt;选择html--&gt;Add Pane增加菜单--&gt;填入Test Menu--&gt;Apply--&gt;Save and Apply 　就完成增加菜单功能 <br />&lt;2&gt;增加portlet模块 <br />--&gt;选择html <br />--&gt;选择Test Menu <br />--&gt;选择Add Portlet <br />--&gt;先择自已想要的模块，CoffeeLists,HelloVelocity等，系统列出所有能够选择的模块，可翻页查找 <br />--&gt;然后一种Apply就可以了返回用户首页，查看自已创建的Test Menu,就可以看到自已选择好的portlet 　模块所做的操作会自动产生配置文件在WEB-INF\psml\user\bluesky<br />　　下面反复测试这两个功能可掌握jetspeed的主要结构，及模块处理方式。里面的布局控制，界面控制，角色控制，基本上都可以通过定制，定制出来，原理与操作过程差不多。<br />(转载文章请保留出处：<a href="http://www.javajia.com/">Java家(www.javajia.com)</a>)<img src ="http://www.blogjava.net/realzar/aggbug/58399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-16 11:03 <a href="http://www.blogjava.net/realzar/archive/2006/07/16/58399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Jetspeed项目中Psml文件的数据库管理 </title><link>http://www.blogjava.net/realzar/archive/2006/07/16/58400.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Sun, 16 Jul 2006 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/16/58400.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58400.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/16/58400.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58400.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58400.html</trackback:ping><description><![CDATA[PSML是Portal Structure Markup Language的缩写。它的目的是为了Jetspeed中内容结构的建设和提取。Jetspeed中支持两种形式的PSML管理：文件系统和数据库管理。<br /><br />何时需要使用数据库存储PSML文件：<br />1 用户数量巨大；<br />2 提高性能和可分布性；<br />3 把Jetspeed的安全性和已有的数据库结合起来；<br />4 使用一个统一、安全的数据库来巩固所有的门户信息。<br /><br />使用数据库存储PSML文件的缺点：<br />1 Jetspeed的运行必须依赖于数据库的运行；<br />2 速度不快的数据库将会影响Jetspeed的性能；<br />3 增加了复杂性；<br />4 你必须使用Jetspeed的PSML定制器来修改PSML文件，或者需要将PSML文件进行导入导出来进行修改，或者使用sql语句来操作复杂的PSML文件修改。<br /><br />具体操作步骤：<br />1 在数据库中建立PSML所需要的3张表。Jetspeed中自带的Hypersonic数据库已经预先建好了这几张表。<br /><br />2 Jetspeed使用Torque来进行数据－值对象的操作、维护.<br />首先编辑配置文件build/torque/dbpsml.properties；<br />再修改数据库schema文件build/torque/schema/dbpsml-schema.xml；<br />用ant进行编译处理，生成java类和sql文件，并执行sql文件。<br /><br />3 配置Jetspeed使用PSML数据库<br />将数据库驱动类的jar包放到特定目录下：webapp/WEB-INF/lib<br />修改配置文件webapp/WEB-INF/conf/Torque.properties<br />torque.database.default.adapter=mysql<br />torque.dsfactory.default.connection.driver = org.gjt.mm.mysql.Driver<br />torque.dsfactory.default.connection.url = jdbc:mysql://localhost:3306/jetspeed<br />torque.dsfactory.default.connection.user =root<br />torque.dsfactory.default.connection.password =<br /><br />4 将PSML文件从文件系统导入到数据库<br />在配置文件JetspeedResources.properties中更改PSML Manager属性值：<br />services.PsmlManager.classname=<br />org.apache.jetspeed.services.psmlmanager.db.DatabasePsmlManagerService<br />services.PsmlImportManager.classname=<br />org.apache.jetspeed.services.psmlmanager.CastorPsmlManagerService<br />使用ant进行导入：<br />ant import<br /><br />5 将PSML文件从数据库中导出到文件系统<br />在配置文件JetspeedResources.properties中更改PSML Manager属性值：<br />services.PsmlManager.classname=<br />org.apache.jetspeed.services.psmlmanager.CastorPsmlManagerService<br />services.PsmlImportManager.classname=<br />org.apache.jetspeed.services.psmlmanager.db.DatabasePsmlManagerService<br />services.PsmlManager.root=/tmp/psml7<br />使用ant进行导出：<br />ant import(转载文章请保留出处：<a href="http://www.javajia.com/"><font color="#002c99">Java家(www.javajia.com)</font></a>)<img src ="http://www.blogjava.net/realzar/aggbug/58400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-16 11:03 <a href="http://www.blogjava.net/realzar/archive/2006/07/16/58400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jetspeed开发实战 </title><link>http://www.blogjava.net/realzar/archive/2006/07/16/58398.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Sun, 16 Jul 2006 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/16/58398.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58398.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/16/58398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58398.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58398.html</trackback:ping><description><![CDATA[jetspeed开发实战 <br /><br />这里假设monsys为web服务的名称，其路径在webapps/下面 <br />1,jetspeed的图片处理图片默认放在monsys/images下面，<br />调用方法：$clink.setURI("images/test.jpg") <br />2,javascript处理 javascript默认放在monsys/javascript下<br />调用方法：$clink.setURI("javascript/test.css") <br />3,portlets的位置位于monsys/WEB-INF/templates/vm/portlets/html下面 <br />4,页面总体布局控制看JetspeedResources.properties <br />bottomnav.enable=true <br />bottomnav.vm=bottom.vm <br />leftnav.enable=true <br />leftnav.vm=left.vm <br />leftnav.width=10% <br />topnav.enable=true <br />topnav.vm=top.vm <br />topnav.logo.file=images/jetspeed-logo-1.5.gif <br />topnav.logo.url= <br />topnav.user_login.enable=true <br />topnav.user_creation.enable=true <br />topnav.my_pages.enable=true <br />5,portlets源代码分析: portlet主要实现三个方法: <br />&lt;1&gt;,buildMaximizedContext最大化 <br />&lt;2&gt;,buildConfigureContext显示信息 <br />&lt;3&gt;,buildNormalContext正常情况,也就是所看到的正常显示时所要显示的信息 <br />&lt;4&gt;,调用时，在添加模块时添加新参数action=portlets.GraphDailyAction <br />package org.apache.jetspeed.modules.actions.portlets; <br />import .............(N个,略) <br />public class GraphDailyAction extends VelocityPortletAction {<br />/**<br />* Subclasses should override this method if they wish to<br />* build specific content when maximized. Default behavior is<br />* to do the same as normal content.<br />*/<br />protected void buildMaximizedContext(VelocityPortlet portlet, Context context, RunData rundata) {<br />buildNormalContext(portlet, context, rundata);<br />String text = (String) context.get("text");<br />if (text == null) {<br />text = "Top Record of baccarat game";<br />}<br />context.put("text", text + " (Maximized !)");<br />}<br />/** <br />* Subclasses should override this method if they wish to <br />* provide their own customization behavior. <br />* Default is to use Portal base customizer action <br />*/<br /><br /><br /><br /><br /><br />protected void buildConfigureContext(VelocityPortlet portlet, Context context, RunData rundata) {<br />buildNormalContext(portlet, context, rundata);<br />setTemplate(rundata, "hello-customize");<br />}<br />/** <br />* 这是主要部份 <br />* Subclasses must override this method to provide default behavior <br />* for the portlet action <br />*/<br /><br /><br /><br /><br /><br />protected void buildNormalContext(VelocityPortlet portlet, Context context, RunData rundata) {<br />String mode = portlet.getPortletConfig().getInitParameter("mode"); //读取添加模块时从配置文件传来的参数<br />String searchdate = rundata.getParameters().getString("searchdate"); //取得从页面提交得到的参数<br />context.put("mode", mode);<br />context.put("searchdate", searchdate) //输出页面要显示的信息,支持输出数组，对像，及容器等形式的数据<br />}<br />}<br /><br />&lt;5&gt;写好源代码，并编译，参考里的：　　<br />1,&lt;3&gt;所建的参数action,其值为portlets.GraphDailyAction，则系统会去执行这个类 <br />(转载文章请保留出处：<a href="http://www.javajia.com/">Java家(www.javajia.com)</a>)<img src ="http://www.blogjava.net/realzar/aggbug/58398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-16 11:02 <a href="http://www.blogjava.net/realzar/archive/2006/07/16/58398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jetspeed介绍 </title><link>http://www.blogjava.net/realzar/archive/2006/07/16/58396.html</link><dc:creator>开源爱好者</dc:creator><author>开源爱好者</author><pubDate>Sun, 16 Jul 2006 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/realzar/archive/2006/07/16/58396.html</guid><wfw:comment>http://www.blogjava.net/realzar/comments/58396.html</wfw:comment><comments>http://www.blogjava.net/realzar/archive/2006/07/16/58396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realzar/comments/commentRss/58396.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realzar/services/trackbacks/58396.html</trackback:ping><description><![CDATA[Jetspeed是一个开放源代码的企业信息门户(EIP)的实现, 使用的技术是Java和XML. 用户可以使用浏览器, 支持WAP协议的手机或者其它的设备访问Jetspeed架设的信息门户获取信息. Jetspeed扮演着信息集中器的角色, 它能够把信息集中起来并且很容易地提供给用户. <br /><br />Jetspeed数据的表现与内容类型无关, 也就是说来自XML, RSS(Rich Site summary)或者SMTP的内容可以用Jetspeed进行整合. Jetspeed支持像Cocoon, WebMacro和Velocity之类的模板和内容发布框架. <br /><br />Jetspeed能够帮助你快速地创建门户应用程序. Jetspeed具有如下的特征: <br /><br />* 即将成为标准化的Java Portlet API<br />* 基于模板的布局, 包括JSP和Velocity<br />* 通过开放的内容同步技术支持远程XML内容交换<br />* 定制默认的主页<br />* 使用数据库进行用户认证<br />* 内存缓存技术, 加快页面的响应<br />* 通过Rich Site Summary技术, 支持同步内容<br />* 和Cocoon, WebMacro, Velocity集成.<br />* Wireless Markup Language (WML) 支持<br />* 使用XML格式的配置文件注册portlet.<br />* 完整的Web Application Archive (WAR) 支持<br />* Web应用程序开发的基础设施<br />* 可以在本地缓存远程内容<br />* 与Avantgo同步<br />* 可移植到所有支持JDK1.2和Servlet 2.2的平台<br />* 与Turbine模块和服务集成<br />* 可以根据用户, 安装媒体类型和语言的不同设定, 产生不同的个性化服务<br />* 持续化服务使得所由的portlet能够容易的存储每个用户的状态, 页面和portlet<br />* 使用皮肤技术使得用户可以选择portlet的颜色和显示属性<br />* 自定义功能是的管理员可以选择portlet以及定义个人页面的布局<br />* 在数据库中存储PSML<br />* 通过Jetspeed的安全portlets管理用户, 组,角色和权限<br />* 基于角色对访问portlet进行控制 <br /><br />版权: The Apache Software License, Version 1.1 详细内容可以看:<br />http://jakarta.apache.org/jetspeed/site/license.html <br /><br />使用Jetspeed架设的门户, 下面是一个我发现的做得最好的:<br />http://www.anglonaweb.it/index.jsp<br /><br /><br /><br />使用Jetspeed架设的门户, 下面是一个我发现的做得最好的:<br />http://www.anglonaweb.it/index.jsp<br /><br /><br /><br />使用Jetspeed架设的门户, 下面是一个我发现的做得最好的:<br />http://www.anglonaweb.it/index.jsp<br />(转载文章请保留出处：<a href="http://www.javajia.com/">Java家(www.javajia.com)</a>)<img src ="http://www.blogjava.net/realzar/aggbug/58396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realzar/" target="_blank">开源爱好者</a> 2006-07-16 11:01 <a href="http://www.blogjava.net/realzar/archive/2006/07/16/58396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>