Hello World——WebSphere Portal V5 最简单的 portlet:第 2 部分,以 JSP 呈现

本文将带读者了解如何在 IBM WebSphere Portal Version 5 中开发和部署一个基于 portlet 的简单 JSP。

引言
“Hello World”序列的第一篇文章中,您已经了解到如何在 Java 中创建一个 portlet,它能够输出“hello, world”。这是示范性的,并不是开发 portlet 的一种实用方法。那么,它到底有什么样的问题呢?本文(第二篇文章)将来解决其中的一个问题。

在这个最简单的“Hello World!”程序中,Java 代码包含了文本“hello, world”,也包含了显示这个文本的逻辑。如果您能够将 portlet 的逻辑和呈现该逻辑的部分分开,那么程序将会做得更好,因为这样可以让您创建支持不同元语言和不同国家语言的 portlet。今天,您可能不需要创建一个用于无线标记语言(Wireless Markup Language,WML)的 portlet,或者不需要创建一种德语版的 portlet。但是,明天呢?

您也可能是和一名图形设计师一块工作,他频繁地更改外观和感觉。如果呈现部分是在 Java 代码中完成的,则需要一名开发人员和一名编辑加工人员对它做修改。解决这一问题的办法就是用 JSP 来呈现您的 portlet,它可以让您创建独立的 JSP 文件,每个文件支持一种元数据或一种国家语言。设计师就可以完全控制 JSP 并对它做修改,而不再需要开发人员的协助了。

在本文中,您将会看到如何在 IBM® WebSphere® Portal Version 5 中构建一个 portlet,它调用一个 JSP 以便在其中呈现。然后我们再介绍该 JSP 以及一些来自 portlet 标记库的标记。最后,创建部署描述符,将所有的这些东西打成一个包,并将它部署到门户网站中。

创建目录结构
首先,您必须创建一个目录结构,在其中可以存储您的 portlet。以下内容是你在 portlet 中将会用到的:

  • helloWorld/com/ibm/portlets/sample —— 存放源代码的位置。
  • helloWorld/WEB-INF —— 存储部署描述符的位置。
  • helloWorld/WEB-INF/lib ——存放 JAR 文件的位置。
  • helloWorld/jsp —— 存储 JSP 文件的位置。

重要: 所有的目录和环境引用都是基于 Windows 惯例的。您可以做些相应的调整,使之适用于 Unix 系统。

创建 Java 代码
样本目录是您存放 Java 源文件的位置。在该目录中创建一个名为 HelloWorld.java 的文件,并用您喜欢的文本编辑器打开。下面这个类您需要将它键入(或者剪切和粘贴到)所创建的 HelloWorld.java 文件中:


package com.ibm.portlets.sample; 
 
//portlet APIs 
import org.apache.jetspeed.portlet.*; 
 
//Java stuff 
import java.io.*; 
 
public class HelloWorld  extends PortletAdapter { 
 
  public void service(PortletRequest request, PortletResponse response) 
    throws PortletException,  IOException { 
 
    // Include the view jsp 
    getPortletConfig().getContext().include( "/jsp/view.jsp",  
          request,  response); 
  } 
}

编译代码
创建源文件之后,您就可以来编译 Java 代码了。您可以使用以下的脚本,在批处理文件中编译该 portlet。首先定义一些环境变量,例如定义 Java 安装位置的环境变量(JAVA_HOME)。使用 WebSphere Application Server 所提供的 JDK 来编译通常是一个很好的主意,因为这是您将要运行应用程序的环境。

您也需要设置 PATH 环境变量,使它包括 Java 编译器的安装位置。同时还要设置 LIBPATH 变量,使它指向 WebSphere JAR 文件所在的目录。

接下来,为我们的编译类路径设计一个名为 CP 的变量。CP 变量可以构建在一行上,但为了说明所需的不同 JAR 文件,我们将它拆开分行显示。然后调用 Java 编译器对代码进行编译。代码假定您是在 helloWorld 目录下。请将目录路径调整为适合您安装的路径。


set JAVA_HOME=C:/WebSphere/AppServer/java 
set PATH=%JAVA_HOME%/bin 
set LIBPATH=C:/WebSphere/AppServer/lib 
set CP=. 
set CP=%CP%;%LIBPATH%/j2ee.jar 
set CP=%CP%;%LIBPATH%/dynacache.jar 
set CP=%CP%;C:/WebSphere/PortalServer/shared/app/portlet-api.jar 
 
javac -classpath %CP% com/ibm/portlets/sample/HelloWorld.java 

如果由于某些原因这不能编译,在继续执行之前必须先修正错误。一些常见的错误是:

  • 输入错误——类名称、路径、变量名称输入错误。
  • 文件名称错误——文件名称必须和类名称相匹配。在我们的示例中,文件名是 HelloWorld.java,类名称是 HelloWorld。如果您已经改变了一个名称,另一个名称也必须改变。
  • 编辑器错误——确定编辑器确实将文件存储为文本。像写字板这样的编辑器不会将文件默认存储为文本。

创建 JAR 文件
在完成了 Java 源文件的编译之后,您需要在 WEB-INF/lib 目录下创建一个 JAR 文件。再次假定您位于 helloWorld 目录下。这些语句可以作为您在上面创建的批处理文件的一部分包含在其中。这取决于您已经将 PATH 设置为指向 jar 程序。


set JAVA_HOME=C:/WebSphere/AppServer/java 
set PATH=%JAVA_HOME%/bin 
 
jar -cv0f ./WEB-INF/lib/HelloWorldFromJSP.jar com/ibm/portlets/sample/*.class

创建 JSP 文件
编译完 Java 源代码并创建了 JAR 文件之后,您就可以专心来创建 JSP 文件了。JSP 目录是存放 JSP 源文件的位置。在这个 JSP 目录下创建一个名为 view.jsp 的文件,并用您喜欢的文本编辑器打开。这里是一些 JSP 代码,您需要将它们键入(或者剪切和粘贴到) view.jsp 文件中:


Hello world from the JSP!

就这么简单。现在,您可以将这些打包并运行!在这之后,您可以再回过头来看看这个 JSP,看看您还可以再添加什么以便支持不同的国家语言和不同的元语言。

创建部署描述符
现在,您需要创建两个 XML 文件:

  • helloWorld/WEB-INF/web.xml —— Web 部署描述符。
  • helloWorld/WEB-INF/portlet.xml —— portlet 部署描述符。

web.xml —— Web 部署描述符
Web 部署描述符是 WebSphere Portal 所需要的。现在 Portlet 扩展了 Servlet,所以需要使用 Web 部署描述符来声明 Servlet(Portlet)类。


<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web 
        Application 2.3//EN" 
   "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> 
<web-app id= "HelloWorldFromJSPWebApp"> 
  <display-name>HelloWorldFromJSPPortlet</display-name> 
  <servlet id="Servlet_1"> 
    <servlet-name>HelloWorldFromJSP</servlet-name> 
    <servlet-class>com.ibm.portlets.sample.HelloWorld</servlet-class> 
  </servlet> 
  <servlet-mapping id="ServletMapping_1"> 
    <servlet-name>HelloWorldFromJSP</servlet-name> 
    <url-pattern>/HelloWorldFromJSP/*</url-pattern> 
  </servlet-mapping> 
</web-app>

portlet.xml —— portlet 部署描述符
Portlet 部署描述符向门户网站定义 portlet。每个 portlet 通过 portlet 元素的 href 属性映射到 Web 部署描述符中定义的一个 Servlet 上。以粗体表示这些引用。Portlet 必须定义一个惟一的 id,每个具体的 portlet 都能引用该 id。每个具体的 portlet 利用 concrete-portlet 元素的 href 属性的给定 id 来引用 portlet。以蓝色表明这些引用。


<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE portlet-app-def PUBLIC "-//IBM//DTD Portlet Application 
        1.1//EN" "portlet_1.1.dtd"> 
<portlet-app-def> 
  <portlet-app uid="com.ibm.portlets.sample.HelloWorldFromJSP.1" major-version="1"
        minor-version="0"> 
    <portlet-app-name>HelloWorldFromJSP0Portlet</portlet-app-name> 
    <portlet href="WEB-INF/web.xml#Servlet_1" id="Portlet_1" major-version="1"
        minor-version="0"> 
      <portlet-name>HelloWorldFromJSP</portlet-name>
      <cache> 
        <expires>0</expires> 
        <shared>no</shared> 
      </cache> 
      <allows> 
        <maximized/> 
        <minimized/> 
      </allows> 
      <supports> 
        <markup name="html"> 
          <view/> 
        </markup> 
      </supports> 
    </portlet> 
  </portlet-app> 
  <concrete-portlet-app uid="com.ibm.portlets.sample.HelloWorldFromJSP.1.2"> 
    <portlet-app-name>Concrete HelloWorldFromJSP</portlet-app-name> 
    <context-param> 
      <param-name>Author</param-name> 
      <param-value>tcat@us.ibm.com</param-value> 
    </context-param> 
    <concrete-portlet href="#Portlet_1"> 
      <portlet-name>HelloWorldFromJSP</portlet-name> 
      <default-locale>en</default-locale> 
      <language locale="en"> 
        <title>Hello World from JSP</title> 
      </language> 
    </concrete-portlet> 
  </concrete-portlet-app> 
</portlet-app-def>

创建这些 XML 文件时,许多地方会出错。而只有在您试图将 portlet 部署到门户网站的时候这些错误才会被发现。这里有一些事项需要特别注意:

  • 检查每个 XML 元素,确保它们都有一个闭元素。
  • 检查类名是否输入错误,对于本例而言,检查您给类起的名称是否是 HelloWorldFromJSP
  • 确保 id 和 href 属性相匹配。
  • 确保编辑器确实将文件保存成文本类型。

创建 WAR 文件
最后,我们就可以创建供分发的 WAR 文件了。我们将使用标准 jar 命令来构建 WAR 文件。在 helloWorld 目录下运行以下命令:


set JAVA_HOME=C:/WebSphere/AppServer/java 
set PATH=%JAVA_HOME%/bin 
 
jar -cf HelloWorldFromJSP.war WEB-INF jsp

部署 WAR 文件

  1. 以门户网站管理员的身份(wpsadmin)登录到门户网站。
  2. 在缺省主题的右上角选择 Administration 链接。

    图 1. 管理员链接
    管理员链接

  3. 在左边选择 Portlets 页面,并选择 Install portlet。

    图 2. 安装 portlet 管理页面
    安装 portlet 管理页面

  4. 单击 Browse 按钮
  5. 找到 WAR 文件的位置,选定,然后单击 Open 按钮

    图 3. 文件选择对话框
    文件选择对话框

  6. 单击 Next。这可能要花费一些时间,请耐心等待它完成。
  7. 验证 Portlet 是否为 HelloWorld。单击 Install 按钮。再次等待直到安装完成。

    图 4. Portlet 安装验证屏幕
    Portlet 安装验证屏幕

  8. 最后,您将看到这条确认消息: Portlet installation successful

如果在部署过程中碰到某类出错信息,通常意味着您在某个 XML 文件中出错了。仔细分析安装页面呈现给您的出错信息,您通常能够从中找到出错原因。这些信息也会记录在最新的日志文件中:
%WPS_HOME%/log/wps_YYYY.MM.DD-HH.MM.SS.log

在上面也列出了 XML 文件常见的一些错误。您还应该检查下列内容:

  • XML 声明必须位于文件的第一行(没有空格)。
  • 在正确的大小写情况下,xml 文件有正确的名称。

将 portlet 添加到某一页面中

  1. 在左边选择 Portal User Interface 页面。
  2. 单击 Manage Pages

    图 5. 管理页面 portlet
    管理页面 portlet

  3. 然后选择 My Portal 页面。
  4. 单击 新页面
  5. 为新页面键入一个标题。
  6. 单击 OK 按钮
  7. 看到 OK 成功消息 以后单击 OK 按钮
  8. 单击新页面边上的编辑页面图标 编辑页面
  9. 单击 添加 portlet
  10. 搜索 Hello,单击 Search
  11. 选中 Hello World portlet 并单击 OK 按钮

    图 6. 查找 portlets
    查找 portlets

  12. 单击 完成 来完成页面版面设计。

    图 7. 编辑版面设计
    编辑版面设计

  13. 在右上角单击 My Portal 链接,然后选择您创建的页面。

    图 8. 显示我们创建的 Portal 的门户网站
    显示我们创建的 Portal 	的门户网站

I18N 与多个元数据语言
I18N 是一个国际化的通用缩写词,这个术语指代以某种方式设计一个应用程序(您的 portlet),采用这种方式设计的应用程序可以适用于不同的语言和地区,而无需再去修改代码。采用您当前的这种实现方法是无法支持多个国家语言或多个元数据语言的。使用 JSP 来呈现的 portlet 具有两类支持方式可以支持 I18N,哪一种都可以帮助您实现多个元数据语言。

第一类支持方式是采用多个 JSP 来呈现您的 portlet。这种支持方式允许一个 portlet 有不同的版面设计、颜色、图片、文本,以及其他特定于所支持的语言、地区和元语言的表示方式。

您的 JSP 的目录结构是 /jsp/view.jsp。门户网站将这个目录作为搜索一个最适合的 JSP 的一个基地。以下是设置为英语(美国)场所的 Web 浏览器的搜索顺序:

/jsp/html/en_US/view.jsp 
/jsp/html/en/view.jsp 
/jsp/html/view.jsp 
/jsp/view.jsp

找到的第一个 view.jsp 用于呈现 portlet。这种约定可以让您为不同的国家语言指定不同的 JSP。例如,您可以在 /jsp/html/de/ 目录中建立一个 view.jsp。它会读取“Hallo Welt”(这是我想要的结果,即德语的“Hello World”)。中心思想就是说每种语言和每个地区都可以有它自己的 JSP,其中提供了专门的版面设计和 verbage。而不同的元语言呢?在上面的搜索路径中您可以发现指定了 /html/。您可以按照以下的路径为 portlet 给出 JSP:

/jsp/html/en_US/view.jsp 
/jsp/html/en/view.jsp 
/jsp/html/de/view.jsp 
/jsp/html/view.jsp 
/jsp/wml/en_US/view.jsp 
/jsp/wml/en/view.jsp 
/jsp/wml/de/view.jsp 
/jsp/wml/view.jsp 
/jsp/view.jsp

拥有不同的 JSP 可以让您的 portlet 用户通过 WML 浏览器访问,并且 portlet 可以使用 /wml/ 目录结构中的 JSP 来执行搜索。所以,这是支持 I18N 的第一个层次。

提供帮助的第二个层次是采用 Java 资源绑定(resource bundles)的形式。对于您的 portlet 而言,Java 资源绑定具有这样的能力,即可以将字符串放入容易解释、与 JSP 代码相互独立的特性文件中。您可以采用同一个版面设计,但以正确的国家语言来呈现文本。为了在 WebSphere Portal V5 中做到这一点,您需要深入到 JSTL(JSP Standard Tab Library,JSP 标准标记库)的世界中。以前,您是使用 WebSphere Portal 中附带的 IBM portlet 标记库从 JSP 访问资源绑定。在 V5 中,您还是可以这样做,只是它已经弃用了文本标记,未来的远景是 JSTL。

用于 I18N 的 JSTL 介绍
JSTL 为 JSP 标记提供了各种各样的功能。实际上,JSTL 是四个不同的标记库:

  1. 核心标记库 —— 它提供了一种表达语言,以及通用的控制流程标记。例如 if 和循环标记。
  2. 格式化标记库 —— 它提供了 I18N 特征,例如从资源绑定、date、time 和其他格式化标记中检索消息。
  3. 数据库访问标记库 —— 可以让您直接从 JSP 访问数据库。
  4. XML 标记库 —— 各种 XML 标记,可以让您解析和转换 XML 文档。
我发现 JSTL 的数据库和 XML 部分与 WebSphere Portal 中的其他标记库往往冲突。举个例子,当我将数据库标记库包含进一个使用 DB2 数据源的 portlet 时,遇到了一个类冲突,这使我无法访问我的数据库。还有就是当我将 XML 标记库包含进一个 portlet 时,我发现我的 JSP 不能再编译了。

这些小问题只在 WebSphere Portal V5.0.2 中出现过。我最后才发现是由于 JSTL XML 标记库发生冲突。所以我建议您减少 JSTL,使它只包含格式化标记库和核心标记库,除非您觉得您真正需要的 JAR 文件对冲突有一个好的解决办法。

说到 JAR 文件,您可以从标准标记库下载 JSTL 库,或者从标准标记库入门寻找您自己的镜像站点,从中下载。本文阐述的是 Version 1.0。

当您解压下载的标记库时,你会发现里面已经创建了几个目录。其中两个您最感兴趣的是 libtld 目录。您需要从 lib 目录复制两个 JAR 文件到您的 WEB-INF/lib 目录下,这两个文件是 jstl.jarstandard.jar。所有其他的标记库本练习并不需要用到,它们也不会妨碍您执行 portlet,如上所述。

您也需要创建 WEB-INF/tld 目录。请将 c.tldc-rt.tldfmt.tld fmt-rt.tldtld 目录复制到您的 WEB-INF/tld 目录。这些文件定义了内核(c)标记库和格式化(fmt)标记库。现在您可能在想为什么需要两个不同的 tld 文件。JSTL 有一个“孪生库(twin libraries)”的概念,它不在本文的讨论范围内。简要地讲就是一个允许使用 JSTL 表示语言,而另一个允许使用 JSP 表示。

是的,从外头看是 JSTL,而在后端则是两种表达方式。您可能要开始表示不满了,抱怨我对 JSTL 不公平,是的,我知道,我对 JSTL 有点轻描淡写了,我也鼓励您写一篇关于 JSTL 的文章。您是一位文雅的读者,您必须去了解读一些比我写得更好的资源,从中了解 JSTL。可以用 Google 去找,也可以去您喜欢的在线书店找。您会找到很多的资源的,但记住是 JSTL 1.0!

为了在您的 portlet 中运用 JSTL 来访问资源绑定,您已经做了大部分的预备工作了。现在,您必须修改 web.xml 文件来声明您将要使用的标记库。请注意看一下 servlet-mapping 标记后面的 taglib 标记。


<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web 
        Application 2.3//EN" 
   "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> 
<web-app id= "HelloWorldFromJSPWebApp"> 
  <display-name>HelloWorldFromJSPPortlet</display-name> 
  <servlet id="Servlet_1"> 
    <servlet-name>HelloWorldFromJSP</servlet-name> 
    <servlet-class>com.ibm.portlets.sample.HelloWorld</servlet-class> 
  </servlet> 
  <servlet-mapping id="ServletMapping_1"> 
    <servlet-name>HelloWorldFromJSP</servlet-name> 
    <url-pattern>/HelloWorldFromJSP/*</url-pattern> 
  </servlet-mapping>

  <taglib id="TagLibRev_JSTL_fmt">
    <taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri>
    <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location>
  </taglib>

  <taglib id="TagLibRev_JSTL_fmt_rt">
    <taglib-uri>http://java.sun.com/jstl/fmt_rt</taglib-uri>
    <taglib-location>/WEB-INF/tld/fmt-rt.tld</taglib-location>
  </taglib>

  <taglib id="TagLibRev_JSTL_core">
    <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
    <taglib-location>/WEB-INF/tld/c.tld</taglib-location>
  </taglib>

  <taglib id="TagLibRev_JSTL_core_rt">
    <taglib-uri>http://java.sun.com/jstl/core_rt</taglib-uri>
    <taglib-location>/WEB-INF/tld/c-rt.tld</taglib-location>
  </taglib>
</web-app>

您已经定义了您可能用得到的所有标记库了。在本文中您不需要所有的都用到,但我认为把它们都做一下定义并没有什么坏处。此外,我在这告诉您如何定义所有的标记库,在您的 portlet 中就不需要自己再去琢磨了!

现在进入真正的 JSP 代码部分。为了利用 JSTL 格式化标记库,需要在 JSP 的开头加入以下的指示以便访问格式化标记库:


<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
        

您可以使用类似的指示来利用核心库。现在我们要使用格式化库来从资源绑定中检索消息。


<fmt:setBundle basename="nls.labels"/>
<fmt:message key="helloWorldLabel"/>
        

这些代码会试着从标签特性文件中获取“helloWorldLabel”。如果没有找到合适的特性文件,那么在缺省情况下是呈现 opening 和 closing 文本标记之间的内容,在我们的示例中是“Hello world from the JSP!”。在 Java 中,搜索特性文件与搜索标准 ResourceBundles 采用的是同样的方式:

<basename>_<lang>_<country>_<variant> 
<basename>_<lang>_<country> 
<basename>_<lang> 
<basename>

在这个练习中,您要创建两个特性文件:

/WEB-INF/classes/nls/labels_en.properties 
/WEB-INF/classes/nls/labels_de.properties

它们会有以下的内容:

/WEB-INF/classes/nls/labels_en.properties: 
helloWorldLabel=Hello World! 
 
/WEB-INF/classes/nls/labels_de.properties: 
helloWorldLabel=Hallo Welt!

总结一下,JSP 文件 /jsp/view.jsp 具有以下的内容:


<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
<fmt:setBundle basename="nls.labels"/>
<fmt:message key="helloWorldLabel"/>
        

如果在 HTML 浏览器中将语言设置为英语,则这个 JSP 文件,连同两个特性文件会生成以下的内容:

图 9. 英语显示的 Hello World portlet
英语显示的 Hello World portlet

然后在我们的 HTML 浏览器中将语言设置为德语,则 portlet 会生成:

图 10. 德语显示的 Hello World portlet
德语显示的 Hello World portlet

漂亮极了!但您可能要问,如何去更新已经部署在门户网站中的 portlet 呢?您可以直接将这个 portlet 删除,然后再重新部署。但在真实的门户环境中,这样做会丢失用户数据和部署信息。本文的最后一节将要简要地介绍一下如何更新一个已部署的 portlet。

更新一个已部署的 portlet

  1. 作为门户管理员(wpsadmin)登录到门户网站中。
  2. 在缺省主题的右上角选择 Administration 链接。

    图 1. 管理员链接
    管理员链接

  3. 在左边选择 Portlets 页面,然后单击 Install 来安装 portlet。
  4. 选择 Manage Applications portlet。

    图 11. 管理 portlets 屏幕
    管理应用程序

  5. 在 Web Modules 列表框中,选择 HelloWorldFromJSP.war 条目。
  6. 单击 Update 图标 按钮。
  7. 单击 Browse 图标 按钮。
  8. 查找 WAR 文件的位置,选中它并单击 Open 图标
  9. 单击 Next 图标,这可能需要花费一些时间,请耐心等待它完成。
  10. 验证 Portlet 确实为 HelloWorldFromJSP,单击 Install 图标,然后等待安装完成。
  11. 最后您会看到确认信息 Successfull update message

结束语
这就结束了。本文让您了解到如何运用 JSP 来呈现您的 portlet。本文介绍如何为一个 portlet 编写、编译并打包 Java 代码。首先创建部署描述符并打包 portlet 以便分发和部署;然后将 portlet 部署到您的门户网站中;最后,重新编写 JSP,使之国际化,并更新部署的 portlet。portlet 开发课程可以让您一学再学。祝您好运!玩得开心!

回页首

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值