`
houzhaowei
  • 浏览: 492614 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

人人网 paoding 旗下 rose 项目实现服务器端 portal

阅读更多

“portal”一词中文翻译为“门户”,所谓门户是指各种信息的集成。

rose portal基于rose框架,是rose的一个插件。这个技术不是基于JavaEE的portlet规范,您只需要使用标准的servlet容器即可实现,而且更简单。

本示例示范如何使用rose portal (基于servlet规范),在一个门户可以显示两个独立的“信息”

创建控制器

1个是Portal主控,另外2个是窗口控制器 1) 在controllers或子目录下创建Portal控制器:PortalController,创建处理方法,并声明Portal参数

package ninja.paoding_rose.test.controllers;

import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.portal.Portal;

@Path("portal")
public class PortalController {
	// 标注@Get,表示这个方法要处理的是对/portal的GET请求
	// 在主控控制方法上声明Portal参数即表示这个页面是portal,就这样!
	@Get
	public String home(Portal portal) throws Exception {
		// 使用addWindow向这个portal页面加入各种子信息(我们成为窗口) 
		portal.addWindow("docin","/windows/docin"); 
		// 第一个参数是用于标识该窗口,使得portal页面中可以引用到这个窗口的html //
		// 第二个参数表示这个窗口的地址(可以包含参数),这个地址等价于forward的地址(也就是这里只要能forward的地址都可以,无论是否是rose框架的,甚至可以是一个jsp页面)
		// // 因此,地址没有说一定要以"/windows"开始
		portal.addWindow("ninja","/windows/ninja?name=value");
		return "portal_page"; 
	}
}

 2) 在controllers.windows下创建可被/windows/docin,/windows/ninja 访问的控制器以及方法 DocinController.java

package ninja.paoding_rose.test.controllers.windows;

import net.paoding.rose.web.Invocation;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;

@Path("docin")
public class DocinController {
	// 这个方法处理"/windows/weather",它只是返回一串中文,而非jsp、vm等页面
	@Get
	public String docin(Invocation inv) {
		return "@豆丁豆丁豆丁豆丁豆丁豆丁豆丁!";
	}
}

 NinjaController.java

package ninja.paoding_rose.test.controllers.windows;

import java.util.ArrayList;
import java.util.List;

import net.paoding.rose.web.Invocation;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.portal.Window;

@Path("ninja")
public class NinjaController {
	// 在控制器使用全局变量并不好,在此仅是一个演示而已
	private int count;

	// 方法名是什么不要紧,关进是@Get代表了这个方法用于处理对/ninja的GET请求
	@Get
	public String ninja(Invocation inv, Window window) {
		List<String> list = new ArrayList<String>();
		list.add("偷袭");
		list.add("忍术");
		list.add(String.valueOf(count++));
		inv.addModel("todolist", list); //
		// 返回页面,rose将从这个模块对应的/views/windows下找名字以ninja开始的页面
		return "ninja";
	}
}

portal页面 

webapp/views下创建PortalController需要的portal_page.jsp (这里亦可以用rose 所支持的.vm文件)

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<html>
<head>
<link href="/static/portal.css" rel="stylesheet" type="text/css" media="all" /> 
<title>Portal</title>
</head>
<body>
<h2>Portal</h2>
<div class="window">
<div class="title">豆丁</div>
<!--这里使用$weather的"weather"即是第一个window的标识-->
<div class="content">${docin}</div>
</div>
<div class="window">
<div class="title">忍者</div>
<!--$todo实际是一个Window对象,velocity会调用其toString()输出html的-->
<div class="content">${ninja}</div>
</div>
</body>
</html>

 

window页面

webapp/views/windows创建ninjaController需要的页面 ninja.jsp (亦可以用ninja.vm 但写法很不同。)

<%@ page import="java.util.*" %>
<ul>
 <%
	List<String> result = (List<String>)request.getAttribute("todolist");
	for(String oneItem : result){
%>
	<li><%=oneItem %></li>
<%
	}
%>
</ul>

 

 

并发数配置

在web.xml的<web-app>下配置并发参数值:

        <context-param> 
                <param-name>portalExecutorCorePoolSize</param-name> 
                <param-value>200</param-value> 
        </context-param>

如果没有配置以上参数,默认portalExecutorCorePoolSize取1,相当于除了http主线程外只有另外1个执行线程, 这对程序的正确性没有任何影响,只是并发能力下降了,整个portal的执行时间也会变长。

 

高级话题

1) 可以在PortalController.home方法上设置@PortalSetting(timeout = 100)表示最多等待各个窗口100ms(包括window的页面渲染耗费时间)

2) 可以通过引入xiaonei-commons-interceptors的@Throughput(maxConcurrent = 20)放置在window的xxx方法上,控制最多并发数

3) 可在web.xml配置全局参数设置poral执行器的线程池参数:portalExecutorCorePoolSize、portalExecutorMaxPoolSize、portalExecutorKeepAliveSeconds

参数意义分别参考java.util.concurrent.ThreadPoolExecutor的corePoolSize、maximumPoolSize、keepAliveTime说明

4) 在portal-home页面中的$weather实际是一个net.paoding.rose.web.portal.Window对象,因此可通过$weather.success 判断window的执行是否完成并且是200的,通过$weather.statusCode等了解具体的执行情况。详细请参考net.paoding.rose.web.portal.Window类属性列表。

5) 可在window的控制器TodoController.xxx方法中声明Window window对象,通过window.setTilte(title)或window.set(name, value)相关属性,并在portal-home.vm使用$todo.title 在todo.vm中,则除了使用todo的名字使用$todo.title,也可以通过$window.title来使用。每个$window在不同的窗口的页面代表自己的Window对象,不会“乱串”

 

启动后,访问http://[yourlocal]/[yourprojectname]/portal

 

可以看到 两个div(这里可以叫做window) 分别通过不同的controller 返回数据。

 

想了解vm页面用法请参考:

http://code.google.com/p/paoding-rose/wiki/Rose_Portal_Demo

此链接为paoding-rose的project home 里面也有paoding-rose 其它方面的介绍

国人罕见的开源项目, 用着也很不错。 祝愿其团队日益强大、此项目风靡国内外。

 

-----------------------

 

补充些东西:

 

portal 的真正意义在于, 在一个页面上如果一个模块down 掉,其它模块还能正常使用。

如人人网的用户个性主页,“用户评论” 模块出现异常,在之前的服务器架构上则会导致整个页面出现异常(因为是由一个controller处理的请求) 。 可能有人说 我用ajax。可以。但ajax是一个页面的多个模块同时向服务器发了多个请求。为服务器增压。而且完全用js 控制页面,也会出现很多不兼容问题。

现在最好的解决方案问世:rose 的portal  整个请求由一个控制器来处理并由这个控制器分发给每个window 的控制器。这些大家都能理解。但关键点在于它的意义。 就在于 portal 的 home 方法的超时配置:@PortalSetting(timeout = 100)

和 并发配置:

        <context-param> 
                <param-name>portalExecutorCorePoolSize</param-name> 
                <param-value>200</param-value> 
        </context-param>
没有超时配置的话,一个窗口超时,controller会永远等待这个窗口,而不返回页面。
没有并发配置的话  默认一个线程处理controller 的转发 会导致如果前面的window 挂掉,会一直在这个window处于等待状态,而其后面的window也就不会处理。虽然返回了页面  但挂掉的window 后面的所有window 也不会显示。

以上代码为本人初次测试的代码,后来又做了新一步测试,实现了超时的窗口不显示而其他窗口正常。
代码不想再一点点上贴,直接发个包儿吧  见附件。
项目用maven 构建 java代码和配置文件分别放在src/main/java 和src/main/resources web文件放在src/main/webapp 。 如果需要项目依赖的jar email我 : ninja.hzw@gmail.com.
2
0
分享到:
评论
1 楼 jiangm520 2012-05-18  
ParamValidator  验证是如何用的,显示使用什么标签和验证采用什么方式?

相关推荐

Global site tag (gtag.js) - Google Analytics