GWT1.6+Spring3.0+RESTlet+Maven2+openCRX/MDX

本学习笔记转载自:http://opencrx.spaces.live.com/default.aspx

GWT1.6+Spring3.0+RESTlet+Jsonlib+Maven2+openCRX/MDX(一)
身为技术人员竟然一直没有发过技术类博客,有点汗颜,趁着新鲜出炉的最新技术所搭建的最新框架,给大家分享一下。
Spring3.0之前大家集成GWT基本上都是用 GWT- Widget/Server Library ,现在最新的Spring发布包提供了REST支持,使用这种方式更自然。其实这是一个老外的博客上提出来的:http://bigohno.blogspot.com/2009/04/gwt-spring-mvc-and-rest-on-google-app.html

只是这位同志哥只提出了一个概念和其中使用到的一些技术,但是没有细节和代码,我几乎花了近两周的时间才把一个完整的业务流程顺利跑通。当然这也是由于我是第一次使用Gwt1.6,Spring MVC,REST,JSONlib,Restlet,Maven。

也许你们注意到了,除了后台的openCRX/MDX是我研究多年的技术,其他技术除了spring,几乎都是完全没有接触过。然而,也因为这样,当我完成了整个框架基本功能的调试运行之后,得出的结论是:其他技术可以不用,Maven2一定要用,Gwt可以不用,SpringMVC/REST一定要用。

当然了,很多只使用过Ant的同志,对于Maven可能觉得可有可无,够用就好。但是,Maven绝不仅仅是构建,而是帮你管理了整个项目的外部资源、内部构建和单元测试的自动化过程。可以这样说,一旦用过Maven,你就再也不愿意去做没有Maven的项目。

SpringMVC是一个较早出现的技术,以前大家习惯使用Struts1或者2作为MVC的实现框架,Spring技术与之相比并没有太大的优势,所以很多人没有用过SpringMVC包括很多老革命在内。在最新的Spring3.0M2中已经加入了REST,这使得我第一次体验到了Annotation和ViewResolver的强大,当然最关键的起因在于REST本身就是一个非常吸引人的技术框架。而Rest的出现,个人认为是来自于对Ajax框架最好的支持。
前面是宣传一下新技术,下面先给大伙儿上张系统架构图:


对于使用其他后台程序的项目,可以简单的用自己的Service替换openCRX API。说到这里,如果使用Maven进行以来管理和打包,那么会有一个很直接的好处,就是GWT的几个包,不需要手工编写脚本来区分开发时使用和部署时使用,而是简单的配置一下scope属性就可以了。另外需要更新spring最新版本的jar包时,也不需要手工去下载更新,只是简单的修改一下版本号就可以了。
特别要说的是:当使用SpringAOP特性的时候,需要一个cglib2的包,当我自己从网上搜索时下载的包死活无法正常运行,而我简单的加入了SpringAOP自己的pom中所使用的依赖之后,就很顺利的启动了。这让我不禁畅想,如果所有的项目都使用maven发布自己的库,那是多美妙的事情呀。
很遗憾,opencrx/mdx就没有一个自己的maven repository——还好我在网上偶然发现一篇博客介绍一款maven repository代理软件,这下可好了,对于一个项目组的成员或者整个公司来说,都可以搭建这样一个本地库,就可以“一次导入,到处更新”了,哈哈。。。
到这里,相信大家对于这个“最新技术”所组成的“最新框架”应该有一个大致的印象了,下次介绍如何建立一个基于maven 的GWT1.6+Spring3.0的Eclipse工程。

GWT1.6+Spring3.0+RESTlet+Jsonlib+Maven2+openCRX/MDX(二)
前面一篇相当于整个架构的一个概述,这次就是关于如何 使用Maven2快速搭建一个支持GWT1.6和Spring3.0的Eclipse工程,这可以帮助我们用最快的速度开始真正的开发。

1.这里,Maven for Google Appengine Java,是一篇介绍如何基于Maven搭建基于google appengine的工程,我们可以利用它先建好一个gwt的工程,照着图文教程一步步做,之后就会得到一个标准的maven工程。

2.执行mvn eclipse:eclipse,这样可以生成eclipse所需要的工程文件和classpath.这里要注意:如果你不需要支持google appengine那么就需要修改pom.xml文件中,把有关appengine的三个dependency注释掉,并且工程目录下的build.xml也是可以删除的

3.仍然是修改pom.xml文件,加入对于spring3.0的依赖。这里要注意两点:一、前面提到的那篇博客里面所说的加入一个dependency来加入spring3.0的支持,似乎已经过时了,结果是一个包都加不进来。我在网上搜索过很多有关spring3.0 maven的文章,最后只有一个spring官方论坛中的帖子是有效的,但是连接已经找不到了,我就直接贴出这一段dependency了:
<dependency>
            <groupId>asm</groupId>
            <artifactId>asm-commons</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.transaction</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.web.servlet</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>org.springframework.js</artifactId>
            <version>${webflow.version}</version>
        </dependency>
<dependency>
            <groupId>net.sourceforge.cglib</groupId>
            <artifactId>com.springsource.net.sf.cglib</artifactId>
            <version>2.1.3</version>
        </dependency>
注意:asm和cglib都是spring的依赖包,但有于是可选,所以不能在默认情况下加进工程库中。本来也可以修改相应的spring dependency条目,但是我在公司机器上没有maven pom编辑器,就偷一下懒,直接引用了。大家记得,有条件一定要装一个maven eclipse的插件,特别是pom编辑器的插件,能够极大提高生产力。

4.加入restlet和jsonlib的dependency条目,这两个都可以在网上找到,但是要注意一点:因为他们会依赖spring2.5.6的包,这会和我们现在的spring3.0冲突,所以需要加入一个exclusion条目

5.加入opencrx/mdx依赖,但是实际上opencrx/mdx开发小组沉迷于cvs/ant之中,给我的答复是:现状很好,无须改变。没办法只好自食其力了.
首先,自行定义opencrx/mdx的groupId,artifactId,下面可以参考:
<dependency>
            <groupId>opencrx</groupId>
            <artifactId>opencrx-application</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>opencrx</groupId>
            <artifactId>opencrx-base</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>opencrx</groupId>
            <artifactId>opencrx-extension</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>opencrx</groupId>
            <artifactId>opencrx-kernel</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>opencrx</groupId>
            <artifactId>opencrx-mail</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>opencrx</groupId>
            <artifactId>opencrx-security</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.core</groupId>
            <artifactId>openmdx-application</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.core</groupId>
            <artifactId>openmdx-base</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.core</groupId>
            <artifactId>openmdx-base-ext</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.core</groupId>
            <artifactId>openmdx-system</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.core</groupId>
            <artifactId>tomcat-juli</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.portal</groupId>
            <artifactId>openmdx-portal</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.security</groupId>
            <artifactId>openmdx-ldap</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.security</groupId>
            <artifactId>openmdx-radius</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>openmdx.security</groupId>
            <artifactId>openmdx-security</artifactId>
            <version>2.4.1</version>
            <scope>provided</scope>
        </dependency>
其次,手工安装相应的jar包到maven repository。这里有一个可选项,就是在本地网上安装maven repository代理服务器,那么可以统一安装在这台服务器上,所有开发人员可以从这里统一更新所有的开发用jar包。

6.以上整个过程中,如果你是在eclipse环境中,并且安装了maven-elcipse插件,那么每次修改了pom.xml文件,都会自动进行maven upate,这样会验证其中所有的依赖包的有效性。如果没有问题,那么可以执行:mvn install,把整个工程构建并打包到本地maven repository之中。因为本人对于Maven研究还不深入,所以把部署的任务也放到了install之中执行。理论上说,可以增加maven build的run命令在eclipse里面,这样可以更方便。大家如果有知道这个方法的,请告知。

最后总结一下:如果你对maven有更深的了解,就会发现更多的惊喜。同样限于时间,我还没有加入编译gwt的任务到pom中,简单尝试下,可以进行编译但是不能生成静态页面到我指定的目录,等有时间再加上这个吧,这样就可以整合gwt compile和deploy into tomcat的任务了。另外,顺便对比一下maven和ant的build,在maven下一旦包安装好整个过程不超过10s.但是如果没有注释掉appengine就会耗费2分钟以上,我也没去研究这到底是什么原因,大家可以自己研究看看,相信其中可以发现更多的功能和收获更多的开发乐趣。

预告:下次我会从springmvc的设置开始讨论整个框架的运行流程


GWT1.6+Spring3.0+RESTlet+Jsonlib+Maven2+openCRX/MDX(三)
前面一篇主要是关于Maven在整个工程中的使用介绍,以后还会根据情况,介绍一些Tips。

本系列博客中的第一篇中,有一张整个架构的示意图,其中联系前台和后台的是http/Rest标准协议。现在我们就先从前台所使用的技术GWT和Restlet开始。



1.GWT作为一种基于java开发Ajax页面的技术框架,真正的发展是开始于1.5版本(支持了大部分java5的特性和库),到了1.6又再一次进行了大的修订。目前来说,它的最大优势就是支持大量开源的控件,包括gwt-ext,smartgwt等等,和另外一个要强调的,所见即所得的编辑器GWT Designer(目前似乎已经被更名为window builder),有了这两点,对于java/j2ee开发人员来说几乎是接近了C/S时代RAD的开发效率了。可惜的是,对于一个完整的web应用来说web ui仅仅是前台的一部分,在webservice/rest协议出现前,前端展现和后台程序耦合性达到了令人发指的地步。GWT也因此没有更大范围的流行起来,特别是国内,几乎看不到使用gwt成功的案例。难以设计/改变风格,不熟悉/适应这种开发方式,都是让人难以接近的原因。


2.Restlet本身是一个完整的Rest实现框架,包括了前端、后台以及和其他技术的集成模块,我们在这里仅仅使用了和GWT集成的Restlet-GWT模块,大家有兴趣也可以去restlet官方网站查看其它解决方案。不得不说,restlet在对于REST支持的领域上已经远远领先,特别是和GWT的集成上,几乎为开发人员周到的考虑到了方方面面的需求,简化了GWT远程调用的繁琐(2个接口类、一个实现类再加上servlet的申明),对于get/post/put/delete来说,都仅仅几行代码就可以实现,下面是一个get方法的例子:
            public void onClick(Widget sender) {
                // Add an AJAX call to the server
                final Client client = new Client(Protocol.HTTP);
                client.get("http://localhost:8888/ping", new Callback() {
                    @Override
                    public void onEvent(Request request, Response response) {
                        button.setText(response.getEntity().getText());
                    }
                });
                dialogBox.hide();
            }


3.对于页面流程、验证/异常处理以及权限控制,在GWT框架下,都是一种新的挑战,但是也可以借鉴C/S的开发经验。
基于角色和页面的编号,可以处理功能权限,基于角色的参数管理,可以控制相应的数据权限,基于opencrx可以提供SaaS的数据分区控制。验证和异常处理依然可以分成前后台,分别处理。基于GWT,已经简化了web flow的处理,但是也同时绑定了业务处理的部分流程,只有通过尽可能多的重用页面组件来提供工作流程的灵活性。


预告:下次介绍Server端,Spring3.0 MVC/REST的实现,以及opencrx/mdx API的调用

 

你可能感兴趣的:(eclipse,spring,maven,REST,gwt)