科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道使用 WebSphere Application Server V6.1 中的 Struts Tiles 和 Portlet Framework 快速实现门户外观

使用 WebSphere Application Server V6.1 中的 Struts Tiles 和 Portlet Framework 快速实现门户外观

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文向您介绍如何使用 IBM® WebSphere® Application Server Version 6.1(以下称为 Application Server)中与 Struts Tiles 集成的 JSR168 portlet 容器框架和聚合标记创建门户页面。

作者:ibm 来源:ibm 2007年10月6日

关键字: 技术 Struts WEBSPHERE 中间件

  • 评论
  • 分享微博
  • 分享邮件
<tiles:getAsString name="title" ignore="true"/>

引言

从 6.1 版开始,WebSphere Application Server 提供了嵌入式 JSR168 portlet 容器。您现在可以将 Portlet 部署到 Application Server V6.1,而以前只能将其部署到门户服务器(如 IBM WebSphere Portal,以下称为 WebSphere Portal)。

此功能具有以下几个主要优点:

  1. 您可以将 Portlet 编写为可重用组件,先在 Application Server 中使用,随后将它们用于与 JSR 168 兼容的门户服务器(如 WebSphere Portal),以便使用该门户服务器中的更多高级功能。
  2. 您可以在 Application Server 中集成其他人员编写的标准 Portlet,这些 Portlet 可能来自开放源代码或商业 Portlet 目录(如 WebSphere Portal 目录)。
  3. 您可以将 Portlet 与 Servlet 一起部署,以满足各种业务需求。例如,您可能需要使用 Portlet 提供各种数据的聚合视图,并使用 Servlet 处理具有许多页面流的复杂用户界面。
  4. 您的应用程序更容易移植到具有不同屏幕大小的普及设备,因为每个 Portlet 在页面上占用的面积很小,它们更容易呈现在普及设备上。例如,应用程序可以指定单个 Portlet 占用移动电话的整个屏幕;指定两个 Portlet 并排占用 Pocket PC 的屏幕;指定多个 Portlet 呈现到 Web 浏览器。

不过,Application Server 6.1 不能提供通常内置到门户服务器(如 WebSphere Portal)的扩展特性和功能。门户的关键特性是其可自定义的外观。在门户服务器中,通常通过配置来动态处理自定义和个性化。例如,您可以基于用户组动态地个性化页面主题和皮肤,并且您可以分配特定的用户组权限,以便在运行时使用 Portlet。如果希望在 Application Server 中使用这些特性,则必须亲自编写它们。另外,Application Server 中的聚合是使用聚合标记库以编程方式完成的。如果您希望在一个页面中显示多个 Portlet,则需要使用聚合标记库编写代码才能做到这一点。(请参阅参考资料中列出的系列文章“探索 WebSphere Application Server V6.1 Portlet 容器”)。

Tile 框架提供定义普通布局的机制,以便在门户中重新用作主题模板。您可以合并 Tile(作为主题模板)和 Portlet 聚合(作为页面内容),以便在 Application Server 中快速实现门户外观。可以使用 Tile 标记库定义页面布局(主题),以使用 Portlet 聚合标记库组装 Portlet。然后,将聚合 Portlet 链接到页面布局中的 Tile。Tile 和 portlet 标记都可以采用参数,所以您可创建自定义外观和动态内容。

本文向您介绍如何在 Application Server 中集成 Struts Tiles 标记和 Portlet 聚合标记,以创建自定义门户页面和门户外观。您将了解如何:

  1. 使用 Tile 标记和 Portlet 聚合标记创建页面、菜单和 Portlet 布局。
  2. 使用布局创建自定义页面。
  3. 将布局组装到门户。

示例代码仅供演示使用。不过,您可以使用本文提供的技术,为自己的应用程序实现面向更多客户的外观。读者应具备 Application Server V6.1 中 Tile、Portlet 和 Portlet 框架的基本知识,并知道如何创建和使用它们。本文中使用的 Portlet 来自 IBM 和 Sun 的示例 JSR 168 Portlet 代码(请参阅参考资料)。在 WebSphere Application Server Toolkit 6.1 中重新打包示例 Portlet,以便将其部署到 Application Server。





回页首


将 Tile 和 Portlet Aggregation Framework 一起使用

例如,让我们查看一下经典门户布局,它由标头区域、菜单区域、正文区域和页脚区域组成(图 1)。您可以将每个区域当作其内容可以作为参数(页面、页面段落和字符串)传递的 Tile。可以分别在菜单布局和正文布局中将菜单区域和正文区域定义为模板,如图 1 所示。菜单布局由动态页面组成,每个页面链接一组在 Portlet 布局中聚合的不同 Portlet。您可以按特定用途将若干子页面组合到一个页面。正文区域中的 Portlet 布局由不同数量的 Portlet 组成,这些 Portlet 是使用 Application Server 提供的 Portlet 聚合标记聚合的。

在 Application Server 6.1 中,您可以使用以下两种方法创建独特的门户外观。

  1. 基于请求自定义门户页面的用户,将不同的参数(页面、页面段落、字符串或 Portlet)传递到布局中的 Tile 和子 Tile。
  2. 更改布局或使用多个布局。您可以为不同的主题更改页面布局、为不同的皮肤更改 Portlet 布局,并更改菜单布局以修改菜单的放置。

例如,您可能需要一个顶部横排(而不是自顶向下)、基于树的页面导航菜单。可以始终创建多个布局,以供不同的页面和不同的用户组使用。例如,您可能希望管理门户页面来使用不同的页面、菜单和 Portlet 布局,以将该界面与用户界面区分开来。


图 1. 经典门户布局
图 1. 经典门户布局




回页首


创建门户布局

以下各部分向您介绍如何使用 Tile 和 Portlet 聚合标记分别创建页面、菜单和 Portlet 布局。

创建页面布局

在户门中,页面布局提供所有页面的一般主题。门户中的每个页面都将调用页面布局,并将参数(页面或页面段落)传递到在页面布局中定义的 Tile。清单 1 显示了经典页面布局,它使用 <tiles:insert /> 标记在表的不同区域中插入了五个 Tile(标题、标头、菜单、正文和页脚),如图 1 所示。Tile 占用的区域将由调用 JSP 页面传入的参数填充。


清单 1. 包括每个区域 Tile 的经典页面布局

	
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
	<tiles:importAttribute />
	<html>
	  <head>
	    <logic:present name="title">
	        <title><tiles:getAsString name="title" ignore="true"/></title>
	    </logic:present>    
	  </head>
	  <body>
	    <table border="0" cellspacing="0" cellpadding="0" width="100%" bgcolor="#F8FBFE"> 
	      <tr>
	        <td align="left" colspan="2">  
	            <tiles:insert attribute="header" ignore="true">
	               <tiles:put name="title" beanName="title" beanScope="tile"/>
	            </tiles:insert>
	        </td>   
	      </tr>
	      <tr><td>&nbsp;</td></tr>    
	      <tr>
	        <td valign="top">
	           <ul> 
	              <tiles:insert attribute="menu" />
	           </ul>
	        </td>
	        <td>
	           <div align="center">
	              <tiles:insert attribute="body" />
	           </div>
	        </td>
	      </tr>
	    </table>    
	      <tiles:insert attribute="footer" ignore="true"/>
	  </body>    
	</html>

创建页面导航

门户菜单显示当前登录到门户的用户可以查看的页面列表。清单 2 展示了如何对菜单布局进行编码,以显示页面名称和链接的列表。每个链接引用一组在门户正文中聚合的 Portlet。


清单 2. 门户页面菜单布局

				
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<tiles:useAttribute id="items" name="items" classname="java.util.List" />   
<logic:iterate id="item" name="items" type="org.apache.struts.tiles.beans.SimpleMenuItem">
   <bean:define id="link" name="item" property="link" type="java.lang.String"/>
   <logic:match name="link" location="start" value="/" >
      <A href="<%=link%>" >
         <bean:write name="item" property="value"/>
   </A>
   </logic:match>
   <logic:notMatch name="link" location="start" value="/" >
       <A href="<%=request.getContextPath()%>/<%=link%>">
         <bean:write name="item" property="value"/>
   </A>
     </logic:notMatch>
     <P/>
</logic:iterate>

清单 2 中的菜单布局使用 Struts 逻辑标记以迭代方式显示页面名称和链接。通过调用 JSP 页面将页面及其链接传入 Bean (org.apache.struts.tiles.beans.SimpleMenuItem) 的列表 (java.util.List)。 如果传入 Bean 的链接引用绝对 URL(以“/”开头),则该链接会复制过去并显示。否则,该链接会附加到使用 request.getContextPath() 获得的页面上下文,然后显示。

创建 portlet 布局

门户正文在不同的列和行中都包含 Portlet。Portlet 布局为门户正文区域中的每个 Portlet 定义单元网格。清单 3 显示了 Portlet 布局的编码,该编码显示正文区域中 Portlet 放置的表格视图。在该布局中,门户正文中的列数是作为字符串从调用 JSP 传递的。Portlet URL、每个 Portlet 的支持模式和最初的 Portlet 模式都从调用 JSP 页面传入实用程序 Bean 的列表 (com.jktelecom.PortletInfo)。因此,调用 JSP 页面可以对页面中 Portlet 的数量和放置、初始模式和每个 Portlet 的支持模式进行总体控制,所以您不必修改每个 Portlet 的 Portlet 布局。

Portlet 布局使用 Portlet 列表的列数和大小(二者均由调用 JSP 页面传递)来确定呈现 Portlet 的行数和单元。Portlet 布局按最初插入到列表的顺序遍历列表。它使用 <portlet:state> 标记放置 Portlet 支持的模式,并使用 <portlet:insert> 标记放置 Portlet URI,所以模式和 Portlet 内容都可以动态地呈现给相应的单元。这将显示 Portlet 模式和适当的链接,以及 <portlet:insert> 标记从 Portlet 部署描述符 (portlet.xml) 检索的 Portlet 标题。


清单 3. Portlet 布局

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="http://ibm.com/portlet/aggregation" prefix="portlet" %>
<%@ page import="java.util.*" %>
<%@ page import="com.jktelecom.*" %>
<%@ page isELIgnored ="false" %>
<%
   String page_uri = (String)session.getAttribute("Current_Page");
   String uri_prefix = PageInfo.getPageName(page_uri) +"/";
%>
<portlet:init portletURLPrefix="<%=uri_prefix%>" >
<tiles:importAttribute />
 <table border="1">  
  <%-- Prepare the links list to be iterated --%>
   <bean:define id="portlets" name="portlets" type="java.util.List" />
   <bean:define id="numColumns" name="numColumns" type="java.lang.String" />
  <%
    int cols = Integer.parseInt(numColumns);
    Iterator loop = portlets.iterator();    
    int portlet_count = 0;
    while (loop.hasNext()) {  
  %>
      <!-- create portal table with number columns defined by variable cols -->
      <tr bgcolor="#e0eaf8">
      <%
        String[] portRefs = new String[cols];  
        for (int i=0; i < cols; i++)  {
          if (!loop.hasNext()) {
          break;
			
          }         
          PortletInfo portletInfo = (PortletInfo)loop.next();          
          portRefs[i] = portletInfo.getName();
          String windowId = String.valueOf(portlet_count);
      %>
          <!-- insert portlet title bar -->
          <td>
            <table width="100%">
              <tr>
                <td>
                  <b><span id="title_<%=portlet_count%>">Portlet <%=
                  portlet_count%></span></b>
                </td>
                <td align="right">
                <%
                  String portletName = portletInfo.getName();
                  String[] portletModes = portletInfo.getSupportedModes(portletName);
                  for (int j=0; j < portletModes.length; j++ )  {
                    %> 
                      <a href="<portlet:state url='<%=portletName%>' 
                      windowId='<%=windowId%>'
                      portletMode='<%=portletModes[j]%>' />">
                      <%=portletModes[j]%> </a>
                      <%
                    }
                   %>           
                &nbsp; &nbsp;
               </td>
			  </tr>
            </table>
          </td>         
      <%
           portlet_count++;
        }
      %>        
     </tr>
     <tr>
      <%
         for (int k=0; k < cols; k++)  {
           int title_num = portlet_count-cols+k;
           String windowId = String.valueOf(title_num);
      %> 
          <td>
            <!-- insert portlet -->
            <portlet:insert url="<%=portRefs[k]%>" windowId="<%=windowId%>" 
              titleVar="title" />
          </td>          
          <!-- insert portlet title -->          
          <script type="text/javascript">
   document.getElementById("title_<%=title_num%>").firstChild.nodeValue = "${title}";
          </script>
      <%
        }     
      %>     
     </tr>
     <tr><td colspan="<%=cols%>">&nbsp;</td></tr>
  <%
   }
  %>   
 </table>
</portlet:init>

在 Portlet 布局中,您需要解决以下问题,如清单 3 所示。

设置 URL 前缀

您需要在 init Portlet 聚合标记中为 portletUrlPrefix 属性指定适当的 URL 前缀。

该前缀用于由 stateinsert 标记创建的 Portlet URL。它由以下两个部分组成:聚合上下文和聚合器映射。如果您使用 URL 的相对路径,则 Portlet 容器将为您管理聚合上下文。不过,如果使用 URL 的绝对路径(例如 /jkTelecom/Tools/),则在将门户应用程序 (WAR) 部署到 Application Server 时,必须指定您在聚合上下文中使用的上下文根 (jkTelecom)。您必须在 Web 应用程序部署描述符 (web.xml) 中,将 URL 中的聚合映射部分配置为指向显示 Portlet 聚合(Portlet 布局)的当前页面引用的 URL。

例如,如果引用 tools.jspTools 页面调用当前 Portlet 聚合,则 Portlet URL 必须映射到 tools.jsp,下面的门户配置部分将介绍关于映射的详细信息。

要设置适当的聚合器映射,您必须跟踪用户当前查看的页面,并相应地设置聚合映射。示例代码按以下方式处理跟踪:

  1. 当用户从菜单单击页面链接时,代码将页面 URL 存储在用户的会话(例如 tools.jsp)中:
    <%
      String current_page = "tools.jsp";   
      session.setAttribute("Current_Page", current_page);
    %>
    

  2. 该代码从 Portlet 布局 (portletLayout.jsp) 的会话中检索 URL。
    <%   
      String page_uri = (String)session.getAttribute("Current_Page");
      String uri_prefix = PageInfo.getPageName(page_uri) +"/";
    %>

  3. 该代码从 PageInfo.java 类中定义的映射获取 URL 的映射(清单 4)。实用类 PageInfo.java 包含到 URL 的所有映射,这些映射与 web.xml 中的映射对应。

    清单 4. 页面映射

    static HashMap pages;
    static {
    	pages = new HashMap();
    	pages.put("index.jsp", "Home");
    	pages.put("account.jsp", "Account");
    	pages.put("tools.jsp", "Tools");
    	pages.put("reports.jsp", "Report");
    	pages.put("services.jsp", "Services");
    	...
    }
    public static String getPageName(String uri) {      
    	return (String)pages.get(uri);
    }

  4. 最后,将聚合器映射分配给 Portlet 聚合器 init 标记的 portletURLprex 属性。
    <portlet:init portletURLPrefix="<%=uri_prefix%>" 
    

处理 Portlet 模式

每个 Portlet 通常支持不同的模式(如视图、编辑和帮助),其图标和 Portlet 标题通常一起显示在门户中。在显示图标之前,您必须知道 Portlet 支持什么模式。否则,支持模式将从 Portlet 丢失(如果您不显示该模式的图标),或抛出异常(如果 Portlet 不支持显示的模式)。

Portlet 部署描述符的 <supports> 部分提供了 Portlet 模式信息(清单 5)。


清单 5. Portlet 部署描述符 (portlet.xml) 片段

<supports>
	<mime-type>text/html</mime-type>
	<portlet-mode>config</portlet-mode>
	<portlet-mode>edit</portlet-mode>
	<portlet-mode>help</portlet-mode> 
</supports>

与使用 Portlet 聚合标记 <portlet:insert> 检索 Portlet 标题不一样,该代码不提供任何 Portlet 聚合标记帮助您检索支持模式。您必须亲自查看 Portlet 部署描述符才能检索支持模式。示例代码中使用的所有 Portlet 的支持模式都存储在散列图中,所以可以动态地检索它们(清单 6):


清单 6. 支持的 Portlet 模式

static HashMap supportedModes;
static {
	supportedModes = new HashMap();
	supportedModes.put("IBMSamples/HelloWorld", new String[]{"view"});
	supportedModes.put("IBMSamples/WorldClock", new String[]{"view", "edit", "help"});
	supportedModes.put("IBMSamples/SQLQuery", new String[]{"view"});    
	supportedModes.put("IBMSamples/HelloJSP", new String[]{"view"});
	supportedModes.put("SunSamples/JSPPortlet", new String[]{"edit", "help"});
	supportedModes.put("SunSamples/NotepadPortlet", new String[]{"edit", "help"});
	supportedModes.put("SunSamples/BookmarkPortlet", new String[]{"edit", "help"}); 
}
public String[] getSupportedModes(String portletName) {
	return (String[])supportedModes.get(portletName);
}





回页首


组装门户

在本部分中,您将了解如何编写 JSP,以便使用页面、菜单和 Portlet 布局创建适当的门户页面。您还将了解如何将 Web 应用程序描述符 (web.xml) 配置为支持 Portlet 聚合映射。

使用页面布局

调用 JSP 页面可传递插入到页面布局的参数。参数可以是另一个 JSP 页面、页面段落或简单的字符串,具体取决于当前用户和显示给用户的内容。

清单 7 显示了缺省页面布局定义的代码,该代码指定传递到页面布局的缺省参数。例如,将 header.jsp 文件传递到页面布局中的页眉 Tile,将 footer.jsp 文件传递到页面布局中的页脚 Tile。


清单 7. 缺省页面布局定义

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<logic:notPresent name="pageLayoutDef" scope="request" >
 <tiles:definition id="pageLayoutDef" page="/pageLayout.jsp" scope="request" >
  <tiles:put name="title" type="string" value="jkTelecom Portal" /> 
  <tiles:put name="header" value="/header.jsp" />
  <tiles:put name="footer" value="/footer.jsp" />
  <tiles:put name="body" value="/default_body.jsp" />   
  <tiles:put name="menu" value="/default_menu.jsp" />                
 </tiles:definition>
</logic:notPresent>

通过传递不同的参数调用 JSP 页面还可以覆盖在页面布局定义中定义的缺省行为。在清单 8 中,调用 JSP 页面 (tools.jsp) 使用清单 7 中的页面布局定义;它使用 menu.jsp 和 portlets.jsp 覆盖缺省菜单页面 (default_body.jsp) 和正文页面 (default_menu.jsp)。


清单 8. 使用页面布局的门户页面 (tools.jsp)

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%
	String current_page = "tools.jsp";   
	session.setAttribute("Current_Page", current_page);
%>
<jsp:include page="/pageLayoutDef.jsp" />
<tiles:insert beanName="pageLayoutDef" flush="true" beanScope="request">
	<tiles:put name="body" value="/portlets.jsp" />  
	<tiles:put name="menu" value="/menu.jsp" />
</tiles:insert>

使用页面导航

清单 9 显示了使用菜单布局的门户菜单 (menu.jsp)。门户菜单使用 jsp:useBean 创建 SimpleMenuItem 的实例。然后使用 jsp:setProperty 设置 SimpleMenuItem Bean 的 link 属性和 value 属性。最后,使用 tiles:add 将 Bean 添加到列表。

为了创建基于角色的页面,可以在用户组的基础上自定义菜单,而无需修改菜单布局。因此,仅当用户是特定的角色,并具有访问页面的权限时,页面才可视。用户角色是通过请求对象的 isUserInRole 方法确定的。


清单 9. 使用菜单布局的门户面页菜单

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:importAttribute />
<tiles:insert page="/menuLayout.jsp" flush="false" > 

   <tiles:putList name="items" >
    <jsp:useBean id="item_0" class="org.apache.struts.tiles.beans.SimpleMenuItem" />
    <jsp:setProperty name="item_0" property="link" value="index.jsp" />
    <jsp:setProperty name="item_0" property="value" value="Home" />               
    <tiles:add beanName="item_0" />
	...	
<%
	if (request.isUserInRole("Managers")){
%>    
	<jsp:useBean id="item_4" class="org.apache.struts.tiles.beans.SimpleMenuItem" />
	<jsp:setProperty name="item_4" property="link" value="tools.jsp" />
	<jsp:setProperty name="item_4" property="value" value="Tools" />
    <tiles:add beanName="item_4" />
        ...	  
   <%

	} else if (request.isUserInRole("Users"))  {  
%>   
	<jsp:useBean id="item_8" class="org.apache.struts.tiles.beans.SimpleMenuItem" />
	<jsp:setProperty name="item_8" property="link" value="services.jsp" />
	<jsp:setProperty name="item_8" property="value" value="Services" /> 
	<tiles:add beanName="item_8" />
	  ...			
   <%
	}			
   %> 
  </tiles:putList> 
</tiles:insert>
			

使用 Portlet 布局

清单 10 显示了使用菜单布局的 JSP 页面 (menu.jsp)。将 Portlet 在正文中呈现的列数和 <jsp:useBean> 创建的 Bean 列表 (com.jktelecom.PortletInfo) 传递到 Portlet 布局。Bean 包含 Portlet 布局需要呈现 Portlet 的所有信息(Portlet URL、初始模式和支持的模式)。


清单 10. 使用 Portlet 布局的 JSP 页面

<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ page import="java.util.*" %>
<%@ page import="com.jktelecom.*" %>
<tiles:insert page="/portletLayout.jsp" flush="false" >    
    <!-- create portal table of two columns -->
<%
    if (request.isUserInRole("Managers"))  {
%> 
      <tiles:put name="numColumns" value="3" />
<%
    } else {
%>    
         <tiles:put name="numColumns" value="2" />
<%
    }
%>         
    <!-- pass portlet links -->   
    <tiles:putList name="portlets" >
       <jsp:useBean id="portlet_0" class="com.jktelecom.PortletInfo" />
       <jsp:setProperty name="portlet_0" property="name" 
         value="IBMSamples/HelloWorld" />
       <jsp:setProperty name="portlet_0" property="initialMode" 
         value="<%=PortletInfo.VIEW%>" />
       <tiles:add beanName="portlet_0" />      
    <%
      if (request.isUserInRole("Managers"))  {
    %>     
         <jsp:useBean id="portlet_1" class="com.jktelecom.PortletInfo" />
         <jsp:setProperty name="portlet_1" property="name" 
           value="SunSamples/JSPPortlet" />
         <jsp:setProperty name="portlet_1" property="initialMode" 
           value="<%=PortletInfo.EDIT%>" />
         <tiles:add beanName="portlet_1" />
         …
    <%
      } else if (request.isUserInRole("Users"))  {      
    %>
         <jsp:useBean id="portlet_6" class="com.jktelecom.PortletInfo" />
         <jsp:setProperty name="portlet_6" property="name" 
           value="IBMSamples/WorldClock" />
         <jsp:setProperty name="portlet_6" property="initialMode" 
           value="<%=PortletInfo.VIEW%>" />
         <tiles:add beanName="portlet_6" />
         …
    <%
      }
%>              
     </tiles:putList>       
</tiles:insert>

如清单 8 所示,列数和 Portlet 列表是在角色的基础上设置的。您还可以从调用 JSP 控制访问 Portlet 的权限。可以使用以下几种方式实现这些自定义:

  1. 仅当用户是某一角色,并具有访问 Portlet 的权限时,它才对用户可视;因此,您可以针对特定的用户或用户组有选择地将 Portlet 传递到 Portlet 布局。没有访问 Portlet 权限的用户将无法在他们的门户中看到它们。
  2. 您可以对某些用户和组进一步限制 Portlet 的可用支持模式,以便对特权进行细粒度控制。例如,通过仅向经过身份验证的用户显示编辑图标,可以选择阻止匿名用户编辑 Portlet。
  3. 您可以将 Portlet 数和列数传递到 Portlet 布局,而无需修改 Portlet 布局。





回页首


配置门户

将包含 Portlet 的多个页面集成到一个门户时,需要进行特殊的操作才能处理 Portlet URL。当用户单击不同的 Portlet 模式时,将刷新所有其他 Portlet 和整个页面,并且重新发送 Portlet 中的表单数据。

  1. 当您使用聚合标记库时,必须将 init 标记的 portletUrlPrefix 属性设置为适当的聚合器上下文和映射。聚合器上下文是当前应用程序的上下文根。上面 Portlet 布局部分中已介绍,聚合器映射必须引用当前页面。
  2. 您需要在应用程序部署描述符 (web.xml) 中为所有门户页面定义映射,以便聚合器映射引用有效的 JSP 页面(清单 11)。web.xml 中定义的映射在实用类 PageInfo.java 中可用,所以可以直接检索这些映射。


清单 11. 门户应用程序部署描述符 (web.xml)

…
<servlet>			
    <servlet-name>Home</servlet-name>
    <jsp-file>index.jsp</jsp-file>
</servlet>
<servlet>			
    <servlet-name>Tools</servlet-name>
    <jsp-file>tools.jsp</jsp-file>
</servlet>
…
<servlet-mapping>
   <servlet-name>Home</servlet-name>
   <url-pattern>/Home/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>Tools</servlet-name>
   <url-pattern>/Tools/*</url-pattern>
</servlet-mapping>
…

在清单 11 中,JSP 页面 (index.jsp) 被定义为假想的 Servlet Home 的实现。聚合映射模式 /Home/* 被引用到 Home Servlet。具有 /Home/* 模式的 URL 将动态解析 JSP 页面 (index.jsp)。图 2 显示了这一映射关系,并演示 web.xml 的映射如何在 Portlet 模式图标链接的 URL 中显示。

例如,在 init 标记的 portletUrlPrefix 属性中,将相对 URL Home 指定到聚合器映射时(jkTelecom 是上下文根),聚合器模式 /Home/ 将解析为 index.xml。当用户在页面中单击 Portlet 的任一图标(视图、编辑和帮助)时,Portlet 模式中请求的表单数据会重新发送,并刷新整个页面(包括所有其他 Portlet)。图 2 演示了这一映射关系。


图 2. 映射关系
图 2. 映射关系




回页首


部署门户

将应用程序打包为 WAR 文件,并作为任一 Web 应用程序进行部署。图 3 和 4 显示了示例代码的部署门户。上下文根指定为 jkTelecom。如果您在 init 标记中使用 PortletUrlPrefix 属性的相对路径(在 Portlet 布局部分中讨论过),则可以将任一字符串用作上下文根。否则,必须指定您在聚合上下文中使用的同一上下文根。


图 3. 用户 sara 以“管理员”角色部署的门户
图 3. 用户 sara 以“管理员”角色部署的门户

图 4. 用户 fred 以“用户”角色部署的门户
图 4. 用户 fred 以“用户”角色部署的门户




回页首


结束语

现在,您已了解了如何使用 Struts Tile 标记和 Portlet 聚合标记将普通门户布局(页面、导航和 Portlet 布局)创建为可重用的模板。您可以使用该布局创建动态 Web 页,也可以将该布局组装为门户。您已了解了如何解决各种开发和部署问题,以使开发工作更加容易。现在,您可以应用这里介绍的信息,使用 WebSphere Application Server Portlet 容器和聚合标记创建自己的门户页面。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章