`
水卢(waterloo)
  • 浏览: 32309 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

基于Web2.0的Web剪切Portlet

阅读更多
    这个Portlet采用Web2.0技术实现,其原因在于,如果读取目标HTML页面是同步载入的话,当页面含有大量的此类Portlet的时候,Portal页面必须要等到所有的Web剪切Portlet都载入后才能够显示出来,当目标页面所在的服务器在Internet的时候,Portal页面的载入过程将会变得非常缓慢。采用的Web2.0的异步载入的方式,将能够很大程度的提高页面载入速度。
下面描述的是这个Portlet的实现思路:
1. 首先显示一个展示有“载入内容”的HTML页面,Portal页面打开时首先显示该页面;
2. 通过XMLHttpRequest对象请求服务器端的Servlet将目标HTML页面读出来;
3. 解析HTML页面,将要截取的HTML区段解析出来;
4. 通过正则表达式将HTML区段中的相关资源的相对引用转换为绝对引用;
5. 根据需要,将HTML区段中的CSS定义替换为新的CSS定义。
6. 对Portlet进行局部刷新,显示截取内容。

<%@page language="java" contentType="text/html; charset=GB18030"
	pageEncoding="GB18030" session="false"%>
<%@taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ page import="javax.portlet.PortletPreferences,com.ibm.webclipping.Constants" %>
<portlet:defineObjects />
<div id="content" align="center"  style="width:100%;height:100%">
<script name="script" language="JavaScript">{
	if (window.XMLHttpRequest){
		xmlObj = new XMLHttpRequest();
	}else if (window.ActiveXObject){
		xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlObj.onreadystatechange = handleResponse;
			
<% PortletPreferences preference = renderRequest.getPreferences(); %>
var params = <%= "\"" + Constants.KEY_URL + '=' + preference.getValue(Constants.KEY_URL, "") + '&' +
	Constants.KEY_CHARTSET + '=' + preference.getValue(Constants.KEY_CHARTSET, "") + '&' +
	Constants.KEY_BEGINTAG + '=' + preference.getValue(Constants.KEY_BEGINTAG, "") + '&' +
	Constants.KEY_ENDTAG + '=' + preference.getValue(Constants.KEY_ENDTAG, "") + '&' +
	Constants.KEY_REGULATOR + '=' + preference.getValue(Constants.KEY_REGULATOR, "") + '&' +
	Constants.KEY_REPLACEMENT + '=' + preference.getValue(Constants.KEY_REPLACEMENT, "") + "\""%>;
	xmlObj.open("POST",'<%= renderResponse.encodeURL(renderRequest.getContextPath()+"/ReadContentServlet")%>',true);
	xmlObj.setRequestHeader("content-type", "application/x-www-form-urlencoded");
	xmlObj.setRequestHeader("content-length", params.length);
	xmlObj.send(params); 	
}
	function handleResponse() {
		if (xmlObj.readyState == 4){//xmlObj loaded	    
			if (xmlObj.status == 200){
				var datas = xmlObj.responseText;
				var obj = document.getElementById("content");
				obj.innerHTML = datas;
			}
		}
	}
</script>
<img src='<%= renderResponse.encodeURL(renderRequest.getContextPath()+"/images/loading.gif") %>'/>
</div>


Constants.KEY_URL:目标页面的URL
Constants.KEY_CHARTSET:目标页面的编码
Constants.KEY_BEGINTAG:目标页面要截取内容的开始html内容
Constants.KEY_ENDTAG:目标页面要截取内容的结束html内容
Constants.KEY_REGULATOR:匹配正则表达式
Constants.KEY_REPLACEMENT:匹配内容的替换表达式


通过HTTP请求将目标HTML内容读出来,为了达到这个目标,我们采用java.net.URL对象来实现,通过这个对象,我们可以把指定地址的HTML内容读出到一个字符串中,为下一步的处理做准备。

//读取strURL中的HTML内容
URL url = new URL(strURL);		   
StringBuffer buffer = new StringBuffer();
String strLine = "";
//从URL中读取内容,
InputStreamReader reader = new InputStreamReader(url.openStream(),charsetName);
BufferedReader br = new BufferedReader(reader);
while ((strLine = br.readLine()) != null) {
	buffer.append(strLine.toLowerCase());
	buffer.append("\r\n");
}
br.close();


这段代码中有两个需要注意的地方,第一是变量charsetName,这个变量必须与目标HTML页面的编码一致,否则会有乱码出现,尤其是中文环境下。第二个重点是buffer.append("\r\n"),当我们从目标HTML页面读取内容到一个字符串中的时候,我们必须要保证目标HTML的内容原原本本的读入到字符串中。由于我们在后面的步骤中要对其进行切割和替换,所以这一点尤其重要。

第三步就是要将读出的HTML内容进行截取,获得要剪切的那部分页面内容。我们通过字符串的indexOf方法来实现。

int beginIndex = buffer.indexOf(beginTag,0);
if(-1 == beginIndex){
result = "未找到起始字符串";
}
//System.out.println("beginIndex is " + beginIndex);
int endIndex = buffer.indexOf(endTag,0);
if(-1 == endIndex){
    result = "未找到结束字符串";
}	
buffer.substring(beginIndex, endIndex);


下面,我们就要通过正则表达式对截取的HTML内容进行替换。在进行内容截取的时候,页面上的资源(例如,图片,超链接,js等)都是采用的相对地址,这里需要将这些相对地址替换为绝对地址,当展示在Portal上不会出现空连接的错误。同时还可以根据需要对class进行替换,使其与整个门户的风格一致。下面的这段代码通过循环一次性的对HTML中的内容进行替换。
//获取beginTag和endTag之间的内容,并对其进行匹配
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(buffer.substring(beginIndex, endIndex));
StringBuffer replacementResult = new StringBuffer();
//分解reg和replacement的区段
// regToken是通过”|”进行分割的正则表达式集合
StringTokenizer regToken = new StringTokenizer(reg,"|");
// replacementToken是通过”|”进行分割的替换内容集合,与正则表达式集合一一对应
StringTokenizer replacementToken = new StringTokenizer(replacement,"|");				
//对匹配出的内容依次进行替换
while(matcher.find()){				    
String matched = matcher.group();					
	//循环判断应该替换哪个内容
	while(regToken.hasMoreElements()){		
		Pattern subPattern = Pattern.compile(regToken.nextToken());
		Matcher subMatcher = subPattern.matcher(matched);
		if(subMatcher.matches()){
			matcher.appendReplacement(replacementResult, replacementToken.nextToken());
			break;
		}
		else
			//如果匹配不成功,将replacementToken的指针向下移动一级
			replacementToken.nextToken();
		}					
		//初始化两个Token,重新开始比对
		regToken = new StringTokenizer(reg,"|");
		replacementToken = new StringTokenizer(replacement,"|");
	}
	matcher.appendTail(replacementResult);
	result = replacementResult.toString();
}


上述方式有一定的局限性,但是在大多数场合能够应用,可以通过定制实现更强大的能力。
分享到:
评论

相关推荐

    portlet 2.0 api doc

    9. **安全性和权限**:Portlet 2.0 API提供了基于角色的访问控制(RBAC),允许portlet根据用户的权限来限制其功能。 10. **国际化和本地化**:portlet可以通过资源bundle提供多语言支持,使应用能够适应不同的地域...

    portlet 2.0 api

    portlet 2.0 api,JSR286下的portlet 2.0 api java类接口,有兴趣的可以下。

    基于Portal和Portlet技术的Web整合应用研究与实现

    基于Portal和Portlet技术的Web整合应用研究与实现基于Portal和Portlet技术的Web整合应用研究与实现基于Portal和Portlet技术的Web整合应用研究与实现基于Portal和Portlet技术的Web整合应用研究与实现

    awection:基于 Portlet 2.0 规范的拍卖实现,用于 Liferay 门户

    基于 Portlet 2.0 规范的拍卖实现,用于 Liferay 门户。 应与结合使用以获得最佳效果。 注意:该主题将与与 Apache Tomcat 服务器捆绑在一起的 Liferay 6.2 GA 3 一起使用。 它可能也适用于 Glassfish 或 JBoss 包...

    官方资料:Oracle WebCenter将组合应用程序Web 2.0集成到企业.pdf

    官方资料:Oracle WebCenter将组合应用程序Web 2.0集成到企业 Oracle融合中间件、最新的Java UI JSF、JSR-227、JSR-168、JCR 1.0,支持SOA、可热插拔、 WebCenter Framework• 使用 JDeveloper 构建上下文丰富的、可...

    portlet-2.0.jar

    portlet-2.0.jar,

    portlet-api-2.0.jar

    portlet-api-2.0.jar,javax.portlet.*

    JavaTM Portlet Specification 2.0

    ### JavaTM Portlet Specification 2.0 - 关键知识点解析 #### 一、概述 《JavaTM Portlet Specification 2.0》(简称JSR 286)是关于Portlet技术的一份重要规范,由Java Community Process (JCP)发布,版本号为2.0...

    pluto部署到tomcat的步骤 同时包含portlet-api-2.0.jar资源

    总的来说,将Pluto部署到Tomcat并结合portlet-api-2.0.jar进行portlet开发,是Java Web开发中的一个重要实践。理解这些步骤和API有助于构建动态、可扩展的Web应用,特别是那些需要集成多种功能和数据源的企业级门户...

    Portlet 2.0 新特性介绍(全)

    系列文章专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学习完本系列后,您将了解相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及...

    portlet 2.0 API.chm

    文档中主要包括以下两个包 javax.portlet javax.portlet.filter

    spring-webmvc-portlet-3.1.1.RELEASE.jar.zip

    Spring Web MVC Portlet的控制器通常是一个实现了Controller接口或者基于注解的@RestController的类。这些控制器处理来自portlet的请求,调用业务逻辑,然后返回一个ModelAndView对象,指示视图如何渲染结果。 五、...

    spring-webmvc-portlet.rar

    Spring Web MVC是一个基于模型-视图-控制器(MVC)设计模式的Web应用框架,它提供了一种松散耦合的编程模型,帮助开发者创建易于维护和测试的代码。Spring Web MVC的核心特性包括: 1. **依赖注入**:通过依赖注入...

    spring-webmvc-portlet-3.2.7.RELEASE.jar

    spring-webmvc-portlet-3.2.7.RELEASE.jarspring-webmvc-portlet-3.2.7.RELEASE.jarspring-webmvc-portlet-3.2.7.RELEASE.jarspring-webmvc-portlet-3.2.7.RELEASE.jar

    web-form-portlet.rar_portlet_web form

    本文将深入探讨“web-form-portlet.rar_portlet_web form”这个主题,介绍如何开发Web表单(Web Form)以及如何利用插件进行Portlet开发。 一、Portlet简介 Portlet是Java Portlet API规范定义的一种组件模型,它...

    plrtlet 2.0 api 网页版

    Portlet 2.0 API 是一个关键的Java技术,用于构建可重用的Web组件,特别是在企业级的Java应用服务器上,如IBM WebSphere或Oracle WebLogic等。它定义了一套标准接口,允许开发者创建可嵌入到门户环境中的交互式小...

    portlet详细例子

    portlet API是由JSR 286(Portlet 2.0)和JSR 168(Portlet 1.0)定义的一套接口和类,它提供了portlet开发所需的各种工具和方法。API文档通常会包含以下内容: 1. **Portlet生命周期**:portlet有三个主要的生命...

    spring-webmvc-portlet-4.0.0.RELEASE.jar

    spring-webmvc-portlet-4.0.0.RELEASE.jar

Global site tag (gtag.js) - Google Analytics