My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Rose_Portal_Demo  
Updated Jul 21, 2010 by qieqie.wang

Portal示例

介绍

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

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

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

创建控制器

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

PortalController.java

    // 按照rose规范来编写控制器即可,控制器必须放到controllers或其子package
    package com.xiaonei.xxx.controllers;
 
    import net.paoding.rose.web.annotation.ReqMapping;
    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("weather", "/windows/weather");

            // 第一个参数是用于标识该窗口,使得portal页面中可以引用到这个窗口的html
            // 第二个参数表示这个窗口的地址(可以包含参数),这个地址等价于forward的地址(也就是这里只要能forward的地址都可以,无论是否是rose框架的,甚至可以是一个jsp页面)
            // 因此,地址没有说一定要以"/windows"开始
            portal.addWindow("todo", "/windows/todo?name=value");

            return "portal-home";
        }
    }

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

    package com.xiaonei.xxx.controllers.windows;
 
    import net.paoding.rose.web.Invocation;
    import net.paoding.rose.web.annotation.rest.Get;
 
    @Path("weather")
    public class WeatherController {
 
        // 这个方法处理"/windows/weather",它只是返回一串中文,而非jsp、vm等页面
        @Get
        public String xxx(Invocation inv) {
            return "@今天天气真好,花儿都开料!";
        }
    }

TodoController.java

    package com.xiaonei.xxx.controllers.windows;
 
    import net.paoding.rose.web.Invocation;
    import net.paoding.rose.web.annotation.rest.Get;
 
    @Path("todo")
    public class TodoController {

        // 在控制器使用全局变量并不好,在此仅是一个演示而已
        private int count;
 
        // 方法名是什么不要紧,关进是@Get代表了这个方法用于处理对/todo的GET请求
        @Get
        public String xxx(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下找名字以todo开始的页面
            return "todo";
        }
    }

portal页面

webapp/views下创建PortalController需要的portal-home.vm (没限制只能是vm,亦可使用jsp)

<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">$weather</div>
	</div>
 
 
	<div class="window">
	<div class="title">待做</div>
        <!--$todo实际是一个Window对象,velocity会调用其toString()输出html的-->
	<div class="content">$todo</div>
	</div>
 
	</body>
</html>

window页面

webapp/views/windows创建TodoController需要的页面 todo.vm

	<ul>
	#foreach($item in $todolist)
	<li>$item</li>
	#end
	</ul>

css文件

在webapp/static下 portal.css

	.window {
	  width: 300px;
	  height: 200px;
	  border: solid black 1px;
	  margin-left: 15px;
	  float: left;
	  background-color: white;
	}
	.window .title {
	  background-color: black;
	  color:white;
	  margin: 2px;
	  padding-top: 2px;
	  padding-left: 2px;
	  height: 26px;
	}
	.window .content {
	  height: 100%
	  padding-top: 2px;
	  padding: 2px 2px 0px 2px;
	}

并发数配置

在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对象,不会“乱串”

启动服务器

运行该webapp,访问http://localhost/portal 显示如下

接下来

如果您对上面的演示已经掌握,想看看具体的实现,请看: 《rose portal原理

Comment by xubing...@gmail.com, Jun 11, 2010

ghjghj

Comment by ilsanboo@gmail.com, Jun 12, 2010

先弄下来体验体验:)

Comment by ilsanboo@gmail.com, Jun 13, 2010

这个跟我们的widget有点像

Comment by project member qieqie.wang, Jul 9, 2010

to ilsanboo:能介绍下widget的功能以及实现?

Comment by zhangdong147896325@gmail.com, Jul 14, 2010

如果在tomcat 6以后会出现net.paoding.rose.web.portal.impl.PrivateRequestWrapper? cannot be cast to javax.servlet.ServletRequestWrapper?错误。 好像是tomcat自带的servlet-api包的原因。但是在resin下就可以正常运行。怎样才能让它在tomcat下运行呢?

Comment by project member qieqie.wang, Jul 15, 2010

经确认zhangdong同学使用的是tomcat 6.0.14的版本,这个版本有bug,使用6.0.15或以上的版本即可(已通过阅读代码确定),已通过测试

Comment by zhangdong147896325@gmail.com, Jul 15, 2010

非常感谢,是这个原因。

Comment by 4myhappy...@gmail.com, Jul 23, 2010

恩。我用的tomcat 6.0.20一切正常。

Comment by kezo...@gmail.com, Aug 14, 2010

其实也就是使用widget框架的原理,每个小格各个独立,这个我已经见过好多个版本了,不过不是java的。总之支持下,国内的公司难得有对开源社区做贡献的。

Comment by project member wangchan...@gmail.com, Aug 15, 2010

使用jetty启动的时候报错了

Comment by project member qieqie.wang, Aug 16, 2010

to wangchangbing:

可以在issure列表中报告一下异常,以及环境

Comment by hxhj...@126.com, Apr 26, 2011

你好我在resin4.0.17报了java.lang.AbstractMethodError? 希望能够解释一下

Comment by zhuyoul...@gmail.com, Jul 7, 2011

干嘛不传个具体的例子上去呢,不完整,折腾人不是吗,非得一个一个贴,自己也累

Comment by hxhj...@126.com, Jul 12, 2011

什么时候能支持一下,resin4.0以上的版本呢

Comment by youngorchen@gmail.com, Sep 2, 2011

import net.paoding.rose.web.annotation.ReqMapping?;

@Path("portal")

这2个会报错 是啥原因 谁这个demo跑起来了?有完整的包吗?

Comment by sunmuyu...@163.com, Sep 18, 2011

你好 使用tomcattomcat-7.0.21 会出现如下错误 2011-09-19 10:43:25,475 ERROR [net.paoding.rose.web.portal.impl.WindowTask?] portalExecutor-1 net.paoding.rose.web.portal.impl.WindowTask?.run(WindowTask?.java:64) - <> javax.servlet.ServletException?: Filter execution threw an exception

at org.apache.catalina.core.ApplicationFilterChain?.internalDoFilter(ApplicationFilterChain?.java:268) at org.apache.catalina.core.ApplicationFilterChain?.doFilter(ApplicationFilterChain?.java:210) at org.apache.catalina.core.ApplicationDispatcher?.invoke(ApplicationDispatcher?.java:684) at org.apache.catalina.core.ApplicationDispatcher?.processRequest(ApplicationDispatcher?.java:471) at org.apache.catalina.core.ApplicationDispatcher?.doForward(ApplicationDispatcher?.java:402) at org.apache.catalina.core.ApplicationDispatcher?.forward(ApplicationDispatcher?.java:329) at net.paoding.rose.web.portal.impl.WindowTask?.run(WindowTask?.java:59) at java.util.concurrent.Executors$RunnableAdapter?.call(Executors.java:441) at java.util.concurrent.FutureTask?$Sync.innerRun(FutureTask?.java:303) at java.util.concurrent.FutureTask?.run(FutureTask?.java:138) at java.util.concurrent.ThreadPoolExecutor?$Worker.runTask(ThreadPoolExecutor?.java:886) at java.util.concurrent.ThreadPoolExecutor?$Worker.run(ThreadPoolExecutor?.java:908) at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.AbstractMethodError?
at javax.servlet.ServletRequestWrapper?.isAsyncSupported(ServletRequestWrapper?.java:401) at javax.servlet.ServletRequestWrapper?.isAsyncSupported(ServletRequestWrapper?.java:401) at org.apache.catalina.core.ApplicationFilterChain?.internalDoFilter(ApplicationFilterChain?.java:227) ... 12 mor

Comment by shangsha...@gmail.com, Feb 21, 2012

切分成多个portal时,如果某个controller要进行redirect怎么办?


Sign in to add a comment
Powered by Google Project Hosting