Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2566868
  • 博文数量: 709
  • 博客积分: 12251
  • 博客等级: 上将
  • 技术积分: 7905
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-17 00:00
个人简介

实现有价值的IT服务

文章存档

2012年(7)

2011年(147)

2009年(3)

2008年(5)

2007年(74)

2006年(431)

2005年(42)

分类: Java

2006-07-21 17:38:03

将Hibernate和Struts进行完美结合

关键词:                                          

HibernateStruts进行配合, 以节省开发时间和成本. 经过再三考虑,发现通过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工程,加入StrutsHibernate. 设定好MySQL连接驱动, 打开MyEclipse Database Explorer 视图,新建连接Stulib,并将数据库的结构通过Hibernate映射成JavaBeans
2.     新建一个From,一个Action,一个ActionFrom.其结构图如下:
上图是Strutsstruts-config.xml配置图,其配置源码如下:
xml version="1.0" encoding="UTF-8"?>
DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "">
<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 是指是哪个网页提交过来的Formpath 是指在URL中显示的一个路径;name是指此表单对应于哪个JavaBeans ,这个JavaBeans必需继承ActionFrom类;scope 表示此表单的作用域;type 则是对应于哪个Servlet 来处理这个表单. 3. struts-config.xml中所出现的的type中对应的字符串实际上是表示对应于项目中的哪个BeansServlet.
下面是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.      JavaScriptServlet之间的通讯.
4.      StrutsHibernate 之间的整合.
有以上的基础,下面的开发将变得透明而又简单. 这是因为:第一,对数据库的操作逻辑是固定的,无论数据库的模型是否发生变理;第二,对在什么时候使用JavaScript通过XMLHTTPServlet进行通讯有一定的了解;第三,StrutsHibernate的配合操作有一定的了解.


2006119                            星期四                               22031
 
Hibernate3 中发现了一个不能查询与插入中文字符的问题,通过网上查阅资源,原来是Hibernate3中的一个Bug, 最后没有办法,JSP2.0技术手册中看到可以通过Filter来解决中文问题,将其代码摘录下来,结果发现,不仅HTML传过来的表单没有了任何中文问题,而且Hibernate的中文问题也解决了.下面就将整个过程描述如下:
因为Filter 的是起过滤的作用,它运行于Servlet Service()之前,所以,在表单还没有到达Service()之前会执行Filter. 添加Filter 的方法和我们添加Servlet 的方法是一样的. 都要配置Web.xml, 下面是解决中文问题的Web.xml配置:
 
      <filter>
<filter-name>setCharacterEncodingfilter-name>
<filter-class>wills.servlet.SetCharacterEncodingFilterfilter-class>
<init-param>
      <param-name>encodingparam-name>
      <param-value>gb2312param-value>
init-param>
      filter>
      <filter-mapping>
       <filter-name>setCharacterEncodingfilter-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);
      }
}
此方法基本解决了通讯中的中文问题,但是在JavaScriptXML中行不通,解决的办法是: Servlet的第一行添加语句request.setCharacterEncoding("utf-8"); 原因可能是FilterStream流的信息也进行了编码,所以必须将编码变成UTF-8.


200622                                  星期四                         184247
 
Structs-config.xmlforward的配置中添加redirect=”true” 要注意, redirect中重新定位,将会清除本页面范围以内的所有的变量的值. 而不用redirect则将造成表单重复递交,解决的办法是,可以在后台将表单清除.
阅读(1107) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~