论坛首页 Java企业应用论坛

(开源)DWZ+EWeb4j打造门户系统

浏览 22292 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2011-08-17   最后修改:2011-08-18
EWeb4J是一个基于Java平台的框架。它是开源的且是商业友好的(Licensed under the Apache License, Version 2.0)。它更喜欢J2EE的应用开发。

截止到2011年8月17日晚上20点,EWeb4j已经更新至1.b.6.x版本了,这是一个里程碑版本,值得庆贺。目前提供了下载,包括源代码,jar包,javadoc 另外,一个值得高兴的消息是,我使用DWZ最新版本作为后台界面,eweb4j1.b.6.4版本开发了一个简单的门户系统雏形,目前整个系统已经搭建起来了,但功能只实现了部分,包括用户登陆,注册,查看,登陆验证,菜单管理(DWZ后台界面的菜单自定义)。现在先发上来,包括源代码都有,大家可以参考来学习EWeb4j。有任何问题可以联系:

QQ:493781187 EMAIL:l.weiwei@163.com 网站留言:http://lurencun.com/guestbook

谢谢。

EWeb4j更新日志:
v1.a.432 
2011-05-09 2:05
修复:mvc action模块的从页面request中自动设值到action属性中不支持数组的bug
改善:orm 模块的对sql查询回来的结果集缓存的内存结构。新的结构为:一个PO持久化类—>一个SqlResultCache缓存池,其中SqlResultCache缓存池的结构为:一条sql语句—>多个对象ID,一个对象ID—>一个查询出来的对象,这些查询出来的对象被放在一个全局的缓存池中。
改善:orm sql模块中的插入、删除、更新sql语句创建类,编写了它们的JUnit测试类
v1.a.433
2011-05-11 22:55
撤掉ORM的缓存机制,原因是需要维护全局缓存资源导致需同步多线程产生了额外时间开销。得不偿失。去掉缓存后发现性能更高。
改善ORM模块,灵活支持多数据库。

v1.b.3
2011-07-15
支持REST
1.b.3 2011-7.16
MVC添加了注解配置的支持、支持REST风格url配置
1.b.4 2011-7-26
ORM添加了注解配置的支持、添加了表关系配置@Many,@One,@ManyMany、添加了级联操作CascadeDAO
1.b.4.2 
修复了因调用了Tomcat7的reqeust.getServletContext()而导致7之前的版本无法启动框架的bug
1.b.4.3
改善了验证器捕获错误方式,本来是一旦发现错误,马上报告给用户,现在是发现所有能够发现的错误,再来报告给用户。另外,将用户输入过的值返回给页面。第三,废除了Validator的showErrorType属性,改而换到Action配置属性里。注解方式下,@ValErrShow(value={""}),value是一个数组类型,对应着第几个action
1.b.4.4
废除了@ReqeustMapping中的数组类型value,转为String类型,因此@Validator和@Result也没有了index属性。
1.b.4.5 2011-7-30
修复:action执行方法的bug
1.将Validator里的Param属性转到Field属性下,同时,@ValParam改名@FieldParam并index属性转到了@ValField下
2.支持action方法返回值里嵌套"redirect:xxx"客户端跳转,或者"forward:xxx"(当没有@Result注解时,"xxx"也表达此意)服务端跳转
3.去掉@RequestMethod注解,改为@RequestMapping增加一个属性method,去掉@ValErrShow,改为MVC中的
@RequestMapping增加一个属性showValErr,且以下注解增加了某些属性的默认值。
@RequestMapping:method默认"GET",showValErr默认"alert"
@FieldParam:index默认0,且改成int[]类型
@ValField:index默认0,且改成int[]类型
@Validator:clazz默认""

ORM中的
@Table:value默认""
@Column:value默认""

1.b.4.6
修复action方法声明HttpSession参数时发生初始化错误的bug。

1.b.4.7 7-23
MVC添加了对多个包扫描的配置,即:
<scanActionPackage>
	<path></path>
	<path></path>
	...
</scanActionPackage>
同理ORM的也是
<scanPojoPackage>
	<path></path>
	<path></path>
	...
</scanPojoPackage>

为MVC的@Param添加了初始化属性init,默认值为""

1.b.4.8 8-1
添加@RequestMapping("GET|POST|PUT|DELETE"),支持“|”来表示映射到多个http方法中
分页组件:添加了首页,末页,下一页,上一页的文字配置。默认是中文的。

1.b.4.9
发现当pojo的自增长主键名字不是id时,BaseDAOImpl将其名字写死为“id”了,因此会报错,修复此bug
为@One添加了级联更新的操作。

1.b.5.0
发现@One注解下的级联查询有一个bug,在获取当前对象的idField上出错了,错在获取的是target类的idField,当前版本修复了这个bug。
将CascadeDAO的所有对外接口方法的末尾String[]参数类型修改成String...的动态数组类型。

1.b.5.1
将CascadeDAO的update(T... t)方法修改为update(T[] t)

1.b.5.2
CascadeDAO的insert方法实现增加一种判断,当@One对象的id值不为0且不为null的时候,会先去查询数据库是否含有该记录,接着如果没有或者为0或者为null,会采用先插入@One对象,获取其ID值,然后插入到当前对象中去完成关联。

1.b.6.0
重构了整个Jdbc包,添加了事务模板的支持。数据源支持方式更加灵活,重构了CascadeDAO,所有的DAO、JdbcUtil操作都支持事务模板。总之,这个版本做的工作非常多,也非常值得庆贺。这个版本应该是目前功能最完善,最给力的了。

1.b.6版本是一个里程碑
下面罗列当前版本已经拥有的主要功能:
IOC:简单POJO的注入
MVC:支持REST,支持Struts2(Xml)、SpringMVC3(Annotation)两种风格的配置。支持拦截器、验证器、JSP模板。
ORM:支持事务模板。自定义SQL。默认DAO实现。支持级联操作。支持ORM映射。支持多数据源同时存在。
其他:配置文件几乎无需开发者手写,框架自动编写,开发者只需填写参数即可。即使填错了也没有关系,框架支持自动修复,保留备份。日志完备。上述三大模块可开启或关闭。自由选择。整个框架几乎无任何侵入,对开发者代码无任何污染。框架当前版本已较成熟。可以使用来开发应用了。

1.b.6.1
UpdateDAO的 
int[] update(T... ts)方法修改为
int[] batchUpdate(T... ts)
并且添加了一个
int update(T t)方法

1.b.6.2 
当使用跳转页面形式来显示验证错误消息时,支持重定向和服务端跳转两种,当使用重定向时,错误消息保存在session中,当使用服务端跳转时,错误消息保存在request中。前者能够有效防止刷新重复提交的问题。
重定向:showValErr="redirect:xxx.jsp"
服务端跳转:showValErr="forward:xxx.jsp"或者"xxx.jsp"

1.b.6.4 8-17
DAOFactory.getSelectDAO().selectWhere(Class<T> clazz, String condition) 改为
DAOFactory.getSelectDAO().selectWhere(String<T> clazz, String condition,Object... args);
即支持sql占位符?。
DAOFactory.getDivPageDAO().divPageByWhere(Class<T> clazz,int p, int n,String condition)改为
DAOFactory.getDivPageDAO().divPageByWhere(Class<T> clazz,int p, int n,String condition,Object... args);即支持sql占位符?;同时修复了这个方法的一个bug(当传入p和n为负数的时候报错,修复为不分页)。



截图:
这是Simportal项目截图,名字含义:简单实用的门户系统


这是登陆界面,请忽略我们很年轻很脆弱的CF团队。


这是后台登陆成功之后的界面,采用DWZ,这是一个list列表。


这是菜单管理里的导航菜单管理,添加导航菜单


这是添加树形菜单,使用了DWZ的查找带回和suggest列表


系统还实现了注册,登陆验证拦截器等功能,但是残缺不全,目前整个系统基本架构已经搭建起来了。这次发出来主要是先作为EWeb4j框架的一个Demo,当然,它一定会慢慢被完成的。它也将会作为一个开源项目。我们的所有开源项目都将采用Apache2.0协议,商业友好。当然,现在发的这些还不能算是真正开源,因为没有协议文件,代码也写得一般,但是我们希望慢慢来,我们有耐心慢慢去完善,做我们喜欢做的事。

下载地址都在这里:
http://code.google.com/p/eweb4j/downloads/list

更新:
注册页面的验证码,src的后缀名请改为.jsp就正常了.
注册功能有bug,请将UserService的create方法改个名字,然后同时在UserController里改下,就可以了,主要是使用了泛型动态数组参数,Jvm在运行期无法正确找到该方法,造成自我递归调用了。



  • 大小: 60.6 KB
  • 大小: 71.9 KB
  • 大小: 130.3 KB
  • 大小: 72.9 KB
  • 大小: 90.1 KB
   发表时间:2011-08-18  
这次发出来的Simportal系统完全支持二次开发,DWZ本身已经搭建好,可以说这也算是一个dwz4j吧。菜单管理都是可以定制出属于自己的菜单的。而对于程序代码,由于采用合理的分层,如果不想使用eweb4j,也可以很容易的换成spring,struts和hibernate等框架来替代。不过对于这样一个简单的web应用来说我个人觉得不需要,当然nutz也是一个不错的选择哦。
0 请登录后投票
   发表时间:2011-08-18   最后修改:2011-08-18
对于DWZ我扩展了下它的suggest,让其支持级联。详细内容且看下面的代码:

在dwz.database.js中的$.extend中定义这样一个function:
cascadeSuggestAndBringBack: function($input,json){
			//在这里可以截获当前点击选择的某个节点,然后做级联显示的功能 by CFuture.weiwei
			//初始化当前菜单
			//将级联菜单url替换掉
			var cascadeSuggest = $input.attr("cascadeSuggestId");
			
			if (cascadeSuggest){
				var suggestUrlFormat = $("#"+cascadeSuggest).attr('suggestUrlFormat');
				var suggestUrl = $("#"+cascadeSuggest).attr('suggestUrl');
				var suggestUrlFormatParams = $input.attr('cascadeSuggestUrlFormatParam').split(",");
				for (i=0;i<suggestUrlFormatParams.length;i++){
					suggestUrl = suggestUrlFormat.replace("$s"+(i+1),json[suggestUrlFormatParams[i]]);
				}
				$("#"+cascadeSuggest).attr('suggestUrl',suggestUrl);
				$("#"+cascadeSuggest).attr("value","请选择");
				//清空给定的dom
				var clearId = $input.attr("clearId");
				if (clearId){
					var clearIds = clearId.split(",");
					for (j=0;j<clearIds.length;j++){
						$("#"+clearIds[j]).attr("value","");
					}
				}
				
				//级联“查找带回”的URL变换
				var cascadeLookup = $input.attr("cascadeLookupId");
				if (cascadeLookup){
					var lookupUrlFormat = $("#"+cascadeLookup).attr('lookupUrlFormat');
					var lookupUrl = $("#"+cascadeLookup).attr('href');
					var lookupUrlFormatParams = $input.attr('cascadeLookupUrlFormatParam').split(",");
					for (i=0;i<lookupUrlFormatParams.length;i++){
						lookupUrl = lookupUrlFormat.replace("$s"+(i+1),json[lookupUrlFormatParams[i]]);
					}
					$("#"+cascadeLookup).attr('href',lookupUrl);
				}
				
				//关闭当前打开的对话框面板
				$.pdialog.closeCurrent();
			}
			
		}


然后在其bringBackSuggest方法中调用它:
bringBackSuggest: function(args){
			var $box = navTab.getCurrentPanel();
			$box.find(":input").each(function(){
				var $input = $(this), inputName = $input.attr("name");
				for (var key in args) {
					var name = ("id" == key) ? _util.lookupPk(key) : _util.lookupField(key);
					if (name == inputName) {
						$input.val(args[key]);

						$.cascadeSuggestAndBringBack($input,args);//add by cfuture.weiwei

						break;
					}
				}
				
			});
		},


最后在页面上的input添加这些属性:
<dl class="nowrap">
                	<dt>所属导航菜单:</dt>
					<dd>
						<input class="required"  type="hidden" name="navMenus.dwz_navMenu2.navMenuId" value="" />
						<input class="required" 
						name="navMenus.dwz_navMenu2.name" type="text" 
						value="请选择"
						suggestFields="navMenuId,name" 
						suggestUrl="navMenus/suggest.json"

						clearId = "pid2" 
						cascadeSuggestId="parentSuggestInput2"
						cascadeSuggestUrlFormatParam="navMenuId"
						cascadeLookupId="parentLookupA2"
						cascadeLookupUrlFormatParam="navMenuId"

						lookupGroup="navMenus" lookupName="navMenu2"/>
						<a class="btnLook" href="navMenus/lookupSearch" 
						lookupGroup="navMenus" lookupName="navMenu2">查找带回</a>
					</dd>
				</dl>
				<dl class="nowrap">
					<dt>父菜单:</dt>
					<dd>
						<input class="required"  id = "pid2" type="hidden" name="${model}.dwz_treeMenu2.treeMenuId" value="0" />
						<input class="required" 

						id = "parentSuggestInput2"
						suggestUrlFormat = "${model}/$s1/suggest.json"

						name="${model}.dwz_treeMenu2.name" type="text" 
						value="请选择"
						suggestFields="navMenuId,pid,treeMenuId,name" 
						suggestUrl="#" 
						lookupGroup="${model}" lookupName="treeMenu2"/>
						<a id="parentLookupA2" lookupUrlFormat = "${model}/$s1/lookupSearch" class="btnLook" 
						href="#" lookupGroup="${model}" lookupName="treeMenu2">查找带回</a>
					</dd>
				</dl>



这样就能产生级联的效果了。详情请运行demo
  • 大小: 159.8 KB
0 请登录后投票
   发表时间:2011-08-18  
DWZ?和DWR有啥联系没?
用了extjs后,dwr都慢慢淡出视线了
0 请登录后投票
   发表时间:2011-08-18  
KimHo 写道
DWZ?和DWR有啥联系没?
用了extjs后,dwr都慢慢淡出视线了

没有。
dwz是一个已经搭建好的基于AJAX的富客户端。注意是已经搭建好的。不是让你自己去组件组合。是直接能用的。二次开发就行了。
0 请登录后投票
   发表时间:2011-08-18  
我想知道,你为什么要开发 eweb4j?有什么特点优点?
0 请登录后投票
   发表时间:2011-08-18  
非常不错,介绍一下eweb4j的优点吗?
0 请登录后投票
   发表时间:2011-08-18  
lqixv 写道
我想知道,你为什么要开发 eweb4j?有什么特点优点?


同时也回答下另外一位朋友的疑问。
1.为什么要开发eweb4j?
    首先我会说,这是我的兴趣爱好,我早起在学习j2ee体系的时候,还没有使用过SSH,在使用jdbc进行小型项目开发的时候,发现很多重复无聊的代码,经常性要复制粘贴,于是慢慢的进行封装,最后渐渐形成自己的类库。最后形成了一个框架,它的名字叫做EasyDAO,可以在谷歌搜索下。
    后来开始使用SSH,发现在使用的过程当中,感受到Struts以一个action为一个类的这种设计,貌似不怎么适合我的风格,action一多起来,很不方便。而且配置xml也很郁闷,于是想自己扩展下EasyDAO,让它拥有自己的MVC。慢慢的发现自己设计的MVC看起来有点像SpringMVC的感觉(扫描包),同时也发现了SpringSide,Play!等框架貌似都在做这些事情。国内还有Nutz也是。那时候突然觉得自己是不是应该停止了,因为我在做大家都在做的事。
    后来比较了下自己的框架和其他框架的不同。且列如下,还望诸君别见笑。
  • eweb4j的配置非常简单,而且是自修复的,开发者无需去弄懂配置文件的结构,只需要配置一个路径,然后框架在运行期会自动生成配置文件,最后开发者填写好相应参数就行了,如果你有意或无意破坏了配置结构,没关系,框架会自动修复,并且会把你之前的配置备份一份。
  • eweb4j的日志完备,我们都知道系统运行期的日志非常重要,尤其是页面访问日志和数据库访问的日志。这些框架都做好了。
  • eweb4j主要由几大模块组成的。这些模块相互之间基本独立,开发者可以自由选择是否开启它们。例如你只想用MVC模块,那么请关闭IOC和ORM模块,然后选择你喜欢的IOC和ORM,例如Guice和Hibernate。
  • eweb4j天生支持DWZ,内置DWZ组件。框架扩展性由组件来保证,目前含有分页组件和DWZ组件。
  • 最主要的是,EWeb4j让JAVA WEB开发非常简单,从页面到Controller的交互,到DAO与数据库的交互,框架都提供了非常成熟稳定的支持。单从MVC来看,既提供XML方式的配置,也提供注解方式的配置。还支持REST,拦截器,验证器等。ORM支持事务模板,非常简答的写法。真的非常简单。对象之间的关系映射和统一的级联操作接口也非常简单。相信使用过的人都会感受到的。框架推行0污染。不让你继承任何一个类,就能完成一个Web应用需要完成的事。我相信,选择EWeb4j来开发web应用比选择SSH要简单的多。谢谢

0 请登录后投票
   发表时间:2011-08-18  
lqixv 写道
我想知道,你为什么要开发 eweb4j?有什么特点优点?

请看第八楼
0 请登录后投票
   发表时间:2011-08-18  
所以,EWeb4j最核心的应该是让开发更简单!代码0污染。不继承任何一个类,不限制任何一句代码的规范。而模块也是自由选择使用,不强制一定加载所有模块,你可以开启或关闭它们。模块包括MVC、IOC、ORM
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics