复杂portlet开发

2024-01-15 13:48
文章标签 开发 复杂 portlet

本文主要是介绍复杂portlet开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

portlet 从天气服务中动态检索指定的邮政编码所代表的地区的天气情况。此外,消息也不再是硬编码的,而是委托给 JSP 去处理。

图 5. 增强的 Weather Portlet 代码样本

package com.ibm.wps.samples.weather; import java.io.*; import vendor.service.weather.*; import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlets.*; import org.apache.jetspeed.portlet.service.*; /** * WeatherPortlet.java ?A more extensive example to display weather. */ public class WeatherPortlet extends PortletAdapter { protected static final String jsp = "/WEB-INF/weather/html/DisplayWeather.jsp"; public void init(PortletConfig portletConfig) throws UnavailableException { super.init(portletConfig); } public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { // Create a Weather Bean. WeatherBean weatherBean = new WeatherBean(); // Get the portlet session. PortletSession session = request.getPortletSession(); // Get the portlet configuration. PortletConfig config = getPortletConfig(); // Get the portlet context. PortletContext context = config.getContext(); // Get portal user object. User user = session.getUser(); // Get the user's full name or null if not available. weatherBean.setFullName(user.getFullName()); // Get the weather service for determining the temperature. WeatherService weatherService = (WeatherService)context.getService(WeatherService.class); // Get the current temperature for the specified zip code. weatherBean.setTemperature( weatherService.getTemperature( Integer.parseInt(config.getInitParameter("ZipCode")))); // Put the bean in the request. request.setAttribute("weatherBean", weatherBean); // Invoke the JSP to do the actual rendering for the portlet view. context.include(jsp, request, response); } }

我们来仔细研究一下这个示例来考察其中的一些重要组件。第一件要注意的事情是 WeatherPortlet 类不再继承 AbstractPortlet 类,而是继承 PortletAdapter 类。PortletAdapter 类是中心 portlet 抽象,即 portlet 接口的一个实现。它为下列 portlet 方法提供缺省的空实现:init、login、service、logout 和 destroy。

接下来要注意的是该类不再直接覆盖 service 方法。而是覆盖与特定的 portlet 模式相关联的方法。Portlet 有四种模式的操作:

  • Portlet.Mode.VIEW
  • Portlet.Mode.EDIT
  • Portlet.Mode.HELP
  • Portlet.Mode.CONFIGURE

从这些模式的名称中就可以看出它们的操作。对于每种模式,PortletAdapter 类都提供一个缺省的空实现方法。在图 5 中,portlet 只支持 VIEW 模式,所以只有一个相应的 doView 方法被覆盖。service 方法的缺省实现确定 portlet 模式并调用适当的模式方法,下图 6 中的代码片段指出了这一点:

图 6. 确定 portlet 模式

... public void service(PortletRequest request, PortletResponse response) throws PortletException, IOException { // Get the mode of the portlet. Portlet.Mode mode = request.getMode(); if (mode == Portlet.Mode.VIEW) doView(request, response); else if (mode == Portlet.Mode.EDIT) doEdit(request, response); else if (mode == Portlet.Mode.HELP) doHelp(request, response); else if (mode == Portlet.Mode.CONFIGURE) doConfigure(request, response); } ... 

我们来研究一下当调用 portlet 去处理它的 VIEW 模式时会发生什么情况。

发生的第一件事是将创建一个 WeatherBean 实例(图 7),这个实例将包含处理显示所需的所有相关数据,在本例中是用户名和预先配置的邮政编码所代表的地区的天气情况。如代码所示,用户名是从 user 对象检索出来的。为确定温度,首先从 PortletConfig 对象检索邮政编码(这里,我们简化的假设是这个 portlet 是由管理员为某个邮政编码所代表地区的全部用户配置的)。第二件事是获取对 PortletService 的引用(具体到这个示例就是引用 WeatherService 对象)。为限制这个示例的复杂性,我们将假设已经向门户服务器注册了天气服务,并且 portlet 可以利用这个服务获取特定的邮政编码所代表的地区的当前天气情况。一旦获得了这两条信息,就将它们存储在 WeatherBean 中。

图 7. WeatherBean 代码样本

package com.ibm.wps.samples.weather; /** * WeatherBean.java ?A bean used to pass data to the JSP display. */ public class WeatherBean { /** The user's full name. */ private String fullName = ""; /** The current temperature. */ private int degrees = 0; public void setFullName(String name) { fullName = name; } public String getFullName() { return fullName; } public void setTemperature(int degrees) { this.degrees = degrees; } public int getTemperature() { return degrees; } }

这个 bean 被从 PortletAdapter 类传递到 JSP,这个 JSP 将最终处理显示。这是通过 PortletRequest 对象的 setAttribute 方法完成的。然后 JSP 将使用 useBean 标记建立对 WeatherBean 的引用,并将用户的全名值和当前的温度嵌入到 HTML 输出标志(markup)中。

图 8. DisplayWeather 代码样本

<!-----------------------------------------------------------------------------> <!-- --> <!-- DisplayWeather.jsp - A JSP used to render the data for the weather --> <!-- portlet. --> <!-- --> <!-----------------------------------------------------------------------------> <%@ page contentType="text/html" errorPage="" %> <jsp:useBean id="weatherBean" class="com.ibm.wps.samples.weather.WeatherBean" scope="request"/> <p> Hi <%= weatherBean.getFullName() == null ? "" : weatherBean.getFullName() %>! <br> The current temperature in your area is <%= weatherBean.getTemperature() %>.

这个 portlet 的输出(图 9)看起来与我们前面的示例相似。

图 9. 增强的 Weather Portlet

增强的 Weather Portlet

目前为止,我们只研究了严格按浏览器(如 IE 和 Netscape,它们实现整个 HTML 规范)处理其显示的 portlet。但如果您想将 portlet 扩展到这些胖客户机之外,并使内容可以由受限的设备(比如袖珍 PC 机、手持设备或智能电话)使用时,又会怎样?在下面的几部分中,我们将研究 IBM WebSphere Portal 提供的额外 API,这些 API 可以帮助为这些设备进行开发工作。我们还将研究更高级的问题,这些问题目前在这些 API 中尚未解决,我们甚至还将演示增加发布的方法的方法。

这个示例中并没有讨论关于一些更高级 portlet API 论题的细节问题,比如窗口状态、事件处理、实例数据等,相关信息请参考 WebSphere Portal InfoCenter(请参阅参考资料)。

介绍普及的编程

面向对象设计的其中一个设计模式是模型-视图-控制器(Model-View-Controller),也称 MVC。MVC 简单的令人惊讶,但却是一个非常有用的模式,它要求开发者按照下面三个基本组件来构思应用程序:

  • 模型(model)是主要的组件,它维护应用程序呈现出的状态和数据模型。
  • 控制器(controller)是模型及其视图之间的桥梁。它是一个组件,用户可以使用它来更改底层数据模型。
  • 视图(view)是数据模型面向用户的图形化表示。

这种设计的强大之处在于它提供了:

  • 通明性?这种设计的逻辑组件是明确分开的。
  • 模块性?应用程序的各种组件可以按您的需要调进调出,使调试工作更加容易。
  • 多个视图?在多个实现中视图是可伸缩的,可以用来体现同一个数据模型。
  • 可伸缩的设计?随着应用程序的增长,各种组件也能够增长,同时不影响底层的应用程序逻辑。

图 10. 模型-视图-控制器(MVC)设计模式

模型

普及的 portlet 编程技术

既然我们了解了进行应用程序开发的模块化方法的背景知识,那么我们就把它应用到普及的编程中吧。我们可以对天气(Weather)示例中的组件做如下分析:

模型:核心天气应用程序,比如通过访问用户的全名或天气服务来检索当前的温度。
控制器:供应 bean,这些 bean 把 portlet 代码和 JSP 之间的数据连接起来。
视图:处理 portlet 内容的图形化显示的 DisplayWeather JSP。

现在很容易就可以看到不管处理的实际显示是什么样子,模型都维持不变。在各个视图之间控制器基本上是保持不变的,但可能需要按照期望的视图对数据执行一些特定的定制工作。视图组件具有处理数据使它们最适合目标显示器的灵活性。例如,智能电话以 WML(无线标记语言(Wireless Markup Language))格式显示内容。于是,对于我们的天气示例,我们可以为每个期望的设备定义一个单独的视图 JSP:为浏览器定义一个 HTML JSP,为智能电话定义一个 WML JSP。看一下图 11 中的样本 portlet,它使用这个设计模式和 WebSphere Portal 的普及 API。

图 11. 为每个设备定义单独的视图

package com.ibm.wps.samples.weather; import java.io.*; import com.ibm.wps.portlets.*; import vendor.service.weather.*; import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlets.*; import org.apache.jetspeed.portlet.service.*; /** * WeatherBaseController.java * Base controller class containing common controller functionality. */ public class WeatherBaseController extends AbstractPortletController { /** The View for HTML devices (e.g. Internet Explorer, Netscape). */ protected String jspHTML = "/WEB-INF/weather/html/"; /** The View for WML devices (e.g. SmartPhones). */ protected String jspWML = "/WEB-INF/weather/wml/"; public void init(PortletConfig config) throws UnavailableException { super.init(config); // Load the HTML View from the configuration jspHTML += config.getInitParameter("view.HTML"); // Load the WML View from the configuration. jspWML += config.getInitParameter("view.WML"); } protected void createBean(PortletRequest request, PortletResponse response) { // Get the portlet configuration object. PortletConfig config = getPortletConfig(); // Create a Weather Bean. WeatherBean weatherBean = new WeatherBean(); // Set the user's full name or null if not available. weatherBean.setFullName( request.getPortletSession().getUser().getFullName()); // Get the weather service for determining the temperature. WeatherService weatherService = (WeatherService)config.getContext().getService(WeatherService.class); // Get the current temperature for the specified zip code. weatherBean.setTemperature( weatherService.getTemperature( Integer.parseInt(config.getInitParameter("ZipCode")))); // Insert bean into the request for the JSP to use. request.setAttribute("weatherBean", weatherBean); } }
package com.ibm.wps.samples.weather; import java.io.*; import com.ibm.wps.portlets.*; import org.apache.jetspeed.portlet.*; /** * WeatherHTMLController.java * Controller for calling the HTML View. */ public class WeatherHTMLController extends WeatherBaseController { public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { createBean(request, response); getPortletConfig().getContext().include(jspHTML, request, response); } }
package com.ibm.wps.samples.weather; import java.io.*; import com.ibm.wps.portlets.*; import org.apache.jetspeed.portlet.*; /** * WeatherWMLController.java * Controller for calling the WML View. */ public class WeatherWMLController extends WeatherBaseController { public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { createBean(request, response); getPortletConfig().getContext().include(jspWML, request, response); } }

这个示例显示了一个基本的控制器,它包含 HTML 和 WML 视图的公共功能。首先,在 init 方法中,加载来自 portlet 配置的 HTML 和 WML 视图 JSP 的名称。然后,提供一个名为 createBean 的方法,这个方法创建一个 WeatherBean 实例并向它植入模型数据。最后,createBean 方法把 bean 插入到请求中,使它能被视图 JSP 使用。

接下来的两个类(图 12)提供每种视图类型的控制器。第一个是 HTML 控制器,第二个是 WML 控制器。这两个控制器类都继承控制器基类来继承后者提供的通用功能。为简单起见,除调用的视图不同之外,这两个控制器之间并没有太多不同之处。但您可以考虑根据用户所采取的操作提供为每种设备类型定制的特别功能。例如,一个胖客户机控制器可以提供对图标的拖放控制,而瘦客户机控制器却不会。

为使这些控制器能工作,您需要向 portlet web.xml 文件注册它们,方法是添加下列配置标志。(web.xmlportlet.xml 文件的详细信息不在本示例内。要了解更多信息,请参阅参考资料部分的 WebSphere Portal InfoCenter 文档。)

图 12. HTML 与 WML 控制器

... <servlet-name>WeatherPortlet</servlet-name> <servlet-class>com.ibm.wps.portlets.MVCPortlet</servlet-class> <init-param> <param-name>controller.html</param-name> <param-value>com.ibm.wps.samples.weather.WeatherHTMLController</param-value> </init-param> <init-param> <param-name>controller.wml</param-name> <param-value>com.ibm.wps.samples.weather.WeatherWMLController</param-value> </init-param> <init-param> <param-name>view.HTML</param-name> <param-value>DisplayWeatherHTML.jsp</param-value> </init-param> <init-param> <param-name>view.WML</param-name> <param-value>DisplayWeatherWML.jsp</param-value> </init-param> <init-param> <param-name>ZipCode</param-name> <param-value>27709</param-value> </init-param> ... 

现在,我们需要提供两个视图 JSP,一个用于 HTML,另一个用于 WML(图 13)。由于 HTML 视图是用于胖客户机的,我们将在其中显示用户名,但在 WML 视图中将省略用户名,因为这个是更受限制的客户机。

图 13. HTML 与 WML JSP

<!-----------------------------------------------------------------------------> <!-- DisplayWeatherHTML.jsp - A JSP view for rendering HTML. --> <!-----------------------------------------------------------------------------> <%@ page contentType="text/html" errorPage="" %> <jsp:useBean id="weatherBean" class="com.ibm.wps.samples.weather.WeatherBean" scope="request"/> <p> Hi <%= weatherBean.getFullName() == null ? "" : weatherBean.getFullName() %>! <br> The current temperature in your area is <%= weatherBean.getTemperature() %>.
<!-----------------------------------------------------------------------------> <!-- DisplayWeatherWML.jsp - A JSP view for rendering WML. --> <!-----------------------------------------------------------------------------> <%@ page contentType="text/wml" errorPage="" %> <jsp:useBean id="weatherBean" class="com.ibm.wps.samples.weather.WeatherBean" scope="request"/> <p align="left"> Current temperature is <%= weatherBean.getTemperature() %>. </p>

图 14 和图 15 分别显示了如何在浏览器和智能电话上处理这些 portlet。

图 14. 使用 HTML JSP 的 Weather Portlet

使用 HTML JSP 的 Weather Portlet

图 15. 使用 WML JSP 的 Weather Portlet

这篇关于复杂portlet开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/609106

相关文章

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10