SpringSide_3开发Web项目的全过程.doc_第1页
SpringSide_3开发Web项目的全过程.doc_第2页
SpringSide_3开发Web项目的全过程.doc_第3页
SpringSide_3开发Web项目的全过程.doc_第4页
SpringSide_3开发Web项目的全过程.doc_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用SpringSide 开发Web项目的全过程(上) 2009年09月24日 来源:BlogJava 作者:海边沫沫 收藏本文 SpringSide 是目前SpringSide的最新版本,也是完成度比较高的一个版本,用来做实际项目的开发应该丝毫不成问题。这里写一下使用该版本开发一个简单Web项目的全过程,当然,最重要的是我自己的一些心得体会。我的文章很长,只有耐下性子细看,才能体会个中三味。第一步、下载SpringSide all-in-one版。这个过程太简单了,SpringSide的官方网站是,去那里就可以下载了,all-in-one版当然是懒人们的不二选择。这里有一点很搞笑,该版本标的是SpringSide ,但是下载后解压缩,解压缩出来的文件是springside-,这可能是江南白衣的一点小小的失误,据我猜测,较的进步应该是加入了jsp-api.jar这一个库,希望白衣这次不要为了更改这个版本号上的失误而再推出一个新版本,如果真要推出新版本,怎么样也应该把我最近研究出来的多数据库的配置加进去。第二步、安装SpringSide。如果安装过SpringSide以前的版本,最好把用户目录下的.m2文件夹删掉,这个文件夹是Maven的本地仓库所在地,虽说Maven可以有效保证库文件不会发生版本冲突,但是删除这个文件夹会使安装过程加快,否则,SpringSide的安装过程会不停询问你是否覆盖某某文件。删除.m2文件夹后,运行springside-目录下的bin目录中的quickstart.bat即可(前提条件是已经安装好了JDK5或以上版本,如果你的电脑中连JDK都没有,就别来趟SpringSide的浑水了)。 等待这个文件运行完,就可以看到SpringSide 3提供的三个示例项目mini-web、mini-service、showcase都运行起来了,这时你可以细细体会一下SpringSide实现的各种特性。仔细察看SpringSide的bin目录,发现该版本提供的脚本更加明确和有用,如start-db.bat可以用来启动Derby数据库,start-selenium.bat用来启动selenium server,而start-tomcat.bat那就别说了,地球人都知道。如果要想使用SpringSide来生成项目,还有一点点小工作要做,就是把Maven的bin目录加入到PATH环境变量中,如下图:第三步,使用SpringSide生成项目。运行bin目录下的new-project.bat即可,如下图:图片看不清楚?请点击这里查看原图(大图)。在创建项目的过程中,该脚本会提出一些问题,其中groupId指的是你的组织的名称,由于该项目由我私人贡献,纯属示范用,所以我填了 youxia.personal,因此,在第5个问题上,我选择了personal.you作为我项目中的package的名字,这也是符合国际惯例的;artifactId指的是项目的名字,这里为MultiDatasourceExample,名字有点长,从名字就可以看出来我要示范多个数据源的配置。第四步、启动Eclipse,导入项目。 生成的项目位于SpringSide目录下的toolsgeneratorgenerated-project目录下,下面是Eclipse的截图:项目导入成功后,Eclispe资源管理器的截图:可以看到,该项目一经导入,立即可用,一个烦人的红叉都没有,这也正说明了该版本是SpringSide 3的一个革命性版本,从该版本开始,SpringSide 3的易用性提高了不止一个档次。Eclipse推荐使用3.4及以上版本,因为在该版本中,对Tomcat服务器的管理更加方便,只需要在项目的快捷菜单中选择Run On Server,即可自动打开Tomcat服务器并部署项目,如下图:图片看不清楚?请点击这里查看原图(大图)。这里有一点一定要注意,由于SpringSide生成的项目默认使用的是Derby数据库,所以要想成功运行项目,必须先启动Derby数据库,还记得前面提到的start-db.bat吗?运行它!然后运行该项目的bin目录下的init-db.jar,在数据库中放入该项目的初始化数据。然后就可以点Run On Server来启动项目了,让大家见识一下Eclipse的嵌入式浏览器、Tomcat服务器视图、Console视图。真的是太方便了:第五步、将数据库迁移到MySQL中。在项目中,创建数据库和初始化数据库的语句都是以SQL文件存在的,如下图:但是该语句都是针对Derby的,如果要应用于MySQL,还必须得要做一些修改才行,先修改schema.sql,如下:droptableifexistsRESOURCES_AUTHORITIES;droptableifexistsROLES_AUTHORITIES;droptableifexistsUSERS_ROLES;droptableifexistsRESOURCES;droptableifexistsAUTHORITIES;droptableifexistsUSERS;droptableifexistsROLES;createtableUSERS(IDintegerprimarykeyauto_increment,LOGIN_NAMEvarchar(20)notnullunique,PASSWORDvarchar(20),NAMEvarchar(20),EMAILvarchar(30);createuniqueindexUSERS_LOGIN_NAME_INDEXonUSERS(LOGIN_NAME);createtableROLES(IDintegerprimarykeyauto_increment,NAMEvarchar(20)notnullunique);createtableUSERS_ROLES(USER_IDintegernotnull,ROLE_IDintegernotnull,FOREIGNKEY(ROLE_ID)referencesROLES(ID),FOREIGNKEY(USER_ID)referencesUSERS(ID);CREATETABLEAUTHORITIES(IDintegerprimarykeyauto_increment,NAMEvarchar(20)notnull,DISPLAY_NAMEvarchar(20)notnull);createtableROLES_AUTHORITIES(ROLE_IDintegernotnull,AUTHORITY_IDintegernotnull,FOREIGNKEY(ROLE_ID)referencesROLES(ID),FOREIGNKEY(AUTHORITY_ID)referencesAUTHORITIES(ID);CREATETABLERESOURCES(IDintegerprimarykeyauto_increment,RESOURCE_TYPEvarchar(20)notnull,VALUEvarchar(255)notnull,ORDER_NUMfloatnotnull);createtableRESOURCES_AUTHORITIES(AUTHORITY_IDintegernotnull,RESOURCE_IDintegernotnull,FOREIGNKEY(AUTHORITY_ID)referencesAUTHORITIES(ID),FOREIGNKEY(RESOURCE_ID)referencesRESOURCES(ID);该修改主要包含两个地方,一个是在drop table后面加上了if exists,一个是把GENERATED ALWAYS as IDENTITY修改为auto_increment。而load-data.sql不需要修改。然后,启动MySQL,在MySQL中使用上面的两个sql文件创建数据库和添加初始化数据,如下图:图片看不清楚?请点击这里查看原图(大图)。然后更改数据库连接,修改项目的perties文件,如下:#jdbcsettingsjdbc.url=jdbc:mysql:/localhost:3306/MultiDatasourceExample?useUnicode=true&characterEncoding=utf8jdbc.username=youxiajdbc.password=*#hibernatesettingshibernate.show_sql=falsehibernate.format_sql=falsehibernate.ehcache_config_file=/ehcache/ehcache-hibernate-local.xml修改项目的applicationContext.xml文件,这里要修改两个地方,一个为DriverClassName,一个为hibernate.dilect,如下:Spring公共配置文件classpath*:/pertiesclasspath*:/perties!-file:/var/myapp/perties-!-org.hibernate.dialect.MySQL5InnoDBDialect$hibernate.show_sql$hibernate.format_sqlorg.hibernate.cache.EhCacheProvider$hibernate.ehcache_config_file!-由于SpringSide不提供Mysql的jdbc驱动,所以需要自己去MySQL的官方网站下载,将下载到的mysql-connector-5.*.jar复制到项目的WEB-INF中的lib目录中。然后运行项目,成功。至此,成功将项目迁移到MySQL中。第六步、添加数据表、编写Entity类、编写Dao类、Manager类,并进行单元测试。还是以前几篇文章中提到的文章发布系统为例,每一篇文章对应多篇评论,所以说据库中需创建articles和comments两个数据表,如下:createtablearticles(idintprimarykeyauto_increment,subjectvarchar(20)notnull,contenttext);createtablecomments(idintprimarykeyauto_increment,contentvarchar(255),article_idintnotnull,foreignkey(article_id)referencesarticles(id);在编写Java代码之前,我还要做一点小工作,什么工作呢?那就是要为我自己的项目创建一个单独的源文件夹,因为srcmainjava这个文件夹已经被江南白衣放入了太多的package,而且因为涉及到security,所以层次也不明显,操作起来不方便,找起代码来也不够快。下面是我创建了自己的源文件夹后的截图:在我自己的源文件夹中,只创建了四个package,刚好代表从底到上的四个层次,这样,找起代码来要方便得多。先来Entity层,Article.java的代码如下:packagepersonal.youxia.entity;importjava.util.LinkedHashSet;importjava.util.Set;importjavax.persistence.CascadeType;importjavax.persistence.Entity;importjavax.persistence.JoinColumn;importjavax.persistence.OneToMany;importjavax.persistence.OrderBy;importjavax.persistence.Table;importorg.hibernate.annotations.Cache;importorg.hibernate.annotations.CacheConcurrencyStrategy;importorg.hibernate.annotations.Fetch;importorg.hibernate.annotations.FetchMode;Entity/表名与类名不相同时重新定义表名.Table(name=articles)/默认的缓存策略.Cache(usage=CacheConcurrencyStrategy.READ_WRITE)publicclassArticleextendsIdEntityprivateStringsubject;privateStringcontent;privateSetcomments=newLinkedHashSet();publicStringgetSubject()returnsubject;publicvoidsetSubject(Stringsubject)this.subject=subject;publicStringgetContent()returncontent;publicvoidsetContent(Stringcontent)this.content=content;OneToMany(cascade=CascadeType.ALL)JoinColumn(name=article_id)/Fecth策略定义Fetch(FetchMode.SUBSELECT)/集合按id排序.OrderBy(id)/集合中对象id的缓存.Cache(usage=CacheConcurrencyStrategy.READ_WRITE)publicSetgetComments()returncomments;publicvoidsetComments(Setcomments)ments=comments;Comment.java如下:packagepersonal.youxia.entity.entities;importjavax.persistence.Column;importjavax.persistence.Entity;importjavax.persistence.Table;importorg.hibernate.annotations.Cache;importorg.hibernate.annotations.CacheConcurrencyStrategy;importpersonal.youxia.entity.IdEntity;Entity/表名与类名不相同时重新定义表名.Table(name=comments)/默认的缓存策略.Cache(usage=CacheConcurrencyStrategy.READ_WRITE)publicclassCommentextendsIdEntityprivateStringcontent;privateLongarticleId;publicStringgetContent()returncontent;publicvoidsetContent(Stringcontent)this.content=content;Column(name=article_id)publicLonggetArticleId()returnarticleId;publicvoidsetArticleId(LongarticleId)this.articleId=articleId;编写Dao层代码,ArticleDao.java如下:packagepersonal.youxia.dao;importorg.springside.modules.orm.hibernate.HibernateDao;importpersonal.youxia.entity.Article;publicclassArticleDaoextendsHibernateDaoCommentDao.java如下:packagepersonal.youxia.dao;importorg.springside.modules.orm.hibernate.HibernateDao;importpersonal.youxia.entity.Comment;publicclassCommentDaoextendsHibernateDao可以看出,以上代码都从HibernateDao继承,得益于泛型支持,基本不需要编写一行代码。编写Bussiness层代码,这一层,白衣使用的包名为service,而类名的后缀都是Manager,我就跟他学算了,懒得改了。ArticleManager.java如下:packagepersonal.youxia.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springside.modules.orm.hibernate.HibernateDao;importpersonal.youxia.dao.ArticleDao;importpersonal.youxia.entity.Article;publicclassArticleManagerextendsEntityManagerAutowiredprivateArticleDaoarticleDao;publicvoidsetArticleDao(ArticleDaoarticleDao)this.articleDao=articleDao;OverrideprotectedHibernateDaogetEntityDao()/TODOAuto-generatedmethodstubreturnarticleDao;CommentManager.java如下:packagepersonal.youxia.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springside.modules.orm.hibernate.HibernateDao;importpersonal.youxia.dao.CommentDao;importpersonal.youxia.entity.Comment;publicclassCommentManagerextendsEntityManagerAutowiredprivateCommentDaocommentDao;publicvoidsetCommentDao(CommentDaocommentDao)mentDao=commentDao;OverrideprotectedHibernateDaogetEntityDao()/TODOAuto-generatedmethodstubreturncommentDao;以上代码大同小异,都是从EntityManager继承,并使用Spring的IoC特性,将Dao类注入到Manager类之中,并重载 getEntityDao方法来使用该注入的Dao。这个时候,为了验证这些数据访问相关的层能否正常运行,可以编写单元测试。 代码如下:packagepersonal.youxia.test;importorg.junit.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springside.modules.test.junit4.SpringTxTestCase;importpersonal.youxia.entity.entities.Article;importpersonal.youxia.entity.entities.Comment;importpersonal.youxia.service.ArticleManager;importpersonal.youxia.service.CommentManager;publicclassDataAccessTestextendsSpringTxTestCaseAutowiredprivateArticleManagerarticleManager;AutowiredprivateCommentManagercommentManager;publicvoidsetArticleManager(ArticleManagerarticleManager)this.articleManager=articleManager;TestpublicvoidaddArticle()Commentcomment=newComment();Articlearticle=newArticle();article.setSubject(test);article.setContent(test);articleManager.save(article);comment.setArticleId(article.getId();commentManager.save(comment);单元测试一运行,发现了三个问题,先是出现Manager类没有注入成功的错误,经检查发现所有的Manager类都应该使用Service注解,再出现的错误是提示Dao类没有注入成功,经检查发现所有的Dao类须使用Repository注解,最后出现的错误是找不到Entity类的错误,经检查发现Entity类不能位于personal.youxia.entity包中,必须位于其子包中,这是由applicationContext.xml文件中的配置决定的,更改包名为personal.youxia.entity.entities后,问题解决。下一步就应该是编写Action和JSP了,由于文章太长,在Blogjava的编辑器中编辑已经非常缓慢了,所以只有将该文章分为上中下三部分。且看下回分解!第七步、编写Action和JSP。在SpringSide 中,使用的是Struts 2及其Convention插件,已经不是前面使用的CodeBehind插件了,关于Convention插件,这里要再说几句,该插件的大部分功能和 CodeBehind相同,唯一让人有点迷惑的就是该插件到哪里寻找Action类的问题,它会根据 struts.convention.package.locators属性的值来决定,在该项目中,其值为“web”,之需要查阅一下 struts.xml文件即可知。这说明,Convention会寻找所有包含“web”这个单词的包,并在该包及其子包中寻找Action类。这也正是 Action层的包名为personal.youxia.web的原因。关于SpringSide 3种的Struts的探讨,大家可以看看我之前写的一篇文章SpringSide 3 中的 Struts 2ArticleAction的实现思路如下,修改index.jsp,使其重定向到article.action,该Action默认调用其list方法显示所有文章,并返回article.jsp作为其视图。在该视图上,有添加文章的连接,点击该连接则访问article!input.action,这时会调用ArticleAction的input方法,并返回article-input.jsp作为其视图,在该视图中输入文章的内容,点击保存,调用 article!save.action,这时会调用ArticleAction的save方法以保存数据,如果要删除文章,则调用 article!delete.action,这时会调用ArticleAction的delete方法。在调用以上方法的过程中,会自动调用 prepare系列的方法。因此,该步骤涉及到三个JSP文件和一个Action类,它们分别是index.jsparticle.jsparticle-input.jspArticleAction.javaindex.jsp的修改很简单,只是让项目一启动后就去访问ArticleAction,而不是默认的UserAction。index.jsp的代码如下:这时,重点进入到ArticleAction中,创建该Action,其代码的框架如下:packagepersonal.youxia.web;importpersonal.youxia.entity.entities.Article;publicclassArticleActionextendsCrudActionSupportOverridepublicStringdelete()throwsException/TODOAuto-generatedmethodstubreturnnull;OverridepublicStringlist()throwsException/TODOAuto-generatedmethodstubreturnnull;OverrideprotectedvoidprepareModel()throwsException/TODOAuto-generatedmethodstubOverridepublicStringsave()throwsException/TODOAuto-generatedmethodstubreturnnull;publicArticlegetModel()/TODOAuto-generatedmethodstubreturnnull;可以看到,该Action从CrudActionSupport类继承,而CrudActionSupport又继承自ActionSupport,并实现了ModelDriven和Preparable接口,这样Struts 2的ModelDriven拦截器和Preparable拦截器就会对我们自己的Action发生作用。CrudActionSupport中的 excute方法默认的实现是调用list方法,所以访问article.action就等于访问ArticleAction的list方法,该方法的目的是为了列出所有的文章,所以在该方法中使用了ArticleDao的分页查询,查询结果放在一个page对象中。在Struts 2中,已经没有了ActionForm的概念,可以直接把Action对象传递到视图中,为了能够在视图中访问page对象,只需要把page对象作为 ArticleAction的一个属性即可。先在ArticleAction.java中加入几行代码:AutowiredprivateArticleManagerarticleManager;publicvoidsetArticleManager(ArticleManagerarticleManager)this.articleManager=articleManager;privatePagepage=newPage(10);publicPagegetPage()returnpage;可以看到该代码的作用是为了注入ArticleManager和初始化Page对象,此时list方法的代码就非常简单,如下:OverridepublicStringlist()throwsExceptionpage=articleManager.getAll(page);returnSUCCESS;由于该方法只是简单获取一个页面的Ac

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论