Struts与Hibernate的完美结合方案
将Hibernate和Struts进行配合,以节省开发时间和成本.经过再三考虑,发现通过JavaScript生成XML发送到后台Servlet利用Hibernate再写入数据库的方法并不可取,此方案只能用于简单操作.当数据库的结构发生变更的时候,则对网站代码需要进行五次修改:
1.修改Hibernate映射;
2.修改Servlet中对XML的解析;
3.修改JavaScript中生成的XML结构;
4.修改HTML表单验证;
5.修改HTML表单.而通过Struts直接将Form表单
递交给Hibernate这种方法则灵活性很强.当数据库的结构发生变更时,我们做三次修改即可达到上述效果:
1.修改Hibernate映射;
2.修改HTML表单验证;
3.修改HTML表单验证.因为我们的控制层是直接将表单交给Beans,再通过Hibernate写入数据库的,中间层的代码除了验证外非常小.
因此,通过Struts可以减少很多代码,并且,当数据模型的变更时,修改起来相对简单!这就是使用Struts+Hibernate的好处之一吧!下面就让我们来看一下整个操作的过程:
1.准备工作.
新建J2EE工程,加入Struts及Hibernate.设定好MySQL连接驱动,打开MyEclipseDatabaseExplorer视图,新建连接Stulib,并将数据库的结构通过Hibernate映射成JavaBeans
2.新建一个From,一个Action,一个ActionFrom.其配置源码如下:
"http://struts.apache.org/dtds/struts-config_1_2.dtd"> |
这里有三个重点需要说明:1.form-beans配置,其名称首先对应于通过Hibernate映射成的JavaBeans名称,其次要与action-mappings中的action中的name的名称一致.
2.action的说明input是指是哪个网页提交过来的Form;path是指在URL中显示的一个路径;name是指此表单对应于哪个JavaBeans,这个JavaBeans必需继承ActionFrom类;scope表示此表单的作用域;type则是对应于哪个Servlet来处理这个表单.3.struts-config.xml中所出现的的type中对应的字符串实际上是表示对应于项目中的哪个Beans或Servlet.
下面是wills.UserReg的代码:
packagewills; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importorg.apache.struts.action.Action; importorg.apache.struts.action.ActionForm; importorg.apache.struts.action.ActionForward; importorg.apache.struts.action.ActionMapping; publicclassUserRegextendsAction{ publicActionForwardexecute(ActionMappingmapping,ActionFormform, HttpServletRequestrequest,HttpServletResponseresponse){ //这条语句就将相对应的From交给JavaBeans了. Usernamews=(Username)form; //经过测度,我们可以正确地取出JavaBeans中的值. System.out.print(ws.getName()); //TODOAuto-generatedmethodstub returnnull; } } |
下面是对Hibernate生成的抽象类的修改.AbstractUsername.java代码如下:
我们可以与Hibernate生成的代码比较发现只是多了extendsActionFrom,当然,我们也可以在AbstractUsername.java中添加reset(),validate(),…等方法.
publicabstractclassAbstractUsernameextendsActionFormimplements Serializable{ privateintId; privateStringname; ….. PublicvoidsetName(String) { … } } |
其总体结构如上图所示.
3.总结:通过这种方式进行网站应用开发,当需求发生改更时有一定的优势,而它的缺点就是配置非常麻烦.不过借助于Eclipse开发工具,工作变得相对简单.但是,当配置更改时还是需要特别注意.到今天为止,已完成了以下的工作:
1.Apache与Tomcat的整合.
2.数据库的建模及Hibernate的配置.
3.JavaScript与Servlet之间的通讯.
4.Struts与Hibernate之间的整合.
有以上的基础,下面的开发将变得透明而又简单.这是因为:第一,对数据库的操作逻辑是固定的,无论数据库的模型是否发生变理;第二,对在什么时候使用JavaScript通过XMLHTTP与Servlet进行通讯有一定的了解;第三,对Struts与Hibernate的配合操作有一定的了解.
在Hibernate3中发现了一个不能查询与插入中文字符的问题,通过网上查阅资源,原来是Hibernate3中的一个Bug,最后没有办法,在JSP2.0技术手册中看到可以通过Filter来解决中文问题,将其代码摘录下来,结果发现,不仅HTML传过来的表单没有了任何中文问题,而且Hibernate的中文问题也解决了.下面就将整个过程描述如下:
因为Filter的是起过滤的作用,它运行于Servlet的Service()之前,所以,在表单还没有到达Service()之前会执行Filter.添加Filter的方法和我们添加Servlet的方法是一样的.都要配置Web.xml,下面是解决中文问题的Web.xml配置:
setCharacterEncoding wills.servlet.SetCharacterEncodingFilter encoding gb2312 setCharacterEncoding /* |
上面的配置说明了:1.定义了一个FiltersetCharacterEncoding它的执行路径是:wills.servlet.SetCharaterEncodingFilter初始化参数是:encoding和gb2312等下我们来看它们是什么意思.2.定义了对于哪些文件通过的时候执行setCharacterEncoding上面我们可以看出所有的相关Jsp也好,Serlet也好等等,都执行setCharacterEncoding.下面是setCharacterEncoding.javapackagewills.servlet;
importjava.io.IOException; importjavax.servlet.Filter; importjavax.servlet.FilterChain; importjavax.servlet.FilterConfig; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; publicclassSetCharacterEncodingFilterimplementsFilter{ protectedStringencoding=null; protectedFilterConfigfilterConfig=null; protectedbooleanignore=true; publicvoiddestroy(){ this.encoding=null; this.filterConfig=null; } publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse, FilterChainchain)throwsIOException,ServletException{ //Conditionallyselectandsetthecharacterencodingtobeused if(ignore||(request.getCharacterEncoding()==null)){ Stringencoding=selectEncoding(request); if(encoding!=null) request.setCharacterEncoding(encoding); } //Passcontrolontothenextfilter chain.doFilter(request,response); } publicvoidinit(FilterConfigfilterConfig)throwsServletException{ this.filterConfig=filterConfig; this.encoding=filterConfig.getInitParameter("encoding"); Stringvalue=filterConfig.getInitParameter("ignore"); if(value==null) this.ignore=true; elseif(value.equalsIgnoreCase("true")) this.ignore=true; elseif(value.equalsIgnoreCase("yes")) this.ignore=true; else this.ignore=false; } protectedStringselectEncoding(ServletRequestrequest){ return(this.encoding); } } |