欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Portlet 应用开发, Part 6 - Portlet 的 Preference对象 网络应用JSPXMLApacheServlet 

程序员文章站 2022-05-19 23:26:57
...
本部分将阐述了Portlet的Preference对象,  Preference 对象是Portlet所特有的对象,用来实现用户的个性化设置,可以替代部分数据库的功能.
• 为什么使用Preference 对象?
Preference 主要用来帮助用户对Portlet进行符合用户需要的显示定制或者行为定制.
举一个简单的例子:  用户有一个用来显示商品列表的Portlet, 可能有些用户需要在Portlet窗口中每页显示10个商品, 但是也有用户需要在Portlet的窗口中显示20个或者是30个商品. 这样的话, 对于同一个Portlet应用, 用户可以定制自己满意的用户界面.
以上的Preference 使用有一个前提, Preference对象只用来存取简单的配置信息,并不能替代数据库的应用.
• 如何使用Preference 对象?
Preference对象对于Portlet的配置信息存取使用KEY=VALUE , 或者是 KEY=VALUES 形式.  如果你的Portlet有需要使用用户定制的元素,可以将其加入到Preference对象中. 如下:
PortletPreference p= req.getPortletPreferences();
p.setValue(“PageSize”,”10”);
p.store();
• Preference的属性的作用范围
因为Preference的属性是用来存取用户的个性化信息的, 因此两个用户之间不可以share属性.
注: Pluto因为是单用户的Portal/PortletContainer的实现,因此如果两个用户使用同一个preference属性名称,互相会有冲突.
• 如何配置Preference 属性?
在Portlet.xml中设置Preference的初始或者是默认属性. 如下:
<portlet-preferences>
  <preference>
    <name>PageSize</name>
    <value>20</value>
    <read-only>true</read-only>
  </preference>
</portlet-preferences>
在以上配置中配置了一个preference 属性PageSize, 注意read-only标签中设置了true, 那么这样一来这个preference 属性便不可以通过编程更改.
• 为什么使用PreferencesValidator对象?
PreferencesValidator对象允许Portlet的preference在被储存之前进行验证.用以保证portlet的Preference存取的正确性.
• 如何配置PreferencesValidator对象 ?
Servlet开发中有一种叫filter Servlet, 它的配置和PreferencesValidator的配置方式非常相似, 只不过一个在web.xml中配置, 而另一个在portlet.xml中配置. 如下XML:
<portlet-preferences>
<preferences-validator>
com.sss.PortletValidator
</preferences-validator>
</portlet-preferences>

• Case Study
以下我们将使用Preference和PreferencesValidator对象来开发一个简单的Portlet实现一个简单的用户登陆auditing. 以下是代码片段:
1. Portlet (PortletPreferenceExample.java)
         … …
PortletPreferences prefs = request.getPreferences();
prefs.setValue("audit_enabled",audit_enabled);
prefs.store();
… …

   以上代码片段将一个Portlet的配置参数audit_enabled赋予相应的值.
  … …
PortletPreferences prefs = request.getPreferences();
prefs.reset("audit_enabled");
prefs.store(); 
… …
以上代码片段将一个Portlet的配置参数audit_enabled重新reset到初始时Portlet.xml配置文件中audit_enabled所对应的值.
2. JSP (edit_preference.jsp)

<%
PortletPreferences prefs = renderRequest.getPreferences();
String flag=prefs.getValue("audit_enabled","").toString();
%>
    Edit 模式下Fragment 用来取得 Preference 的KEY值的代码 .

3. JSP (view_portletpreference.jsp)
<%
PortletPreferences prefs = renderRequest.getPreferences();
String flag=prefs.getValue("audit_enabled","").toString();
%>
   View 模式下Fragment 用来取得 Preference 的KEY值的代码.

     4. PreferencesValidator (PortletPreferencesValidator.java)
public class PortletPreferencesValidator implements
PreferencesValidator{
… …
… …
public void validate(PortletPreferences preferences)
  throws ValidatorException
  {
  … …
  … …
  }
}
PortletPreferencesValidator执行了PreferencesValidator接口, 其具体的功能实现由validate方法执行. 我们这里将应用逻辑在validate方法中执行. 其功能主要是验证KEY所对应的值是否符合要求.(本例中Validator将验证audit_enabled所对应的值是否为”0”或者”1”,  否则将抛出错误).
• Preference Portlet的运行结果
将Tomcat启动, 在IE 或者 NetScape 中敲入以下地址:
http://localhost:8080/pluto/portal

  

单击Preference Example Page后可以看到如下页面(图6-1)
图6-1

输入”SpiritSeekerS” , 单击 Enter Button, 进入如下页面 (图6-2)
图6-2
进入edit mode , 将enable audit 选项选中 , 如下(图6-3):
图6-3
单击 SAVE button , 将回到view mode , 再次登陆后, 如下图(图6-4)
图6-4
• 源代码及Portlet相关配置文件
1. Portlet (PortletPreferenceExample.java)
package portlets.portletpreference;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;
public class PortletPreferenceExample  extends GenericPortlet{
  public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("view");
PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);
rd.include(request, response);
  }
  public void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("edit");
PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);
rd.include(request, response);
  }
 

public void processAction(ActionRequest request, ActionResponse response)
        throws PortletException, java.io.IOException
   { 
  
String action = request.getParameter("action");
String audit_enabled = request.getParameter("audit_enabled");


if(action.equals("edit")&&audit_enabled!=null){
  PortletPreferences prefs = request.getPreferences();
  prefs.setValue("audit_enabled",audit_enabled);
  prefs.store();
}else if(action.equals("edit")){
  PortletPreferences prefs = request.getPreferences();
  prefs.reset("audit_enabled");
  prefs.store(); 
}else if(action.equals("view")){
  String usr= request.getParameter("usr");
  response.setRenderParameter("usr",usr);
}
else{
  throw new PortletException("Unexpected Error!");
}
  }
}
2. JSP (view_portletpreference.jsp)
<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<%
PortletPreferences prefs = renderRequest.getPreferences();
String flag=prefs.getValue("audit_enabled","").toString();
%>
<portlet:actionURL portletMode="view" var="url">
<portlet:param name="action" value="view"/>
</portlet:actionURL>
<form method=post action=<%=url%>>
<table border=0>
<tr><td><b>Name:</b></td><td><input type=text name=usr></tr>
<tr><td colspan=2 align=right><input type=submit value="Enter"></td></tr>
</table>
</form>

<%
String usr=renderRequest.getParameter("usr");
if(usr!=null){
  %>Welcome, <%=usr%> !! <BR><%

%>
<%
  if(flag.equals("1")){
%>
===============================================<BR>
<table border=0>
<tr>
  <td><b>INFO:</b> <%=usr.toUpperCase()%> login at </td>
  <td><%=new Date().toString()%></td>
</tr>
</table>
===============================================<BR>
<%
  }
}
%>
3. JSP (edit_portletpreference.jsp)
<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<%
PortletPreferences prefs = renderRequest.getPreferences();
String flag=prefs.getValue("audit_enabled","").toString();
%>

<portlet:actionURL portletMode="view" var="url">
<portlet:param name="action" value="edit"/>
</portlet:actionURL>
<form method=post action=<%=url%>>
<table border=0>
<tr>
  <td><b>Auditing Enabled:</b></td>
  <td><input type=checkbox name="audit_enabled" value="1" <%=flag.equals("1")?"checked":""%>></td>
</tr>
<tr>
  <td colspan=2 align=right><input type=submit value="SAVE"></td>
</tr>
</table>
</form>
4. Preference Validator (PortletPreferencesValidator.java)
package portlets.portletpreference;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.util.*;
public class PortletPreferencesValidator implements PreferencesValidator{
public static final String AUDITING_ENABLED="1";
public static final String AUDITING_DISABLED="0";

public void validate(PortletPreferences preferences)
  throws ValidatorException
{
  Enumeration prefnms = preferences.getNames();
  Collection errKeys = new ArrayList();
  while (prefnms.hasMoreElements()){
    String prefnm = prefnms.nextElement().toString();
    String value = preferences.getValue(prefnm, AUDITING_DISABLED);
    System.out.println(value);
    if((value.equals(AUDITING_ENABLED))||(value.equals(AUDITING_DISABLED))){
   System.out.println("#### INFO: VALID KEY.");
    }else{
   System.out.println("#### ERROR: INVALID KEY.");
   throw new ValidatorException("INVALID KEY",new Throwable("Incorrect Value!"),errKeys);
    }
  }
}
}

5. Portlet.xml
… …
<!-- Preference Example -->
<portlet>
  <description>PortletPreference Example</description>
  <portlet-name>PortletPreferenceExample</portlet-name>
  <display-name>PortletPreferenceExample</display-name>
  <portlet-class>portlets.portletpreference.PortletPreferenceExample</portlet-class>
  <init-param>
   <name>view</name>
   <value>/fragments/portletpreference/view_portletpreference.jsp</value>
  </init-param>
  <init-param>
   <name>edit</name>
   <value>/fragments/portletpreference/edit_portletpreference.jsp</value>
  </init-param>
  <expiration-cache>-1</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
   <portlet-mode>VIEW</portlet-mode>
   <portlet-mode>EDIT</portlet-mode>
  </supports>
  <supported-locale>en</supported-locale>
  <portlet-info>
   <title>PortletPreference Example</title>
   <short-title>PortletPreference</short-title>
   <keywords>PortletPreference</keywords>
  </portlet-info>
  <portlet-preferences>
   <preference>
    <name>audit_enabled</name>
    <value>0</value>
   </preference>
   <preferences-validator>portlets.portletpreference.PortletPreferencesValidator</preferences-validator>
  </portlet-preferences>
</portlet>

… …
6. pageregistry.xml
… …
<!-- Preference Example Page -->
    <fragment name="preferencepage" type="page">
        <navigation>
            <title>Preference Example Page</title>
            <description>Preference Example Page</description>
        </navigation>
        <fragment name="row1" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.70"/>
                </fragment>
            </fragment>
        </fragment>
</fragment>
… …
7. portletregistry.xml
… …
        <portlet id="70">
<definition-id>portlets.PortletPreferenceExample</definition-id>
</portlet>
       … …

资源:
• Pluto
http://jakarta.apache.org/pluto
• Pluto Mail List
http://news.gmane.org/gmane.comp.jakarta.pluto.user
• WSRP Spec1.0
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
• Apache的WSRP实现
http://ws.apache.org/wsrp4j/
• Apache’s Portal, JetSpeed:
http://jakarta.apache.org/jetspeed/site/index.html
• JSR 168:
http://www.jcp.org/en/jsr/detail?id=168
• "Portlet 规范介绍" By Stefan Hepper 和 Stephan Hesmer
Part 1: Get your feet wet with the specification's underlying terms and concepts (August 2003)
Part 2: The Portlet API's reference implementation reveals its secrets (September 2003)



Java Portlet 应用开发, Part 5 - Portlet 的 Session对象
By Jia.li(Terry.li)
SpiritSeekerS@sqatester.com

本系列前一部分阐述了Portlet的Request和Response对象,本部分继续讲解Portlet中Session对象.及其与Servlet中Session对象的不同点.
• Portlet Session中存取对象的作用范围 (Scope)
Servlet中的Session属性和Portlet中的Session属性有一个非常大的不同点, 由于Portlet处于Portal中的缘故, Portlet的Session属性分为两种, 分别作用于不同的范围中:
1.  Application Scope
2.  Portlet Scope
这两者的区别在于:
1) Application Scope类型的PortletSession中保存的对象对于同一个Portlet Application中的所有其它Portlet来说是可以被访问到的.
2) Portlet Scope类型的PortletSession中保存的对象对于同一个Portlet Application中的所有其它Portlet来说是不可见的.
但对于Portlet Application来说,其实它也是个Web Application , 因此不论是Application Scope也好,或者是Portlet Scope也好,同样都属于HttpSession,因此都可以通过HttpSession 来访问.
实际上Application Scope的Session就是HttpSession , 而Portlet Scope的Session 由于不可被其他Portlet访问, 它的session属性名称有它独特的存取方式, 如下:
javax.portlet.p.<ID>?<ATTRIBUTE_NAME>
其中ID是Portal/Portlet-Container生成用来唯一确定一个Portlet.
Portlet Scope 的Session 使用以上的Attribute Name 用以存取Session上绑定的属性.  我们所设制的Portlet Scope 的Session属性由Portlet容器自动转化成以上格式. 用以保证不被其它的Portlet访问到.
注:  以javax.portlet开头的Session属性名称是保留的,不可以用于Portlet的Session 属性名称.
• Case study: 不同Scope Session的比较

以下我们将编码实现两个Portlet, 其中一个用来创建session属性的Portlet 和另一个用来验证session属性作用范围的Portlet. 用以验证Session属性的正确性.

1. Portlet (PortletSessionExample1_GenerateSesssion.java)
… …
public void processAction(ActionRequest request,ActionResponse response)
  throws PortletException,IOException{
  String action=request.getParameter("ACTION");
  if(action.equals("ApplicationScope")){
   PortletSession ps=request.getPortletSession();
   ps.setAttribute("PortletSession.AS",action,PortletSession.APPLICATION_SCOPE);
  }else{
   PortletSession ps=request.getPortletSession();
   ps.setAttribute("PortletSession.PS",action,PortletSession.PORTLET_SCOPE);  
  }
   }

      … …

以上代码片段根据不同参数分别产生不同Scope的PortletSession 的属性 , 作用范围分别为Application 和 Portlet.
2. Portlet (PortletSessionExample1_DisplaySession.java)
这个Portlet调用一个JSP (jspShowSession.jsp) 来获得Portlet session和HttpSession, 并且示出来.
3. JSP(view_portletsession1_generatesession.jsp)
这个JSP将创建两个ActionURL , 分别用来产生两种PortletSession属性:
… …
<portlet:actionURL windowState="NORMAL" portletMode="view" var="pu1">
<portlet:param name="ACTION" value="ApplicationScope"/>
</portlet:actionURL>
<portlet:actionURL windowState="NORMAL" portletMode="view" var="pu2">
<portlet:param name="ACTION" value="PortletScope"/>
</portlet:actionURL>
 
… …
4. JSP (jspShowSession.jsp)
取得以上创建的两个PortletSession 的属性值, 由Browser中可以看到只有Application Scope的Session 属性可以被获得.
if(ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE)!=null){
  app=ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE).toString();
}

if(ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE)!=null){
  portlet=ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE).toString();
}

以下代码将Httpsession中的所有属性全部列出:
      可以看到PortletContainer是如何存取Portlet Scope类型的session属性的.
      <%
  HttpSession s=request.getSession();
for (Enumeration e = s.getAttributeNames() ; e.hasMoreElements() ;) {
         %><tr><td><%=e.nextElement()%></td></tr>
<%
}
         %>
 
将以上源代码编译后, 再通过Eclipse生成/更新Portlet的web.xml后,  将所有配置及相关文件部署后, 启动Tomcat.

在Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面(图:5-1)
    图:5-1

单击PortletSession Example1 Page后可以看到如下两个Portlet 页面(图5-2)

图:5-2

上图中上边的一个Generate Portlet用来创建两个PortletSession属性,分别是Application Scope 和 Portlet Scope 类型.
下方的Display Portlet用以验证Session的作用范围.
单击Application Scope Session, 可以看到如下页面(图5-3)

                                                                   图5-3
如上图,生成了一个Application Scope的属性, 名称: PortletSession.AS

单击Portlet Scope Session, 可以看到如下页面(图5-4)
图5-5
生成了一个Portlet Scope Session属性,所以Display portlet 无法取得. 但是从HttpSession 可以看到又创建了一个session属性.

Case study: Session的共享
以上例子验证了Portlet中Session的作用范围, 可能在开发过程中经常需要有Popup页面的处理这个时候就无法使用Portlet, 但是可以使用Servlet或者是JSP, 以下这个例子是一个Portlet和Servlet的Session共享的应用 (或许是Tomcat4的一个BUG), 我们将使用一个Portlet创建一个Application Scope的Session, 然后在一个Servlet中得到它.
1. Portlet (PortletSessionExample2_ShareSession.java)
以下代码将创建一个application scope的Portlet Session:
… …
if(INF!=null){
  PortletSession ps=request.getPortletSession();
  ps.setAttribute("INF",INF,PortletSession.APPLICATION_SCOPE);
}
… …
2. JSP (jspLoginView.jsp)
… …
<%
PortletSession ps = renderRequest.getPortletSession();

String app=null;

if(ps.getAttribute("INF",PortletSession.APPLICATION_SCOPE)!=null){
  app=ps.getAttribute("INF",PortletSession.APPLICATION_SCOPE).toString();
%>  <u><a style="cursor:hand" onclick='window.open("/pluto/popup","a","width=400,height=330,scrollbars=1")'>Click here to Popup</a></u> <%   
}
%>
… …
3. Servlet (PopupServlet.java)
… …
   HttpSession se=request.getSession();
Object info=se.getAttribute("INF");
… …
注: 由于Tomcat下webapps目录下的pluto和portlets分别是两个web application, 所以将以上的PopupServlet配置到pluto目录下,而非portlets目录下.

将以上源代码编译后, 再通过Eclipse生成/更新Portlet的web.xml后,  将所有配置及相关文件部署后, 启动Tomcat.

在Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面
  

单击PortletSession Example2 Page后可以看到如下页面(图5-6)


图5-6
单击 Click here to generate a session , 后可以看到如下页面(图5-7)
                                                              图5-7
单击 Click here to Popup , 后可以看到如下页面(图5-8)
 
图5-8
• 源代码及Portlet相关配置文件
A. Session Example1
1. Portlet (PortletSessionExample1_GenerateSesssion.java)
package portlets.portletsession;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;
public class PortletSessionExample1_GenerateSesssion extends GenericPortlet{
public void doView(RenderRequest request, RenderResponse response)
  throws PortletException, IOException{
  response.setContentType("text/html");
  String jspName = getPortletConfig().getInitParameter("view");
  PortletRequestDispatcher rd =
     getPortletContext().getRequestDispatcher(jspName);
  rd.include(request, response);
   }
  
public void processAction(ActionRequest request,ActionResponse response)
  throws PortletException,IOException{
  String action=request.getParameter("ACTION");
  if(action.equals("ApplicationScope")){
   PortletSession ps=request.getPortletSession();
   ps.setAttribute("PortletSession.AS",action,PortletSession.APPLICATION_SCOPE);
  }else{
   PortletSession ps=request.getPortletSession();
   ps.setAttribute("PortletSession.PS",action,PortletSession.PORTLET_SCOPE);  
  }
   }

}
   
2. Portlet (PortletSessionExample1_DisplaySession.java)
package portlets.portletsession;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;
public class PortletSessionExample1_DisplaySession extends GenericPortlet{
  public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("view");

PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);
rd.include(request, response);
  }
}
3. JSP (view_portletsession1_displaysession.jsp)
<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<h3>Display PortletSession and HttpSession Example</h3>
<%
PortletSession ps = renderRequest.getPortletSession();

String app="NULL";
String portlet="NULL";

if(ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE)!=null){
  app=ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE).toString();
}

if(ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE)!=null){
  portlet=ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE).toString();
}
%>
<b>PortletSession list:</b>
<table border=1>
<tr><td><b>Session Scope</b></td><td><b>Attribute Name</b></td><td><b>Attribute Value</b></td></tr>
<tr><td>Application scope</td><td>PortletSession.AS</td><td><b><%=app%></b></td></tr>
<tr><td>Portlet scope</td><td>PortletSession.PS</td><td><b><%=portlet%></b></td></tr>
</table>
<br>
<b>HttpSession list:</b>
<table border=1>
<tr><td><b>Attribute Name</b></td></tr>
<%
  HttpSession s=request.getSession();
     for (Enumeration e = s.getAttributeNames() ; e.hasMoreElements() ;) {
         %><tr><td><%=e.nextElement()%></td></tr>
<%
     }
%>
</table>
<BR><BR>
4. JSP (view_portletsession1_generatesession.jsp)
<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<portlet:actionURL windowState="NORMAL" portletMode="view" var="pu1">
<portlet:param name="ACTION" value="ApplicationScope"/>
</portlet:actionURL>
<portlet:actionURL windowState="NORMAL" portletMode="view" var="pu2">
<portlet:param name="ACTION" value="PortletScope"/>
</portlet:actionURL>
<BR>
<h3>Generate PortletSession Example</h3>
<a href="<%=pu1%>">Application Scope Session</a>
<Br>
<a href="<%=pu2%>">Portlet Scope Session</a>
<Br><BR>

B. Session Example2
1.Portlet (PortletSessionExample2_ShareSession.java)
package portlets.portletsession;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;
public class PortletSessionExample2_ShareSession extends GenericPortlet{
  public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("view");

PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);
rd.include(request, response);
  }
  
public void processAction(ActionRequest request,
         ActionResponse response)
        throws PortletException,
         java.io.IOException{
  String INF=request.getParameter("INF");
  if(INF!=null){
  PortletSession ps=request.getPortletSession();
  ps.setAttribute("INF",INF,PortletSession.APPLICATION_SCOPE);
  }
  }
}

2. Servlet (PopupServlet.java)
package servlet;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
public class PopupServlet extends HttpServlet{
 
public void doGet(HttpServletRequest request,
         HttpServletResponse response)
   throws IOException, ServletException
  {
   PrintWriter pw=response.getWriter();
   HttpSession se=request.getSession();
    Object info=se.getAttribute("INF");
    if(info!=null){
     pw.println("<table border=1 bordercolor=black>");
     pw.println(" <tr>");
     pw.println("  <td><b>Attribute</b><td><td><b>Value</b></td> ");
     pw.println(" </tr>");
     pw.println(" <tr>");
     pw.println("  <td>INF<td><td>"+ info.toString() +"</td> ");
     pw.println(" </tr>");
     pw.println("</table>");
    }else{
     pw.println("No session");
    }
  }
}

C. 配置文件
1. Portlet.xml
… …
<!-- PortletSession Example -->
<!-- PortletSession Example1 - GenerateSession -->
<portlet>
  <description>PortletSession_Generator Example</description>
  <portlet-name>PortletSession_GeneratorExample</portlet-name>
  <display-name>PortletSession_Generator Example</display-name>
  <portlet-class>portlets.portletsession.PortletSessionExample1_GenerateSesssion</portlet-class>
 
  <init-param>
   <name>view</name>
   <value>/fragments/portletsession/view_portletsession1_generatesession.jsp</value>
  </init-param>
  <expiration-cache>-1</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
   <portlet-mode>VIEW</portlet-mode>
  </supports>
  <supported-locale>en</supported-locale>
  <portlet-info>
   <title>PortletSession_Generator Example</title>
   <short-title>PortletSession_Generator</short-title>
   <keywords>PortletSession_Generator</keywords>
  </portlet-info>
</portlet>

<!-- PortletSession Example1 - DisplaySession -->
<portlet>
  <description>PortletSession_Display Example</description>
  <portlet-name>PortletSession_DisplayExample</portlet-name>
  <display-name>PortletSession_Display Example</display-name>
  <portlet-class>portlets.portletsession.PortletSessionExample1_DisplaySession</portlet-class>
 
  <init-param>
   <name>view</name>
   <value>/fragments/portletsession/view_portletsession1_displaysession.jsp</value>
  </init-param>
  <expiration-cache>-1</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
   <portlet-mode>VIEW</portlet-mode>
  </supports>
  <supported-locale>en</supported-locale>
  <portlet-info>
   <title>PortletSession_Display Example</title>
   <short-title>PortletSession_Display</short-title>
   <keywords>PortletSession_Display</keywords>
  </portlet-info>
</portlet>
… …
2.  pageregistry.xml
… …
<!-- PortletSession Example1 Page -->
    <fragment name="portletsessionpage1" type="page">
        <navigation>
            <title>PortletSession Example1 Page</title>
            <description>PortletSession Example Page</description>
        </navigation>
        <fragment name="row1" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.40"/>
                </fragment>
            </fragment>
        </fragment>
        <fragment name="row2" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.50"/>
                </fragment>
            </fragment>
        </fragment>       
    </fragment>
<!-- PortletSession Example2 Page -->
    <fragment name="portletsessionpage2" type="page">
        <navigation>
            <title>PortletSession Example2 Page</title>
            <description>PortletSession Example Page</description>
        </navigation>
        <fragment name="row1" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.60"/>
                </fragment>
            </fragment>
        </fragment>     
    </fragment>
… …
3. Portletregiestry.xml
… …
        <portlet id="40">
            <definition-id>portlets.PortletSession_GeneratorExample</definition-id>
        </portlet>
        <portlet id="50">
            <definition-id>portlets.PortletSession_DisplayExample</definition-id>
        </portlet>
        <portlet id="60">
            <definition-id>portlets.PortletSession_ShareExample</definition-id>
        </portlet>
… …


总结
Session对于Web 开发来说是非常重要且必要的元素, 对于Portlet来说, 其Session的功能和Servlet略有不同. 但实际还是HttpSession的延伸及包装.
资源:
• Pluto
http://jakarta.apache.org/pluto
• Pluto Mail List
http://news.gmane.org/gmane.comp.jakarta.pluto.user
• WSRP Spec1.0
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
• Apache的WSRP实现 (WSRP4J)
http://ws.apache.org/wsrp4j/
• Apache’s Portal, JetSpeed:
http://jakarta.apache.org/jetspeed/site/index.html
• JSR 168:
http://www.jcp.org/en/jsr/detail?id=168



Portlet 应用开发, Part 4 - Portlet 的 Request和Response对象
By Terry.li
SpiritSeekerS@sqatester.com


本文使用本系列中Part1搭建的开发环境,如果没有搭建好开发环境,请参考Portlet应用开发Part1进行开发环境的搭建.在Part1中我们已经介绍了Portlet的GenericPortlet类. 从形式上来看, Portlet与Servlet非常相似, 但是从request和response对象的具体特点及功能来说, 又有所不同. 本部分主要描述了Portlet的Request和Response对象的特点及其与Servlet的Request和Response对象的不同点.

 Portlet的Request 对象
Portlet中的Request与Servlet的Request一样接受Client端发送的Request, 但是与Servlet不同, Portlet的Request分为Action Request及Render Request两种类型,因此Portlet接口中定义了两种方法用来处理不同的Request. 分别是processAction(ActionRequest request,ActionResponse response) 和render(RenderRequest request,RenderResponse response),分别用以处理Action Request和Render Request. 某种意义上来讲,render方法类似Servlet中的service方法,doView,doEdit,doHelp方法又类似doGet,doPost方法,如下图:


1. RenderRequest和ActionRequest有什么不同呢?
对于Portlet来说PortletRequest分为ActionRequest和RenderRequest两种,分别是由renderURL和actionURL来触发的.可以这样理解, renderURL是actionURL的一种优化形式.Portlet开发过程中尽可能使用renderURL而避免使用actionURL. actionURL适用于有确实的Action(行为)的情况下. 比如说, form表单的递交. Persistent状态的改变,session的操作,preference的修改,这种情况下使用actionURL,而不使用renderURL, renderURL通常用来操作portlet内容的导航.

以下是两个例子:

使用actionURL:
<%
PortletURL pu=renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");

%>
<form name="usrfrm" method="post" action="<%=pu.toString()%>">

注: form表单递交时,使用HTTP post方法,而不用get方法.因为某些Portal/Portlet Container的实现将内部状态编码到URL的Query字符串中.


使用renderURL:
<%
PortletURL pu=renderResponse.createRenderURL();
pu.setParameter("PAGE",Number);

%>
<a href=”<%=pu%>”>下一页</a>

2. renderURL和actionURL的处理方式有什么不同?
当客户端request是由一个renderURL触发时,Portlet/Portlet Container会调用Portal页面中所有Portlet的render方法. 如下:

renderURL
/       |      \
                                                              render      render  render 


而当客户端request一个actionURL触发时, Portlet/Portlet Container会先调用目标Portlet的processAction()方法, 当processAction方法处理完毕后,再分别调用Portal页面中所有Portlet的render方法.如下:

     actionURL
            | 
             processAction
             /        |         \
     render     render     render

由于以上原因,所以使用renderURL要比使用actionURL的performance来的好.

3. RenderRequest和ActionRequest的parameter参数作用范围有什么不同?
当客户端request一个actionURL触发时,比如一个form表单的提交,所有的Parameter的get操作必须在processAction方法中进行. 例如:

JSP的form表单页面:
<%
PortletURL pu=renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");

%>
<form name="usrfrm" method="post" action="<%=pu.toString()%>">


Portlet的处理:
public void processAction(ActionRequest req,ActionResponse res){
String str=req.getParameter(“ACTION”);
//response.setRenderParameter("ACTION",action);
}

public void doView(ActionRequest req,ActionResponse res){
String str=req.getParameter(“ACTION”);
}

如上processAction方法中,getParamter方法将能成功得到表单中的参数ACTION所对应的值,因为我们知道,当目标portlet的processAction方法运行完后,Portlet Container将调用Portal页面中所有Portlet的render方法.但是实际上doView方法中使用getParameter不会得到任何值.但是如果把processAction方法中注释了的一行uncomment的话,你就可以在doView方法中的得到参数ACTION对应的值. 这说明action request的参数,render方法中不可以直接取到.必须使用了setRenderParameter方法,再次传递一次.


 A case study
在这部分中,我们来做一个简单的Portlet, 实现一个简单的Form submit功能. 以下是代码片段: (完整代码请参考文章末尾)

JSP(view_portletrequest.jsp.jsp):

… …
<!-- Use PortletURL Object//-->
<%
PortletURL pu1=renderResponse.createActionURL();
pu1.setParameter("ACTION","Use PortletURL Object");
pu1.setPortletMode(PortletMode.VIEW);
%>

<table width=100% border=0>
<TR><TD>1. Use PortletURL object to get an ActionURL and set current portlet mode to view</TD></TR>
<tr><td>
<form name="usrfrm" method="post" action="<%=pu1.toString()%>">
<input type=submit name=bt1 value="GetActionByJava">
</form>
<tr><td>
</table>
… …
 
注: 处理完form后将会将PortletMode设定为VIEW.

以上代码使用了actionURL因为是form表单的递交. 详细请参考Portlet的Request 对象部分. 或者也可以使用Tag. 它同样也可以生成一个Portlet的URL, 如下:

… …
<!-- Use Portlet Tag //-->
<portlet:actionURL windowState="maximized" portletMode="edit" var="pu2">
<portlet:param name="ACTION" value="Use Portlet Tag"/>
</portlet:actionURL>

<BR>
<table width=100% border=0>
<TR><TD>2. Use Portlet Tag to get a ActionURL and and set current portlet mode to edit</TD></TR>
<tr><td>
<form name="usrfrm" method="post" action="<%=pu2%>">
<input type=submit name=bt2 value="GetActionByTag">
</form>
<tr><td>
</table>
… …

注: 它在处理完form后将会将PortletMode设定为EDIT,并且Window state会为最大化.

Portlet(PortletRequestExample.java):

… …
public void processAction(ActionRequest request, ActionResponse response)
  throws PortletException, IOException
{
  String action=request.getParameter("ACTION");
  System.out.println("ACTION" + action);
  if(action==null){
   action="";
  }
 
  response.setRenderParameter("ACTION",action);
}
… …


JSP(view_portletrequest.jsp)

… …
<%
String getaction="";
if(request.getParameter("ACTION")!=null){
getaction=request.getParameter("ACTION");
}
%>

<B>ACTION: <%=getaction%></B>
… …
 

JSP(edit_portletrequest.jsp.jsp)

… …
<%
String getaction="";
if(request.getParameter("ACTION")!=null){
getaction=request.getParameter("ACTION");
}
%>
<B>ACTION: <%=getaction%></B>
… …

将以上源代码编译后, 再通过Eclipse生成/更新Portlet的web.xml后,  将所有配置及相关文件部署后, 启动Tomcat.

 

在Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面(图:4-1)


图:4-1


单击PortletRequest Example Page后可以看到如下Portlet 页面(图4-2)


图:4-2

 

单击 GetActionByJava 后, 得到如下(图:4-3):

  图:4-3

单击 GetActionByTag 后, 将跳转到edit mode, 如下(图:4-4):


         图:4-4

 Portlet的Response 对象
与Request对象类似,Response对象也有两种:分别是ActionResponse和RenderResponse, 分别封装了对应ActionRequest和RenderRequest对象返回的所有信息。例如,重定向,windows state,portlet mode等的信息。其中他们的父类,PortletResponse拥有setProperty和addProperty方法,用以传递提供商指定的信息给portal/portlet container

1。ActionResponse和RenderResponse有什么不同?
ActionResonse可以用来处理以下相关功能:
1) 重定向
sendRedirect方法用来进行帮助portal/portlet-container进行头信息,及其内容的设定,并且将URL重定向到用户指定的页面。
2) 改变windows state, portlet mode ,我们在以前章节中介绍了window state 和 portlet mode概念.
3) 传递Parameter参数到RenderRequest中去,如上面request部分中用到的例子。

RenderResponse用来提供如下功能(和Servlet中的Response更相似):
1) 设置ContentType
2) 得到Output Stream and Writer对象,用来产生页面内容
3) Buffering
4) 设定Portlet的Title , 但必须先于portlet的输出递交前来调用,否则将会被忽略。(注:目前的pluto没有实现,如果调用不会修改title)

 A example

… …
public void doView(RenderRequest request, RenderResponse response)
  throws PortletException, IOException
{
response.setContentType("text/html");
PrintWriter pw=response.getWriter();
pw.print(“Hello, Portlet”);
… …


• 源代码及Portlet相关配置文件

A. Portlet (PortletRequestExample.java)

package portlets.portletrequest;

/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;

public class PortletRequestExample extends GenericPortlet{

  public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");

String jspName = getPortletConfig().getInitParameter("view");

PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);

rd.include(request, response);
  }

  public void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");

String jspName = getPortletConfig().getInitParameter("edit");

PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);

rd.include(request, response);
  }

public void processAction(ActionRequest request, ActionResponse response)
  throws PortletException, IOException
{
  String action=request.getParameter("ACTION");
  System.out.println("ACTION" + action);
  if(action==null){
   action="";
  }
 
  response.setRenderParameter("ACTION",action);
}
}

B. JSP (view_portletrequest.jsp)

<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<h3>Request Example</h3>

<!-- Use PortletURL Object//-->
<%
PortletURL pu1=renderResponse.createActionURL();
pu1.setParameter("ACTION","Use PortletURL Object");
pu1.setPortletMode(PortletMode.VIEW);
%>

<table width=100% border=0>
<TR><TD>1. Use PortletURL object to get an ActionURL and set current portlet mode to view</TD></TR>
<tr><td>
<form name="usrfrm" method="post" action="<%=pu1.toString()%>">
<input type=submit name=bt1 value="GetActionByJava">
</form>
<tr><td>
</table>

<!-- Use Portlet Tag //-->
<portlet:actionURL windowState="maximized" portletMode="edit" var="pu2">
<portlet:param name="ACTION" value="Use Portlet Tag"/>
</portlet:actionURL>

<BR>
<table width=100% border=0>
<TR><TD>2. Use Portlet Tag to get a ActionURL and and set current portlet mode to edit</TD></TR>
<tr><td>
<form name="usrfrm" method="post" action="<%=pu2%>">
<input type=submit name=bt2 value="GetActionByTag">
</form>
<tr><td>
</table>

<%
String getaction="";
if(request.getParameter("ACTION")!=null){
getaction=request.getParameter("ACTION");
}
%>

ACTION: <B><%=getaction%></B>

<BR><BR>
Current Portlet Mode: <B><big><%=renderRequest.getPortletMode()%></big></font></B><br>


C. JSP (edit_portletrequest.jsp)

<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<h3>Request Example</h3>


<%
String getaction="";
if(request.getParameter("ACTION")!=null){
getaction=request.getParameter("ACTION");
}
%>

ACTION: <B><%=getaction%></B>

<BR><BR>
Current Portlet Mode: <big><B><%=renderRequest.getPortletMode()%></font></big></B><br>

D. Portlet.xml

… …
<!-- PortletRequest Example -->
<portlet>
  <description>PortletRequest Example</description>
  <portlet-name>PortletRequestExample</portlet-name>
  <display-name>PortletRequest Example</display-name>
  <portlet-class>portlets.portletrequest.PortletRequestExample</portlet-class>
 
  <init-param>
   <name>view</name>
   <value>/fragments/portletrequest/view_portletrequest.jsp</value>
  </init-param>
  <init-param>
   <name>edit</name>
   <value>/fragments/portletrequest/edit_portletrequest.jsp</value>
  </init-param>

  <expiration-cache>-1</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
   <portlet-mode>VIEW</portlet-mode>
   <portlet-mode>EDIT</portlet-mode>
  </supports>
  <supported-locale>en</supported-locale>
  <portlet-info>
   <title>PortletRequest Example</title>
   <short-title>PortletRequest</short-title>
   <keywords>PortletRequest</keywords>
  </portlet-info>
</portlet>
… …

E. portletentityregistry.xml

<?xml version="1.0" encoding="UTF-8"?>
<portlet-entity-registry>
<application id="10">
<definition-id>portlets</definition-id>
… …
        <portlet id="30">
             <definition-id>portlets.PortletRequestExample</definition-id>
        </portlet>
… …
</application> 
</portlet-entity-registry>

F. pageregistry.xml

<?xml version="1.0"?>
<portal>

    <fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
    </fragment>

… …

<!-- PortletRequest Example Page -->
     <fragment name="portletrequestpage" type="page">
        <navigation>
            <title>PortletRequest Example Page</title>
            <description>PortletConfig Example Page</description>
        </navigation>
        <fragment name="row1" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.30"/>
                </fragment>
            </fragment>
        </fragment>
</fragment>

… …

</portal>


注: web.xml文件可以从portlet.xml通过Eclipse的Plugin直接生成,所以没有列出配置文件, 请参考本系列中的Part1.

      资源:
• Pluto
http://jakarta.apache.org/pluto

• Pluto Mail List
http://news.gmane.org/gmane.comp.jakarta.pluto.user

• WSRP Spec1.0
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp

• Apache的WSRP实现
http://ws.apache.org/wsrp4j/

• Apache’s Portal, JetSpeed:
http://jakarta.apache.org/jetspeed/site/index.html

• JSR 168:
http://www.jcp.org/en/jsr/detail?id=168
• "Portlet 规范介绍" By Stefan Hepper 和 Stephan Hesmer
o Part 1: Get your feet wet with the specification's underlying terms and concepts (August 2003)
o Part 2: The Portlet API's reference implementation reveals its secrets (September 2003)

 

11:19:51 | 添加评论 | 发送消息 | 固定链接 | 查看引用通告 (0) | 写入日志 | 我的技术文章
Java Portlet应用开发 (JSR168), Part 3 - PortletConfig 对象
By Jia.li(Terry.li)
SpiritSeekerS@sqatester.com


本部份将讲述PortletConfig对象及其PortletContext对象的概念及应用.

• PortletConfig对象
和ServletConfig对象类似, PortletConfig对象提供Portlet初始的所需的参数及其对PortletContext对象存取提供相关方法.
和ServletConfig不同处在于, PortletConfig对象提供对Portlet Title Bar资源的I18N支持,我们可以设定不同的Resource Bundle文件用以提供多语言的支持, 如下portlet.xml文件:

… …
  <portlet-info>
   <title>PortletConfig Example</title>
   <short-title>PortletConfig</short-title>
   <keywords>PortletConfig</keywords>
</portlet-info>
… …

以上Portlet描述文件中的设置用于显示Portlet的Title Bar文字, 同样也可以使用Resource Bundle用以显示Title Bar文字, 如下:

  … …
<resource-bundle>
portlets.portletconfig.portletconfigexample
</resource-bundle>
  … …


• A case study

这里我们将开发一个简单使用Resource Bundle的Portlet.只需要添加所须的Resource Bundle文件.

我们使用英文及其中文的Resource Bundle, 如下:

3) Base Resource Bundle (portletconfigexample.properties)

# English Resource Bundle
#
# filename: portletconfigexample.properties
# Portlet Info resource bundle example
javax.portlet.title=PortletConfig Example
javax.portlet.short-title=PortletConfig
javax.portlet.keywords=PortletConfig

2) Chinese Resource Bundle (portletconfigexample_zh.properties)

# Chinese Resource Bundle
#
# filename: portletconfigexample.properties
# Portlet Info resource bundle example
javax.portlet.title=Portlet配置 例子
javax.portlet.short-title=Portlet配置
javax.portlet.keywords=Portlet配置


3) portlet.xml

… …
<resource-bundle>
portlets.portletconfig.portletconfigexample
</resource-bundle>
… …

 

 

• 源代码及Portlet相关配置文件

1) Portlet (PortletConfigExample.java)

package portlets.portletconfig;

/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/

import javax.portlet.*;
import java.io.IOException;
import java.io.Writer;

public class PortletConfigExample  extends GenericPortlet{

  public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");
String view = getPortletConfig().getInitParameter("view");
Writer writer=response.getWriter();
writer.write(view);
  }

  public void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");
String edit = getPortletConfig().getInitParameter("edit");
Writer writer=response.getWriter();
writer.write(edit);
  }
 
}


2) Portlet.xml

… …
<!-- PortletConfig Example -->
<portlet>
  <description>PortletConfig Example</description>
  <portlet-name>PortletConfigExample</portlet-name>
  <display-name>disPortletConfigExample</display-name>
  <portlet-class>portlets.portletconfig.PortletConfigExample</portlet-class>
  <init-param>
   <name>view</name>
   <value>Here is View Mode</value>
  </init-param>
  <init-param>
   <name>edit</name>
   <value>Here is Edit Mode</value>
  </init-param>
  <expiration-cache>-1</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
   <portlet-mode>VIEW</portlet-mode>
   <portlet-mode>EDIT</portlet-mode>
  </supports>
  <supported-locale>zh</supported-locale>
  <supported-locale>en</supported-locale>
  <resource-bundle>portlets.portletconfig.portletconfigexample</resource-bundle>
</portlet>
… …

3) pageregistry.xml

… …
  <!-- PortletConfig Example Page -->
    <fragment name="portletconfigpage" type="page">
        <navigation>
            <title>PortletConfig Example Page</title>
            <description>PortletConfig Example Page</description>
        </navigation>
        <fragment name="row1" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.20"/>
                </fragment>
            </fragment>
        </fragment>
    </fragment>
… …

4) PortletRegistry.xml

… …
              <portlet id="20">
             <definition-id>portlets.PortletConfigExample</definition-id>
        </portlet>
… …


将以上源代码编译后, 再通过Eclipse生成/更新Portlet的web.xml后,  将所有配置及相关文件部署后, 启动Tomcat.

 

在Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面(图:3-1)

如果机器的Locale及语言设定是以中文简体为缺省,则单击PortletConfig Example Page后可以看到如下Portlet 页面(图3-1):

   图3-1

注: 因为现在Pluto的开发中没有做I18N的处理,这里如果你的机器的Locale是中文的话, 显示是乱码,请将IE的encoding设定为GB2312(View -> Encoding -> Chinese Simplified), 如图3-1.


如果机器的Locale及语言设定是英文的话, 将看到如下Portlet 页面(图3-2):

图3-2

 

资源:
• Pluto
http://jakarta.apache.org/pluto

• Pluto Mail List
http://news.gmane.org/gmane.comp.jakarta.pluto.user

• WSRP Spec1.0
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp

• Apache的WSRP实现
http://ws.apache.org/wsrp4j/

• Apache’s Portal, JetSpeed:
http://jakarta.apache.org/jetspeed/site/index.html

• JSR 168:
http://www.jcp.org/en/jsr/detail?id=168
• "Portlet 规范介绍" By Stefan Hepper 和 Stephan Hesmer
Part 1: Get your feet wet with the specification's underlying terms and concepts (August 2003)
Part 2: The Portlet API's reference implementation reveals its secrets (September 2003)

11:18:16 | 添加评论 | 发送消息 | 固定链接 | 查看引用通告 (0) | 写入日志 | 我的技术文章
Java Portlet应用开发 (JSR168), Part 2 - Pluto中添加新的Portal Page 和 Portlet
By Jia.li(Terry.li)
SpiritSeekerS@sqatester.com


本部分使用本系列中Part1搭建的开发环境,如果还没有搭建好开发环境,请参考Portlet应用开发(JSR168),Part1进行开发环境的搭建.

在Part1中,我们开发了一个简单的portlet程序,但是几乎所有的代码和文件都是由Eclipse的pluto plugin替我们完成的,如何配置用来在Pluto中的Portal中添加新的Portal Page并且将新的Portlet添加到新的Page中去呢? Part2将一步一步教你如何创建一个新Portal Page.


• Portal的设定
Tomcat 中Webapps目录: 其中pluto是portal所在目录, 用以配置Portal Page的两个文件分别是pageregistry.xml和portletentityregistry.xml (如图Figure1_1)

 


Figure1_1


其中pageregistry.xml用来在Portal中配置Portal Page, 而portletentityregistry.xml 用来在Page中配置Portlet.

• portletentityregistry.xml
打开pageregistry.xml, 内容如下 :

<?xml version="1.0" encoding="UTF-8"?>
<portlet-entity-registry>
    <application id="1">
        <definition-id>portlets</definition-id>
        <portlet id="1">
            <definition-id>portlets.SimplePortlet</definition-id>
        </portlet>
    </application>
</portlet-entity-registry>

其中application 标签表明了目前的application 的 ID, portlet标签定义了一个Portlet , 如果你新开发了一个Portlet , 可以加入以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<portlet-entity-registry>
    <application id="1">
        <definition-id>portlets</definition-id>
        <portlet id="1">
            <definition-id>portlets.SimplePortlet</definition-id>
        </portlet>
        <portlet id="2">
            <definition-id>portlets.IntroPortlet</definition-id>
        </portlet>
    </application>
</portlet-entity-registry>

这样一来你又在portal中注册了一个新的Portlet,接下来是将新注册的Portlet加入Page中.

• pageregistry.xml
打开pageregistry.xml, 内容如下 :

<?xml version="1.0"?>
<portal>

    <fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
    </fragment>
   
    <fragment name="sample" type="page">
        <navigation>
            <title>Sample Portlet</title>
            <description>Basic page to show the simple portlet</description>
        </navigation>

        <fragment name="row" type="row">

            <fragment name="col1" type="column">

                <fragment name="p1" type="portlet">
                    <property name="portlet" value="1.1"/>
                </fragment>

            </fragment>

        </fragment>

    </fragment>
</portal>

以上是sample portlet的配置.

Fragment标签用来配置navigation(导航栏), Page,以及Page中的Column和Row.
分别用fragment标签的type属性来标识. Pluto自带的Portal使用fragment标签来配置及处理简单的Portlet Layout.

<property name="portlet" value="1.1"/>中的value值是在portletentityregistry.xml中定义的. 分别对应application id 和portlet id, 将其值用”.”连接起来使用用以定义一个Portlet. 同样 , 如果使用<property name="portlet" value="1.2"/>,则将使用portlets.IntroPortlet.
 


1) 配置同一行中的两个Portlet, 如下:
<?xml version="1.0"?>
<portal>

    <fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
    </fragment>
   
    <fragment name="sample" type="page">
        <navigation>
            <title>Sample Portlet</title>
            <description>Basic page to show the simple portlet</description>
        </navigation>

        <fragment name="row" type="row">

            <fragment name="col1" type="column">

                <fragment name="p1" type="portlet">
                    <property name="portlet" value="1.1"/>
                </fragment>

                <fragment name="p2" type="portlet">
                    <property name="portlet" value="1.1"/>
                </fragment>

            </fragment>

        </fragment>

    </fragment>

</portal>
 

2) 配置同一列中的两个Portlet, 如下:
<?xml version="1.0"?>
<portal>

    <fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
    </fragment>
   
    <fragment name="sample" type="page">
        <navigation>
            <title>Sample Portlet</title>
            <description>Basic page to show the simple portlet</description>
        </navigation>

        <fragment name="row1" type="row">

            <fragment name="col1" type="column">

                <fragment name="p1" type="portlet">
                    <property name="portlet" value="1.1"/>
                </fragment>

            </fragment>

        </fragment>

        <fragment name="row2" type="row">

            <fragment name="col1" type="column">

                <fragment name="p1" type="portlet">
                    <property name="portlet" value="1.1"/>
                </fragment>

            </fragment>

        </fragment>

    </fragment>

</portal>

 

 

• Portlet Modes 和 Portlet window states
Portlet模式(Portlet Mode)是Portlet提供的用以区分 Portlet所执行功能的一个概念.通常情况下其拥有以下几种模式:
1. VIEW
2. EDIT
3. HELP

以上各模式分别对应GenericPortlet中的 doView(…) , doEdit(…) , doHelp(…) 方法,分别调用以上方法来产生各个模式中的Fragment内容. 非常类似Servlet中的doGet(…) , doPost(…) 方法,都是Helper方法, 但是概念不同.

Portlet状态(Portlet window states)提供了对于Portlet窗口的控制功能 , 其中有如下三种最基本的状态:
1. Normal
2. Maximized
3. Minimized

Portlet开发人员可以在处理ActionRequest (以后的章节将讲述其概念) 时使用代码实现Portlet模式, 及其Portlet状态的转变.

注: 只能在处理ActionRequest时改变Portlet Modes和Portlet Window states.

以上Portlet Modes和Portlet window states都可以配置成custom Portlet mode和custom portlet window state. 不同的地方在于对于Mode来说, 定制化的Mode需要对GenericPortlet的doDispatch方法进行重写(Overriding), 因为GenericPortlet类通过render方法按照不同的Portlet Mode将request分别分发给doView,doEdit,doHelp等辅助方法. 如果需要定制的Mode , 必须重写doDispatch 方法. 同时如果使用Portal提供商的Portlet Modes 或者 Portlet window States,都必须在部署描述中添加相关的设定.

A. 添加Custom Portlet Modes
以下使用代码实现了一个新的Portlet Mode: CONFIG , 当然也可以使用Portal提供商支持的Portlet Mode. 但是需要Mapping到Portal提供商所支持的Portlet Mode. 使用如下描述:

    <custom-portlet-mode>
  <description>Provides administration functions</description>
  <portlet-mode>CONFIG</portlet-mode>
    </custom-portlet-mode>

1. Portlet代码 (CustomPortletModeExample.java)

package portlets.portletmode;

/**
* @author terry
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;

public class CustomPortletModeExample extends GenericPortlet{

  public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");

String jspName = getPortletConfig().getInitParameter("all");

PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);

rd.include(request, response);
  }

  public void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
  {
response.setContentType("text/html");

String jspName = getPortletConfig().getInitParameter("all");

PortletRequestDispatcher rd =
   getPortletContext().getRequestDispatcher(jspName);

rd.include(request, response);
  }
  
public void render(RenderRequest request, RenderResponse response)
throws PortletException, IOException{
  doDispatcher(request,response);
}
  
public void doDispatcher(RenderRequest request, RenderResponse response)
  throws PortletException, IOException{
  if(!request.getWindowState().equals(WindowState.MINIMIZED)){
  if(request.getPortletMode().equals(PortletMode.VIEW)){
   doView(request,response);
  }else if(request.getPortletMode().equals(PortletMode.EDIT)){
   doEdit(request,response);
  }else if(request.getPortletMode().equals(new PortletMode("CONFIG"))){
   doConfig(request,response);
  }
}
}

public void doConfig(RenderRequest request, RenderResponse response)
   throws PortletException, IOException
{
   response.setContentType("text/html");

   String jspName = getPortletConfig().getInitParameter("all");

   PortletRequestDispatcher rd =
  getPortletContext().getRequestDispatcher(jspName);

   rd.include(request, response);
}

public void processAction(ActionRequest request, ActionResponse response)
  throws PortletException, IOException
{
  String action=request.getParameter("ACTION");
  System.out.println("ACTION" + action);
  if(action==null){
   action="";
  }
  response.setRenderParameter("ACTION",action);
}
}

2. JSP(all_mode.jsp)

<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<br>
<h3>Custom Portlet Mode Example</h3>
Current Portlet Mode: <b><%=renderRequest.getPortletMode()%></b><br>
Current Window State: <b><%=renderRequest.getWindowState()%></b><br>
<br>

 

5. Portlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="/org/apache/pluto/portalImpl/xml/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="/org/apache/pluto/portalImpl/xml/portlet-app_1_0.xsd /org/apache/pluto/portalImpl/xml/portlet-app_1_0.xsd">

<!-- Custom PortletMode Example -->
<portlet>
  <description>CustomPortletModeExample Example</description>
  <portlet-name>CustomPortletModeExample</portlet-name>
  <display-name>CustomPortletModeExample</display-name>
  <portlet-class>portlets.portletmode.CustomPortletModeExample</portlet-class>
  <init-param>
   <name>all</name>
   <value>/fragments/portletmode/all_mode.jsp</value>
  </init-param>
  <expiration-cache>-1</expiration-cache>
  <supports>
   <mime-type>text/html</mime-type>
   <portlet-mode>VIEW</portlet-mode>
   <portlet-mode>EDIT</portlet-mode>
   <portlet-mode>CONFIG</portlet-mode>
  </supports>
  <supported-locale>en</supported-locale>
  <portlet-info>
   <title>Custom PortletMode Example</title>
   <short-title>PortletMode</short-title>
   <keywords>PortletMode</keywords>
  </portlet-info>
</portlet>

</portlet-app>

6. portletregistry.xml.

<?xml version="1.0" encoding="UTF-8"?>
<portlet-entity-registry>
    <application id="10">
        <definition-id>portlets</definition-id>
        <portlet id="10">
            <definition-id>portlets.CustomPortletModeExample</definition-id>
        </portlet>
    </application>
</portlet-entity-registry>

7. pageregistry.xml

<?xml version="1.0"?>
<portal>

    <fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
    </fragment>
   
   <!-- Custom PortletMode Example Page -->
       <fragment name="customportletmodepage" type="page">
        <navigation>
            <title>Custom PortletMode Example Page</title>
            <description>Custom PortletMode Example Page</description>
        </navigation>
        <fragment name="row1" type="row">
            <fragment name="col1" type="column">
                <fragment name="p1" type="portlet">
                    <property name="portlet" value="10.10"/>
                </fragment>
            </fragment>
        </fragment>
  </fragment>

</portal>

 

将以上源代码编译后, 再通过Eclipse生成/更新Portlet的web.xml后,  将所有配置及相关文件部署后, 启动Tomcat.

 

在Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面(图:2_1)

       图2-1


单击Custom PortletMode Example Page后可以看到如下Portlet 页面:


图2-2

单击右上角的config后,可以看到如下页面片段:


图2-3

以上可以看到新添加的Portlet Mode: config.


B. 添加Custom Window States

添加新的window states同样需要在配置文件中加入相应的描述,如下:
<custom-window-state>
<description>Occupies 50% of the portal page</description>
<name>half_page</name>
</custom-window-state>

但是同样需要Mapping到Portal提供商所支持的Window state.

总结:
因为Eclipse 的Pluto plugin使用的是version1.0 , 所以可能有许多Bugs或者没有实现的功能, 所以如果需要最新版本的Pluto , 可以在Apache的CVS上下载, 下载的代码中有现成的Build scripts 以及相关的deploy script.请参考相关文档资料.

累了,去读意优休息一下下,QQ空间,美文,非主流,网络日记,搞笑短信,祝福短信,热门短信,有意思啊