转: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连接驱动, 打开MyEclipse Database Explorer 视图,新建连接Stulib,并将数据库的结构通过Hibernate映射成JavaBeans

2.     新建一个From,一个Action,一个ActionFrom.其结构图如下:
上图是Struts的struts-config.xml配置图,其配置源码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" 

"http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
   <data-sources />
   <form-beans>
        <form-bean name="UserReg" type="wills.Username" />
   </form-beans>
   <global-exceptions />
   <global-forwards />
   <action-mappings>
        <action input="/UserReg.jsp" path="/UserReg" name="UserReg" scope="request" type="wills.UserReg" />
   </action-mappings>
   <message-resources parameter="wills.struts.ApplicationResources" />
</struts-config>
这里有三个重点需要说明: 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.

下面是UserReg.jsp中的代码: 请注意突出代码.
<body>
    <html:form action="/UserReg" method="post" focus="login">
      <table border="0">
        <tr>
          <td>Login:</td>
          <td><html:text property="name" /></td>
        </tr>
        <tr>
          <td>Password:</td>
          <td><html:password property="pwd" /></td>
        </tr>
        <tr>
          <td colspan="2" align="center"><html:submit /></td>
        </tr>
      </table>
    </html:form>
</body>
下面是wills.UserReg的代码:
package wills;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class UserReg extends Action {
      public ActionForward execute(ActionMapping mapping, ActionForm form,
                 HttpServletRequest request, HttpServletResponse response) {
// 这条语句就将相对应的From交给JavaBeans了.
           Username ws = (Username) form;
// 经过测度,我们可以正确地取出JavaBeans中的值.
           System.out.print(ws.getName());
           // TODO Auto-generated method stub
           return null;
      }
}
下面是对Hibernate生成的抽象类的修改. AbstractUsername.java 代码如下:
我们可以与Hibernate生成的代码比较发现只是多了 extends ActionFrom, 当然,我们也可以在AbstractUsername.java中添加 reset(), 

validate(),…等方法.
public abstract class AbstractUsername extends ActionForm implements
           Serializable {
private int Id;
private String name;
…..
Public void setName(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配置:

 
      <filter>
<filter-name>setCharacterEncoding</filter-name>
<filter-class>wills.servlet.SetCharacterEncodingFilter</filter-class>
<init-param>
      <param-name>encoding</param-name>
      <param-value>gb2312</param-value>
</init-param>
      </filter>
      <filter-mapping>
       <filter-name>setCharacterEncoding</filter-name>
       <url-pattern>/*</url-pattern>
</filter-mapping>
 
上面的配置说明了: 1.定义了一个Filter setCharacterEncoding 它的执行路径是: wills.servlet.SetCharaterEncodingFilter 初始化参数

是: encoding 和 gb2312等下我们来看它们是什么意思. 2. 定义了对于哪些文件通过的时候执行setCharacterEncoding 上面我们可以看出所

有的相关Jsp也好,Serlet也好等等,都执行setCharacterEncoding. 下面是setCharacterEncoding.java
 
package wills.servlet;
 
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
public class SetCharacterEncodingFilter implements Filter {
      protected String encoding = null;
      protected FilterConfig filterConfig = null;
      protected boolean ignore = true;
 
      public void destroy() {
 
           this.encoding = null;
           this.filterConfig = null;
 
      }
 
      public void doFilter(ServletRequest request, ServletResponse response,
                 FilterChain chain) throws IOException, ServletException {
 
           // Conditionally select and set the character encoding to be used
           if (ignore || (request.getCharacterEncoding() == null)) {
                 String encoding = selectEncoding(request);
                 if (encoding != null)
                      request.setCharacterEncoding(encoding);
           }
           // Pass control on to the next filter
           chain.doFilter(request, response);
 
      }
 
      public void init(FilterConfig filterConfig) throws ServletException {
           this.filterConfig = filterConfig;
           this.encoding = filterConfig.getInitParameter("encoding");
           String value = filterConfig.getInitParameter("ignore");
           if (value == null)
                 this.ignore = true;
           else if (value.equalsIgnoreCase("true"))
                 this.ignore = true;
           else if (value.equalsIgnoreCase("yes"))
                 this.ignore = true;
           else
                 this.ignore = false;
 
      }
 
      protected String selectEncoding(ServletRequest request) {
           return (this.encoding);
      }
}
此方法基本解决了通讯中的中文问题,但是在JavaScript与XML中行不通,解决的办法是: 在Servlet的第一行添加语句request.setCharacterEncoding("utf-8"); 原因可能是Filter对Stream流的信息也进行了编码,所以必须将编码变成UTF-8.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值