Graph Servlet:用于门户频道的动态图像生成器

本文介绍了Graph Servlet,一个用于Sun ONE Portal Server的动态图像生成器,用于创建门户频道的饼形图和条形图。文章详细阐述了其体系结构、主要组件,包括Singleton结构、JSP页面和Java servlet,以及如何处理数据和显示图形。Graph Servlet通过Servlet解决Sun ONE Portal Server不能聚合Java servlet和JSP无法生成动态图像的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Graph Servlet:用于门户频道的动态图像生成器

作者:Paul Lovvik 和 Beverly Sum

使用 Java Servlet API,可以为门户构建多种简单实用的实用程序。例如,Graph Servlet 在 Sun ONE Portal Server 6 的自定义频道中动态地图形化数据。

本文档描述了 Graph Servlet 的体系结构,并重点讲述其组件和实现。同时讨论了安装和部署过程、主要实现方面的优缺点以及故障诊断技巧。

目录

体系结构
主要组件
安装与部署
动态图像
高速缓存
体系结构的优点与缺点
故障诊断
参考资料
关于作者

体系结构

该程序包含三个主要组件:

  • 驻留在系统类加载器 (java.awt.ClassLoader) 中的 Singleton 结构类,它在 Sun ONE Portal Server 和 Graph Servlet 之间共享数据。

  • 使用 HTML 和 Java 技术中的 JavaServerPages (JSP) 创建的页面,用以生成频道内容。

  • 动态呈现饼形图或条形图的 Java servlet。

图1阐释了体系结构中的请求流。

图1:请求流程

图1:请求流

图2展示了体系结构的层次。

图2:架构结构

图2:体系结构

用户与包含控制器的频道通信。视图将动态图像与标准 HTML <img> 标签合并在一起。这个设计围绕以下两个主要难点:

  • Sun ONE Portal Server 不能聚合 Java servlet。

  • JSP 页面不能生成动态图像,而这些图像正是图形实用程序所必需的。(使用 HTML 是惟一可行的选择) 比如 Time-sheet数据经常地变化并需要不断地升级。

主要组件

本节描述了 Graph Servlet 中的主要组件 —— JSP 页面和 Java 类的组合。

controller.jsp

controller.jsp 是控制器,用于从请求、频道的类 (JSPProvider) 和用户配置文件 (用于存储任务数据) 中收集信息。收集数据后,controller.jsp将对这些数据进行处理、排序和调度,以便生成图形。具体来说,controller.jsp 执行以下任务:

  1. 请求频道名称、将要图形化的活动以及图像的维度。请参见代码示例1-3。

代码示例1:引用 JSPProvider

JSPProvider provider =
(JSPProvider)pageContext.getAttribute "JSPProvider");
ProviderContext providerContext = provider.getProviderContext();

代码示例2:从用户配置文件中检索 Collection 属性

newNamesAndTimes =
providerContext.getCollectionProperty(channelName, "activities");

代码示例3:从 HttpServletRequest 中检索参数

String activityName = (String)request.getParameter(channelName + "-activity");

注意:Sun ONE Portal Server 6 会将一个频道名称的请求参数传送给当前显示的所有频道。因此,命名时一定要采用 channel_name-parameter_name命名约定,例如,ActivityChannel-activity,这样便可以将每个请求仅应用于一个频道,而不是多个频道。

  1. 将活动数据置入 HashMap 以便修改。

  2. 将数据置入 ActivityElement 数组以进行排序和颜色指定。

  3. 将数据放入会话和 Singleton 中使之可以存取。

  4. 适时地添加和删除活动数据。
请参见代码示例 4 和代码示例 5。

代码示例 4:将数据置入 HttpSession

session = request.getSession(true);
session.putValue("timesheet",elements);

代码示例 5:将数据置入 Singleton

DataFactory.setData(request, elements);

最后,controller.jsp 将按照用户输入确定是显示主视图还是显示图形视图,并将 <img> 标签插入到生成的 HTML 内容中。

main.jsp

main.jsp 显示以下数据,即输出经 controller.jsp 处理和排序后的数据:

  • 以表格形式显示活动名称和持续时间。
  • 用以选择和删除活动的复选框。
  • 用于输入或修改当前活动数据的表单。
  • 条形图或饼形图的缩略图;请参见代码示例 6。

代码示例 6:为饼形图添加缩略图

<a href="<dtpc:getDesktopURL/>?<%=channelName%>-
view=graph.jsp&<%=channelName%>-style=Pie"><img
src="/graph/graphController?width=100&height=100&style=Pie"></a>

  • 两个按钮,标签分别为 Add 和 Delete
  • 一个 HTML 链接,标签为 Refresh,用于重新载入主视图

graph.jsp

graph.jsp 执行以下任务:

  1. 根据用户的输入确定是显示条形图还是显示饼形图。

  2. 为 HTML 表示方法将颜色对象转换为红-绿-蓝 (RGB) 十六进制字符串。

  3. 显示以下内容:

    • 根据用户输入 (在 main.jsp 的两个缩略图中单击任意一个) 显示较大的图形视图。

    • 活动的颜色编码表。

    • 一个标签为 Back to Main Page 的 HTML 链接。

GraphServlet

GraphServlet,一种扩展了 HttpServlet 类的 Java servlet,用以执行以下任务:

  1. controller.jsp 生成的 URL 中获取绘图参数:高度、宽度和样式。

  2. 为图形创建一个框架。

  3. DataFactory 获取相关数据(ActivityElement 数组)并将这些数据发送给 PieBar 对象。

  4. 将图形编码为 GIF 文件。

  5. 删除 GraphicsFrame 对象。

代码示例 7:从 HttpServletRequest 收集图形外观数据

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
ServletOutputStream out = res.getOutputStream();
String width = req.getParameter("width");
String height = req.getParameter("height");
String style = req.getParameter("style");
..}

注意:在 UNIX 系统中,您可以选择从任何 shell 启动 Web 容器,因此一定要授予用户显示访问权限。请参见 故障诊断。另外,如果运行门户的服务器正在 headless 模式下执行,您也可以使用 Xvfb 服务器软件 启动 Web 容器。

Pie 对象

Pie 对象将信息从 controller.jsp 传递到 DataFactory,然后再传递到 GraphServlet,以呈现一个表示活动持续时间的饼形图。Pie 对象执行两个主要任务:

  1. 计算活动的持续时间。

  2. 使用浮点转换法和除法使持续时间的总时间缩放为 360 度。具体来说,Pie 对象执行以下任务:

    1. 将持续时间转换为整型。

    2. 如果存在整数圆整错误,使用一种方法对其进行修正。

    3. 用固定的度数和不同颜色来填充弧形,填充颜色时使用抽象窗口工具套件 (java.awt.*) 中的 Graphics 方法。

    4. 缩放饼形图,使之居中。

Bar 对象

同样,Bar 对象将信息从 controller.jsp 传递到 DataFactory,然后再传递到 GraphServlet,以呈现表示活动持续时间的条形图。它执行三个主要任务:

  1. 确定最长持续时间的活动。

  2. 缩放条形图,使其适合图形的高度和宽度范围。

  3. 使用 java.awt.* 中的 Graphics 方法填充矩形,为条形图着色并创建条形图。

DataFactory 对象

DataFactory 对象驻留在系统的类装载器中,用于联系从 Sun ONE Portal Server 传递到 GraphServlet 的数据。在典型的 Singleton 设计中,DataFactory 使用方法 (setData) 使数据能够存储在 HashMap 中,这样 Sun ONE Identity Server 的 SSOToken 在以后的 getData 方法中便可以引用这些数据。这样,用户便拥有了与其数据相匹配的独占访问权限和惟一的 ID。

要使多条数据与单个用户匹配,可在 DataFactory 中关联保留所有用户数据的容器。

每当 DataFactory 接收到新数据时,它都会检查数据 ID 是否已经存在于映射中,如不存在,则添加一个条目。由于 Sun ONE Identity Server 的每个用户都有一个惟一的 ID,因此用户与其数据之间为独占匹配。

请参见代码示例 8。

代码示例 8:在系统类加载器中设置数据

public static void setData(HttpServletRequest r, Object obj){
String uniqueID = getUniqueID(r);
		
if(h.get(uniqueID) == null){
try{
SSOTokenManager tokenManager =
SSOTokenManager.getInstance();
SSOToken s = tokenManager.createSSOToken(r);
/*
* If the user is logging in for the first time,
* DataFactory adds a token listener to watch for session
* logouts and timeouts.
 */
s.addSSOTokenListener(factory);
}catch(SSOException e){
d.error("setData method could not get
SSOTokenManager", e);
            }
        }
h.put(uniqueID, obj);
    }

如果有大量用户同时登入系统,Sun ONE Portal Server 的性能可能会下降。要避免这个问题,只需在 SSOToken上添加一个事件监听器来监视会话的变化 (用户注销和会话超时),然后从 HashMap 删除关联的数据,从而实现内务处理的清除。请参见代码示例 9。

代码示例 9:从 HashMap 中删除数据以优化性能

public void ssoTokenChanged(SSOTokenEvent evt) {
SSOToken token = evt.getToken();
h.remove(token.getTokenID().toString());
}

处理流程如下:

  1. controller.jsp 返回的内容包含图像标签。

  2. controller.jsp 调用用户配置文件中的数据,并将其发送给 DataFactory 对象。

  3. 浏览器解析标签数据并从 GraphServlet 中请求图像,也就是说,Sun ONE Portal Server 调用 controller.jsp,然后浏览器从 GraphServlet 请求图像。

Sorter 对象

Sorter 对象使用 mergesort 方法将对象数组按字母顺序排序。

ActivityElementStringComparator 对象

ActivityElementStringComparator 对象用于比较 ActivityElements 对象数组中的字符串。

NamedColors 对象

NamedColors 对象是从 /usr/openwin/lib/rgb.txt 文件中创建的。NamedColors 按名称存储众多的颜色,以增加图形代码和图形显示的可读性。这些颜色远远超过 java.awt.Color 中的颜色,为图形提供了许多颜色选择。

NamedColors 提供了两个方案以获取颜色:静态的 final 类变量和一个静态的 lookup 方法。

ActivityElement 对象

ActivityElement 对象作为数据的存储位置和单个活动的颜色。ActivityElement 的每个实例主要包含 setget 方法。ActivityElement 只执行最低限度的数据处理,这些处理有:

  • SetDuration 方法接受整型或字符串参数。

  • controller.jspActivityElement 实例数组传递到 DataFactory,再传递到 GraphServlet,最后传递到 PieBar 用以图形化和输出。

安装和部署

首先,下载 压缩文档 并将其放到一个临时目录,例如 /tmp

安装

安装时请执行以下步骤:

  1. 解压压缩文档。

  2. 转至 graphing 目录。

  3. 键入下面的命令,导入门户档案 (PAR) 文件:
    % par import -p password -r uid -- TimeTracker.par dn channel

    在这里:
    • password 是登录门户时的口令。
    • uid 是系统管理员的标识名称。
    • dn 是频道目标的标识名称。

表 1 解释了如何导出 uid 和 dn 的值,并提供了示例。

表 1:标识名称
  
名称类型
   

   
示例
 
  
uid
   
install_dir/SUNWam/lib/
AMConfig.properties 文件中的


com.sun.identity.authentication
.super.user
设置
   
Sun ONE Portal Server 6.0:
uid=amadmin,ou=people,o=sun.com,o=isp

Sun ONE Portal Server 6.1:
uid=amadmin,ou=people,dc=sun,dc=com
 
  
dn
   install_dir/SUNWam/lib/
AMConfig.properties 文件中的

com.iplanet.am.defaultOrg
设置
   
Sun ONE Portal Server 6.0:
uid=amadmin,ou=people,o=sun.com,o=isp

Sun ONE Portal Server 6.1:
dc=sun,dc=com
 

注意:以下步骤中描述的用户界面适用于 Sun ONE Portal Server 6.0。Sun ONE Portal Server 6.1 和 6.2 中的 UI 稍有不同。

  1. 执行以下这些步骤,将新的频道添加到门户桌面中:

    1. 登录到 Administration Console。

    2. 在左侧面板中选择机构,跟着选择 Show:Services,然后单击桌面左侧 Portal Server Configuration 下面的箭头。

    3. 在右侧面板的 Display Profile 下单击 Channel and Container Management。

    4. 在 Container Channels 下的滚动列表中单击要为新频道指定的容器。

      要在示例桌面的第一个选项卡中放置新频道,请选择 MyFrontPageTabPanelContainer。

    5. 在 Existing Channels 的滚动列表中选择 TimeTrackerChannel。

    6. 在 Available and Visible 滚动列表的左侧单击 Add。

    7. 单击 Channel Management 下的 Save。

    8. 退出 Administration Console。

  2. DataFactory 类添加到系统类加载器中。请执行以下步骤:

    1. DataFactory 类创建一个目录:

      % mkdir /opt/DataFactory

    2. 将 JAR 文件复制到此目录:

      % cp DataFactory.jar /opt/DataFactory

    3. 将 JAR 文件添加到系统类加载器的 CLASSPATH 属性。

      如果门户运行于 Sun ONE Web 服务器,在 jvm12.conf 文件中追加 jvm.classpath 设置,这个文件位于 install_dir/SUNWam/servers/https-hostname/config,加入的字符串是:

      :/opt/DataFactory/DataFactory.jar

部署

Graph Servlet 驻留在 graph.war 文件中。像部署其他 Web 文档 (WAR) 文件一样部署 Graph Servlet 的 Web 应用。根据不同的 Web 容器,此过程可能会有所不同。如果使用的是 Sun ONE Web 服务器 和 Sun ONE Portal Server 6.0,那么在一行内运行 wdeploy 命令,如下:

% wdeploy deploy -u /graph -i instance_name -v virtual_server_name
-d /opt/GraphServlet graph.war


例如:

% /opt/SUNWam/servers/bin/https/httpadmin/bin/wdeploy deploy
-u /graph -i gravitywell.sun.com -v https-gravitywell.sun.com
-d /opt/GraphServlet graph.war


最后,重新启动 Sun ONE Portal Server。确保 $DISPLAY 环境设置是正确的,同时在启动门户的 shell 中有正确的访问权限。

动态图像

Graph Servlet 演示了动态图像在 Sun ONE Portal Server 中的应用。Sun ONE Portal Server 一收到用户请求(例如对新图片或者带有修订过数据的请求)就将请求发送到 controller.jsp。如果请求是改变图形的样式,controller.jsp 将为 main.jspgraph.jsp 在 URL 中创建 style 参数。请参见代码示例 10。

代码示例 10:创建样式参数

<a href="<dtpc:getDesktopURL/>?<%=channelName%>-
view=graph.jsp&<%=channelName%>-style=Pie">

随后的过程如下:

  1. main.jspgraph.jsp 确定用户请求了哪种图形样式,比如放大或新活动。

  2. main.jspgraph.jsp 调用 DataFactory 中的 setData 方法,并派送请求和数据到系统类加载器,供以后的 DataFactory 访问。

  3. DataFactory 将请求的 SSOToken ID 和数据进行匹配,并将数据作为易于理解的对象进行处理。

  4. GraphServlet 调用 PieBar 来呈现图形。

传递给 Graph Servlet 的数据在 URL 中是可视的,并包含图形的重要参数,如宽度、高度以及样式。

注意:null 值参数将导致错误。请确保为参数设置了默认值。

高速缓存

作为改善性能的方案,高速缓存存储最近生成的数据并用于后续的请求。

Graph Servlet 支持高速缓存,这样可确保频道的视图能保持连续,甚至在刷新之后或用户从浏览其他内容返回之后也是如此。

体系结构的优点与缺点

软件解决方案中包含多种任务。具体采用哪种解决方案,主要取决于代码的“简洁度” —— 程序越简洁明了,解决方案就越健壮。例如,Graph Servlet 只使用一个 servlet 来生成饼形图和条形图。如果使用两个 servlet 将使部署过程复杂化并增加实现的费用。

下面是对 Graph Servlet 设计方面的优缺点分析:

  • JSPProvider 与其他内容提供者

    JSPProvider 使用 JSP 页面创建桌面频道内容。由于以下这两个主要优势,JSPProvider 相对其他内容提供者(例如 ProfileProviderAdapter)来说,提供了更有效的开发周期:

    • JSPProvider 提供了从表示层分离逻辑层的标准方案:JSP 页面文件包含表示层;大多数逻辑层驻留在分离类的 Java 代码中。

    • JSPProvider 可以在不必重新启动 Web 服务器的情况下更新 JSP 页面。

  • 系统类加载器中的数据与会话数据

    您不能访问门户的 session 对象,且分离的 Web 应用不能共享同一会话。重新调用会话以在不同 Web 应用间共享数据,您可以将这些数据存储在从系统类加载器载入的 Singleton 类中。

  • 深度集成与浅层集成

    在采用浅层集成的体系结构中单击频道内的链接将为目标位置打开一个新浏览器窗口。

    Graph Servlet 采用深度集成,即剩余程序在其自身频道内。因此,当您单击 Graph Servlet 频道内的链接时,该频道内的视图就会变化,导致对屏幕内容的保存。

    深度集成需要更复杂的实现。然而,它的许多优点都可在同一桌面上访问到,而不需要付出额外的努力。这些优点包括,减少了弹出窗口的数量,并且对 安全远程访问附加产品 的集成更稳定。对于大多数的 Sun ONE Portal Server 频道,深度集成提供了更健壮的用户界面。

  • 通过 URL 的共享数据与其他方案

    因为不能访问会话数据,所以 GraphServlet 使用 HttpServletRequest 对象中的参数来接收信息。此方案不仅是一个简单的共享数据解决方案,还能揭示数据是否从一个组件正确地传递到了另一个组件 —— 这是调试时最有用的线索。

    使用此方案的优点在于用户可以修改 URL 中的参数,在浏览器中可以清楚地看到 URL。

故障诊断

您可以在系统控制台或 Web 服务器日志中查找解决问题的线索。还可以启动调试进程解决问题,方法如下:

  • 以 root 身份登录,修改 /opt/SUNWam/lib/AMConfig.properties 文件。

  • 将其设置为您需要的级别以激活调试:errorwarningmessageall

  • 插入 com.iplanet.am.util.* 包的 Debug 类中的调试语句。保存更改。

表 2 描述了公共错误条件及解决问题的建议。

表 2:错误条件和故障诊断技巧
  
错误
   
故障诊断技巧
 
  
图像不能显示
   
请参见 awt 错误的 Web 服务器日志。如果存在,则可能是 DISPLAY 环境变量设置不正确。查看 DISPLAY 是否设置在同一 shell 或重新启动 Web 服务器的终端中。如果不存在,在 shell 命令行或 Web 服务器执行的终端中,键入:
% setenv DISPLAY hostname:0.0

在默认状态下,X 服务器只为登录用户授予显示图像的权限。确保 root 用户具有此权限,在 shell 命令行或主机终端键入:
% xhost +hostname

键入下面的命令进行测试:
% xterm

如果扩展的终端显示出来,则权限正确。

验证 URL 和图像是否正确。要测试图像,请打开一个新的浏览器窗口,并在此窗口中单击图像,而不是通过 Sun ONE Portal Server。
 
  
图形视图破坏了其他门户频道
   
可能未在 URL 中指明频道名称,这将导致 Sun ONE Portal Server 6 将请求发送到所有频道。当定义 URL (例如,您选择的视图) 变量时,请确保频道名称完全正确。下面是一个正确的 URL 示例:

<a href="<dtpc:getDesktopURL/>?<%=channelName%>-
view=graph.jsp">exampleLink</a>

 
  
不显示数据
   
验证 JSP 页面中的代码是否已将数据置于 DataFactory 对象中
 
  
graph.jsp 不能访问所需数据
   
确保已将类文件部署到正确位置,且 Web 应用指向正确的目标
 

参考资料

关于作者:

Paul Lovvik 有六年的 Sun 工作经历,他是 Sun ONE Portal Server ISV 组在市场拓展中的首席工程师。在过去的两年中,Paul 和他的团队为 Sun ONE Portal Server 的 ISV 解决方案设计了接近 40 个集成环境。

Beverly Sum 是一个对编程有强烈兴趣的中学生,2003 年夏天与 Sun 签约。她在 Paul 领导的团队中开发 Graph Servlet。

Marina SumSun Developer Network 的专栏作家。14 年来,她一直为 Sun 从事写作工作,写作内容大多涉及技术领域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值