1 背景概述
Portlet是AEAI Portal组件API,是基于Java的Web组件,由Portlet容器管理,并由容器处理请求,生产动态内容。AEAI Portal中已经预置了许多Portlet组件,可以直接配置使用。由于不同业务需求也可以将Portlet进行定制开发。本文是本人在综合集成项目中由于业务需要动态显示风险统计信息,即对某一风险进行评估时引用不同的风险点对其的影响(可能性与影响程度的乘积)进行分析,并在页面以个数的形式显示不同区间所包含风险点的影响。故而对Portlet的定制开发的过程以及方法进行总结。
2 预期读者
-
AEAI Portlet开发人员
-
数通畅联人员
-
其他相关人员
3 技能要求
本文档假定目标用户具备以下技能:
-
了解Eclipse基本用法;
-
了解基本数据库知识安装以及SQL基本技能;
-
了解AEAI Portal基本知识;
-
了解AEAI ESB基本知识。
4 名词解释
5 实现思路
Portlet工程的定制开发过程大致为:初始化数据库portal、portal_test,portal_test中初始化业务数据表(risk_level_setting、risk_analyze_entry)以便提供业务需要的数据(参见6.3数据表初始化),在ESB工程(TestPortlets)中创建数据源portal_test(连接数据库portal_test)以及创建消息流程(测试Portlets)来提供页面显示的数据信息(参见7.3Json处理),本地搭建Portal环境,开发Portlet工程,配置开发的Portlet实现业务需求。6 实现步骤
6.1 创建工程
1. 在中点击创建工程,选择集成Web项目,填写应用名称(可自定义)、主目录(可自定义),点击测试连接,连接成功后点击Next按钮。配置如下图:
2. 填写连接的数据库名称,对应的用户名以及密码点击测试连接弹出连接成功后点击Finish按钮。
按钮若创建的PortLet数据库中没有内容,则点击初始化数据,将自动生成数据表。若数据库已经存在且有内容,不可点击初始化数据,否则将覆盖已有的数据库内容。
3. 由于新版的PortalServer的加密机制升级与当前的的加密机制不同,故需修改对应配置文件中的密码(参见附件中密码生成文档)
4. 替换新的密码位置(两处)如下:
1) 工程中的配置文件
2) (你的设计器的路径)\miscdp-studio-win32_x86\workspace\test_portlets下的
5. 点开新创建的项目,在业务管理上点击右键,选择创建功能。
6. 填写功能名称(可自定义),功能类型选择Portlet功能模型,点击Finish按钮。
7. 如下图所示,填写目录编码(可自定义)保存。
8. 点击按钮生成代码,点击按钮或者点击切换到Java透视图可以查看代码。如下图:
9. 开发Portlet的Java类(相当于Handler)
1) 定义四个方法(具体参见7.1四个方法)
1. @RenderMode(name ="view")—指向View页面构造页面需要的属性
publicvoidview(RenderRequest request, RenderResponse response)
2. @RenderMode(name = "edit")—指向Edit页面构造页面需要的属性
publicvoidedit(RenderRequest request, RenderResponse response)
3. @ProcessAction(name ="saveConfig")
publicvoidsaveConfig(ActionRequest request, ActionResponse response)
4. @Resource(id ="getAjaxData")支持异步传递传递回调函数需要的Json等信息
publicvoidgetAjaxData(ResourceRequest request, ResourceResponse response)
2) 创建两个页面(具体参见7.2两个页面)
1. View—在js中添加回调函数(回调函数处理Json等显示的信息)
2. Edit—传递属性信息
10. 扩展方法以及页面完成后点击加载应用,重启应用
6.2 数据表初始化
1. 初始化数据表(Json中用到的业务数据)
1) 在数据库中创建数据表risk_level_setting 步骤如下:
2) 在下点击下的将下面的SQL复制在其中
DROP TABLE IF EXISTS `risk_level_setting`;
CREATE TABLE `risk_level_setting` (
`RL_ID` char(36) NOT NULL,
`RLS_MIN` float DEFAULT NULL,
`RLS_MAX` float DEFAULT NULL,
`RLS_CORLOR` varchar(255) DEFAULT NULL,
PRIMARY KEY (`RL_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of risk_level_setting
-- ----------------------------
INSERT INTO `risk_level_setting` VALUES ('29FE4961-6F01-4913-99E3-24551E3BCF1F', '0', '5', 'GREEN');
INSERT INTO `risk_level_setting` VALUES ('874494A8-CD87-4EC2-9E44-4AAF9A493976', '5', '12', 'YELLOW');
INSERT INTO `risk_level_setting` VALUES ('EE214872-FE74-4F7E-A80F-FDC127570725', '12', '25', 'RED');
|
3) 点击执行
结果如下
4) 在数据库中创建数据表risk_analyze_entry 步骤同上,SQL如下:
DROP TABLE IF EXISTS `risk_analyze_entry`;
CREATE TABLE `risk_analyze_entry` (
`RAE_ID` char(36) NOT NULL,
`RAE_HAPP_POSS` decimal(10,0) DEFAULT NULL,
`RAE_INF_DEGREE` decimal(10,0) DEFAULT NULL,
`RAE_RISK_LEVEL` decimal(10,0) DEFAULT NULL,
`RAE_SORT` int(11) DEFAULT NULL,
PRIMARY KEY (`RAE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of risk_analyze_entry
-- ----------------------------
INSERT INTO `risk_analyze_entry` VALUES ('0EC07E27-5130-4EA8-A64B-6B3DE5DFD22E', '2', '2', '4', null);
INSERT INTO `risk_analyze_entry` VALUES ('470840C1-086C-43C4-977A-7F16D14F7D33', '5', '3', '15', null);
INSERT INTO `risk_analyze_entry` VALUES ('67815A3F-4B52-490B-A520-E787AE8585BE', '3', '3', '9', null);
INSERT INTO `risk_analyze_entry` VALUES ('B76D5B92-FDE5-46E6-8E02-BD06CD6D5E6D', '1', '1', '1', null);
|
6.3 配置说明
1. Portal配置说明
1) 浏览器输入http://localhost:8080/portal/login.jsp访问portal工程,界面如下:
2) 以admin身份登录密码为admin,点击门户管理。
3) 点击组件管理Portlet应用
4) 点击按钮填写编码标识(为自定义开发的portlets工程名)、编码值(可自定义)、选择编码类型、编码排序、选择是否有效,后点击保存按钮。
5) 点击组件管理中的Portlet设置
6) 点击按钮填写标题(可自定义)、选择所属应用、Portlet名称、分组,后点击保存按钮。
7) 点击下的点击综合门户如下图:
8) 选中点击右侧的弹出界面填写编码、名称(可自定义)点击保存按钮。配置如下:
9) 点击刚创建好的切换到页面布局点击按钮添加容器
10) 弹出的界面选择对应的Portlet
点击保存按钮
11) 点击下的切换回主界面,点击决策分析菜单中的显示如下图:
12) 点击按钮切换到界面,将创建的ESB流程中的HttpRequest节点(参见7.3Json处理)的访问地址填写到数据URL中,设置高度,点击保存按钮。配置如下:
13) 结果如下:
6.4 参考技巧
由于本人Portlet的开发并不是十分了解,故在开发过程中找到如下小技巧为开发者提供参考。对根据需求开发不同功能的Portlet,定义所需要的属性,可利用反编译软件打开已封装完现有的Portlet组件功能,作为实现的参考。达到Portlet的定制开发的目的。参考路径为:…..你的服务器的地址)\portal_server_x64_Vx.x.x.YYYYMMDD\webapps\portal_portlets\WEB-INF
\classes\com\agileai\portal\portlets
7 核心说明
7.1 四个方法
1. 自定义开发的Portlets中扩展开发下面的四个方法,本例位于
2. View方法中指向View页面构造页面需要的属性
@RenderMode(name = "view")
publicvoid view(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
PortletPreferences preferences = PreferencesHelper.getPublicPreference(request);
String chartHeight = preferences.getValue("chartHeight", "50");
String namespace = preferences.getValue("namespace", null);
String defaultVariableValues = preferences.getValue("defaultVariableValues", null);
String dataURL = preferences.getValue("dataURL", null);
String defaultValueString = "namespace="+namespace+"&"+defaultVariableValues;
PortletVariableHelper variableHelper = new PortletVariableHelper(request,defaultValueString);
dataURL = variableHelper.getRealDataURL(dataURL);
String portletId = request.getWindowID();
Integer height = Integer.parseInt(chartHeight);
request.setAttribute("height", height);
request.setAttribute("portletId", portletId);
request.setAttribute("namespace", namespace);
request.setAttribute("dataURL", dataURL);
super.doView(request, response);
}
|
3. Edit方法中指向Edit页面构造页面需要的属性
@RenderMode(name = "edit")
publicvoid edit(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
PortletPreferences preferences = PreferencesHelper.getPublicPreference(request);
String dataURL = preferences.getValue("dataURL", null);
String chartHeight = preferences.getValue("chartHeight", null);
String namespace = preferences.getValue("namespace", null);
String defaultVariableValues = preferences.getValue("defaultVariableValues", null);
request.setAttribute("dataURL", dataURL);
request.setAttribute("chartHeight", chartHeight);
request.setAttribute("namespace", namespace);
request.setAttribute("defaultVariableValues", defaultVariableValues);
super.doEdit(request, response);
}
|
4. saveConfig方法保存配置信息
@ProcessAction(name = "saveConfig")
publicvoid saveConfig(ActionRequest request, ActionResponse response)
throws ReadOnlyException, PortletModeException, ValidatorException,
IOException, PreferenceException {
String dataURL = request.getParameter("dataURL");
String chartHeight = request.getParameter("chartHeight");
String namespace = request.getParameter("namespace");
String defaultVariableValues = request.getParameter("defaultVariableValues");
PreferencesWrapper preferWapper = new PreferencesWrapper();
preferWapper.setValue("dataURL", dataURL);
preferWapper.setValue("chartHeight", chartHeight);
preferWapper.setValue("namespace", namespace);
preferWapper.setValue("defaultVariableValues", defaultVariableValues);
PreferencesHelper.savePublicPreferences(request,preferWapper.getPreferences());
response.setPortletMode(PortletMode.VIEW);
}
|
5. getAjaxData支持异步传递传递回调函数需要的Json等信息
@Resource(id = "getAjaxData")
publicvoid getAjaxData(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
String ajaxData = "";
try {
String dataURL = getDataURL(request);
StringWriter buffer = new StringWriter();
URL url = new URL(dataURL);
InputStream inputStream = url.openStream();
IOUtils.copy(inputStream, buffer, "UTF-8");
IOUtils.closeQuietly(inputStream);
ajaxData = buffer.toString();
} catch (Exception e) {
this.logger.error("获取取数据失败getAjaxData", e);
}
PrintWriter writer = response.getWriter();
writer.print(ajaxData);
writer.close();
}
|
7.2 两个页面
1. 自定义开发的Portlets中扩展开发下面的两个页面,本例位于WebRoot下:
2. view页面为界面所显示的信息,其中responseText为getAjaxData方法中返回的参数Json
获得Java类中定义的height变量,将css的高度变量化
代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page import="com.agileai.hotweb.domain.PageBean"%>
<portlet:defineObjects/>
<%
Integer height = (Integer)request.getAttribute("height");
Integer tab2height = (Integer)request.getAttribute("height") - height/10;
%>
<style>
.graphTable<portlet:namespace/>{
font-family: verdana,arial,sans-serif;
border-width:1px;
border-color: #000000;
border-collapse: collapse;
}
.graphTable<portlet:namespace/>tr{
height:<%=height%>px;
border-width: 1px;
border-style: solid;
border-color: #000000;
}
.graphTable<portlet:namespace/> tr td{
height:<%=height%>px;
width:<%=height%>px;
text-align:center;
border-width: 1px;
border-style: solid;
border-color: #000000;
}
.table2<portlet:namespace/> tr td{
width:<%=height%>px;
text-align:right;
}
.table1<portlet:namespace/> tr td{
height:<%=tab2height%>px;
}
</style>
<portlet:resourceURL id="getAjaxData" var="getAjaxDataURL">
</portlet:resourceURL>
<body>
<span style="float:left">
<table border="0" style="float:left" class = "table1<portlet:namespace/>" id="table1">
<tr>
<td>影</td>
<td> </td>
<td>5.0</td>
</tr>
<tr>
<td>响</td>
<td> </td>
<td>4.0</td>
</tr>
<tr>
<td>程</td>
<td> </td>
<td>3.0</td>
</tr>
<tr>
<td>度</td>
<td> </td>
<td>2.0</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>1.0</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>0.0</td>
</tr>
</table>
<table border="1" class="graphTable<portlet:namespace/>" id="graphTable1">
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
<table border="0" class="table2<portlet:namespace/>" id="table2">
<tr>
<td>1.0</td>
<td>2.0</td>
<td>3.0</td>
<td>4.0</td>
<td>5.0</td>
</tr>
<tr>
<td> </td>
<td>可</td>
<td>能</td>
<td>性</td>
<td> </td>
</tr>
</table>
</span>
</body>
<%
String portletId = (String)request.getAttribute("portletId");
%>
<div>${someProperty}</div>
<script type="text/javascript">
$(function(){
var __renderPortlet<portlet:namespace/> = function(){
sendAction('${getAjaxDataURL}',{dataType:'text',onComplete:function(ajaxData){
var allJson = $.parseJSON(ajaxData);
var rowCountIndex = 0;
for (var i=5;i > 0;i--){
rowCountIndex++;
for (var j=0;j < 5;j++){
var rowIndex = i-1;
var colIndex = j;
var colCountIndex = j+1;
var total = rowCountIndex * colCountIndex;
if (total >= allJson.dataLine.GREEN.min && total <= allJson.dataLine.GREEN.max){
$("#graphTable1 tr:eq("+rowIndex+") td:eq("+colIndex+")").css("background-color","green");
}
elseif (total >= allJson.dataLine.YELLOW.min && total <= allJson.dataLine.YELLOW.max){
$("#graphTable1 tr:eq("+rowIndex+") td:eq("+colIndex+")").css("background-color","yellow");
}
else{
$("#graphTable1 tr:eq("+rowIndex+") td:eq("+colIndex+")").css("background-color","red");
}
}
}
for (var i=0 ;i < 25 ;i++){
if(allJson.cellNumbers[i].count == 0){
$("#graphTable1 tr:eq("+allJson.cellNumbers[i].rowIndex+") td:eq("+allJson.cellNumbers[i].colIndex+")").text("");
}else{
$("#graphTable1 tr:eq("+allJson.cellNumbers[i].rowIndex+") td:eq("+allJson.cellNumbers[i].colIndex+")").text(allJson.cellNumbers[i].count);
}
}
}});
};
__renderPortlets.put("<%=portletId%>",__renderPortlet<portlet:namespace/>);
__renderPortlet<portlet:namespace/>();
});
</script>
|
3. Edit页面为配置Portal中编辑页面所显示的属性信息如下图:
编辑页面所显示的属性
代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<portlet:defineObjects/>
<portlet:actionURL name="saveConfig" var="saveConfigURL"></portlet:actionURL>
<portlet:renderURL portletMode="edit" var="editURL"></portlet:renderURL>
<%
String isCache = (String)request.getAttribute("isCache");
%>
<form id="<portlet:namespace/>Form">
<table width="90%" border="1">
<tr>
<td width="120">数据URL <span style="color: red;">*</span></td>
<td><input type="text" size="50" name="dataURL" id="dataURL" value="${dataURL}" /></td>
</tr>
<tr>
<td width="120">默认值</td>
<td>
<input type="text" name="defaultVariableValues" id="defaultVariableValues" size="50" value="${defaultVariableValues}" />
</td>
</tr>
<tr>
<td width="120">高度 <span style="color: red;">*</span></td>
<td><input type="text" size="50" name="chartHeight" id="chartHeight" value="${chartHeight}" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="button" name="button" id="button" value="保存" />
<input type="button" name="button2" id="button2" value="取消" onclick="fireAction('${editURL}')"/></td>
</tr>
</table>
</form>
<script language="javascript">
</script>
|
7.3 Json处理
1. ESB创建工程TestPortlets、创建数据源portal_test为ESB的基础知识,在这里不做过多的赘述。(可参见AEAI ESB集成平台技术手册)
2. ESB创建消息流程
1) 在消息流程中添加数据查询节点以及数据转换节点
2) 在JdbcQueryer节点中创建DataSet接收查询的结果集
3) 在JavaConverter中创建XXX用于接收转换后的结果集,在扩展代码中修改对应代码
4) 在HttpResponse中打印转换后的结果:@{XXX}
3. 流程图如下:
查询风险评价节点选择数据源创建结果类型变量riskGraphMaxMinDataSet,点击选择表选择数据表(risk_level_setting)生成SQL。配置如下:
点击刷新按钮后,点击Finish按钮。
查询风险点节点(参见查询风险评价节点)结果变量为(riskGraphDataSet)数据表为(risk_analyze_entry)配置如下:
下面我们重点讲解JOSN格式转换节点。
双击改节点选择转换,DataSet装换为数据表格,点击Next按钮。
点击选择按钮选择来源变量,创建目标变量,选中扩展代码,点击Finish按钮。
扩展代码如下:
创建Json存储、最外层的Json名称为dataLine
将rowIndex与colIndex放入到子Json中。
此方法是由于业务需要设置默认值均为0
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import com.agileai.domain.DataRow;
import com.agileai.domain.DataSet;
import com.agileai.esb.component.Variable;
import com.agileai.esb.component.transformer.JavaTransformer;
import com.agileai.esb.core.AdapteException;
publicclass JavaConverter1 extends JavaTransformer{
private List<DataRow> dataModel = new ArrayList<DataRow>();
publicvoid handleRequest() throws AdapteException{
try {
this.initModel();
Variable riskGraphVariable = this.getVariable("riskGraphDataSet");
Variable riskGraphMaxMinVariable = this.getVariable("riskGraphMaxMinDataSet");
DataSet riskGraphDataSet = (DataSet)riskGraphVariable.getValue();
for (int i=0;i < riskGraphDataSet.size();i++){
DataRow row = riskGraphDataSet.getDataRow(i);
BigDecimal degree = (BigDecimal)row.get("RAE_INF_DEGREE");
for (int m =0 ;m < 5;m++){
if (degree.compareTo(new BigDecimal(m)) > 0 && degree.compareTo(new BigDecimal(m+1)) <=0){
DataRow modelRow = this.dataModel.get(m);
BigDecimal poss = (BigDecimal)row.get("RAE_HAPP_POSS");
for (int n = 0;n < 5;n++){
if (poss.compareTo(new BigDecimal(n)) > 0 && poss.compareTo(new BigDecimal(n+1)) <=0){
Integer currentCount = (Integer)modelRow.get(String.valueOf(n));
modelRow.put(String.valueOf(n),++currentCount);
}
}
}
}
}
DataSet riskGraphMaxMinDataSet = (DataSet)riskGraphMaxMinVariable.getValue();
JSONArray riskGraphjsonArray = new JSONArray();
JSONObject totalJsonObj = new JSONObject();
JSONObject riskGraphMaxMinJsonObj = new JSONObject();
for (int i=0;i < riskGraphMaxMinDataSet.size();i++){
DataRow dataLineRow = riskGraphMaxMinDataSet.getDataRow(i);
JSONObject dataLinejsonObject = new JSONObject();
riskGraphMaxMinJsonObj.put(dataLineRow.stringValue("RLS_CORLOR"),dataLinejsonObject);
dataLinejsonObject.put("min", dataLineRow.stringValue("RLS_MIN"));
dataLinejsonObject.put("max", dataLineRow.stringValue("RLS_MAX"));
}
totalJsonObj.put("dataLine", riskGraphMaxMinJsonObj);
for (int m=0;m < 5;m++){
DataRow row = this.dataModel.get(m);
for (int n=0;n < 5;n++){
JSONObject cellNumsJsonObject = new JSONObject();
int rowIndex = 4-m;
int colIndex = n;
cellNumsJsonObject.put("rowIndex", rowIndex);
cellNumsJsonObject.put("colIndex", colIndex);
int count = row.getInt(String.valueOf(n));
cellNumsJsonObject.put("count", count);
riskGraphjsonArray.put(cellNumsJsonObject);
}
}
totalJsonObj.put("cellNumbers", riskGraphjsonArray);
Variable targetVariable = this.getVariable("riskGraphJson");
targetVariable.setValue(totalJsonObj);
} catch (Exception e) {
logger.error(e.getLocalizedMessage(), e);
thrownew AdapteException(e.getLocalizedMessage(),e);
}
}
privatevoid initModel(){
for (int i=0;i < 5;i++){
DataRow row = new DataRow();
this.dataModel.add(row);
for (int n=0;n < 5;n++){
row.put(String.valueOf(n),0);
}
}
}
}
|
HttpResponse节点打印Json配置如下:
4. 在TestPortlets应用节点右键,如下:
5. 点击部署ESB应用,弹出窗口如下:
6. 点击“Finish”,由于部署ESB应用可能较慢(5-10秒),可能在设计器上没有及时响应,图表处于变灰状态,点击按钮来刷新,左边的菜单节点才能高亮显示,如下:
7. 访问HttpRequest节点的URL http://localhost:9090/TestPortlets/http/TestPortlets得到Json如下:
8 附件说明
ESB文件夹/ TestPortlets.zip:消息流程--测试Portlets提供业务数据
Portal文件夹/ portal.zip:本地搭建portal环境
Portal文件夹/ portal_portlets.zip:封装好的portlets
Portal文件夹/ test_portlets.zip:自定义开发的portlets
sqls文件夹/ portal.sql本地搭建portal环境需要的数据库文件
sqls文件夹/ portal_test.sql提供自定义开发的portlets需要的数据库信息,包含需要初始化的业务数据表
密码生成:生成密文密码的方法
AEAI Portlet开发心得相关附件及文档 下载
相关推荐
Portlet开发参考手册是针对portlet技术的一份详细指南,它为开发者提供了全面的指导,以帮助他们构建和集成portlet到Web门户中。Portlet是一种可重用的Web组件,它们在门户环境中运行,允许用户自定义门户界面,展示...
Portlet开发是构建企业级Web应用程序的一种方法,它允许在门户环境中创建可重用和交互的小型组件。在本文中,我们将深入探讨portlet的开发、相关的工具包以及如何将portlet应用整合到Tomcat服务器中。 首先,理解...
### Portlet开发指南知识点概述 #### 一、Portlet简介 **什么是Portal?** Portal是一种Web应用程序,它为用户提供了一个集中的入口点来访问各种不同的应用程序和服务。Portal通常包括多种功能,如新闻、天气预报、...
Liferay Portlet开发文档是一份全面介绍Liferay Portlet开发的指南,内容涵盖了Portal的概念、Portlet的定义以及JSR 286(Java Specification Request 286)规范。文档强调了Liferay作为一款开源企业级门户网站解决...
portlet开发高层设计 在Web应用程序开发领域,portlet是一种可重用的、自包含的用户界面组件,它可以在门户环境中运行。JSR168(Java Portlet API 1.0)是Java Community Process定义的一个标准,用于规范portlet的...
5. **Portlet开发探讨**:"基于Jetspeed的Portlet开发探讨.pdf"可能会讨论一些实际开发中的挑战和解决方案,例如portlet的调试技巧、性能监控方法、最佳实践,以及如何解决portlet与门户平台之间的兼容性问题。...
Portlet开发是构建企业级Web应用程序的一种方法,特别是在Java平台上,它被广泛应用于构建可重用、可组合的Web组件。Portlet技术允许开发者创建独立的功能模块,这些模块可以集成到更大的Web门户中,为用户提供个性...
上述知识点涵盖了从基础到高级的Portlet开发方方面面,详细解释了Portlet的核心概念、开发环境搭建、生命周期、请求处理、状态管理、安全性等多个关键领域。这对于任何希望深入学习和掌握Portlet开发技术的开发者来...
在IT行业中,portlet开发是构建企业级Web应用程序的重要部分,特别是在使用IBM WebSphere Portal或其它支持portlet标准的平台时。Portlet是一种可重用的Web组件,能够在门户环境中提供特定的功能,比如显示新闻、...
在JetSpeed中开发portlet项目是一项涉及Java Web技术的重要工作,主要基于JSR168(portlet规范1.0)标准。JetSpeed是一个开源的企业门户服务器,它支持portlet的开发和集成,提供了一个灵活且可扩展的框架来构建企业...
在IT领域,特别是企业级应用开发中,Liferay作为一个强大的企业门户平台,提供了丰富的功能和服务,其中Liferay Portlet的开发是构建定制化企业应用的关键技术之一。本文将基于提供的文件信息,深入解析Liferay ...
《Liferay Portlet开发参考手册》是温兵先生编著的一本专为开发者设计的指南,旨在帮助读者深入了解和熟练掌握Liferay Portal平台上的Portlet开发技术。Liferay Portal是一款开源的企业级内容管理平台,而Portlet是...
要开始学习portlet开发,首先你需要一个支持portlet的开发环境,如IBM WebSphere Portal Server、Liferay Portal、Apache Pluto等。这些平台提供了portlet容器,可以托管和管理portlet。同时,你还需要一个Java集成...
在"portlet开发资料.rar"这个压缩包中,包含了关于portlet开发的一系列文档,这些文档可能详细介绍了portlet开发的基础到高级概念,帮助开发者从入门到精通掌握portlet开发。 1. **portlet的概念与作用**: - ...
portlet开发手册是IT专业人士在构建portlet应用程序时的重要参考资料,它能帮助开发者深入理解portlet的配置和实现机制。Portlet是Web应用程序的一种组件,通常在门户环境中运行,提供交互式的用户界面。以下是对...
### Struts-Portlet开发详解 #### 一、概述 在深入探讨Struts-Portlet开发之前,我们先来了解一下其基本概念和发展背景。Struts-Portlet是一种结合了Struts框架与Portlet技术的开发模式,它允许开发者在门户环境中...
portlet开发样例主要涵盖两大部分:portlet的类名规范以及使用RAD7开发JSR168portlet的过程。本文将详细阐述这两个方面的内容。 首先,我们来看portlet的类名规范。类名是portlet开发中的一个重要组成部分,它需要...
### Portlet开发指南详解 #### 一、Portlet与Portal技术概述 **1. Portal**:Portal是一种提供统一入口的网站或应用平台,用于整合多种信息和服务资源,为用户提供个性化和集中化的信息展示和交互界面。它能够集成...