封封窝

还没有想好

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
本文为转载
快速搭建起基于Webwork与Hibernate的web应用.

主要是一下几个文件完成了我们将Hibernate的Session与Webwork的Action绑定从而快速搭建web应用的关键:

通用类:
 HibernateSessionFactory.java
 HibernateSessionFactoryImp.java
 HibernateSession.java
 HibernateSessionImp.java
 
 AbstractAction.java
拦截器:
 HibernateInterceptor.jva

此外还需要在配置文件中加入相应的申明和相关的资源文件,下面一一介绍.

一.通用类

1.HibernateSessionFactory.java中主要封装了Hibernate的SessionFactory实例,我们知道SessionFactory相比Session是重量级别,所以生成
相当耗费资源,而一个应用也只能生成一个SessionFactory实例.

 

public class HibernateSessionFactory implements Initializable, Disposable, Serializable {
 
 private static final Log LOG = LogFactory.getLog(SessionFactoryService.class);
 
 private SessionFactory sf;
 
 //返回SessionFactory实例
 public HibernateSessionFactory getSessionFactory() {
  return sf;
 }
 
 //初始化生成SessionFactory
 public void init() {
  try {
   sf = new Configuration().configure().buildSessionFactory();
  }
  catch (Exception e) {
   LOG.error("error generate SessionFactory", e);
   throw new RuntimeException( e.getMessage() );
  }
 }
 
 //关闭SessionFactory
 public void dispose() {
  try {
   sf.close();
  }
  catch (Exception e) {
   LOG.error("error closing HibernateSession", e);
  }
 }
 
 public String getDialect() {
  return Environment.getProperties().getProperty(Environment.DIALECT);
 }
 
}

2.HibernateSessionFactoryImp.java是一个Interface,供HibernateSession实现,从而让webwork拦截器自动调用其中的方法.
 
 

public interface HibernateSessionFactoryImp {
  public void setSessionFactoryService(SessionFactoryService sfs);
 }

3. HibernateSession.java封装了一个Session实例,并且实现了HibernateSessionFactoryImp接口从而在加入拦截器申明以后(后文会介绍)会通过webwork的拦截器自动调用其中的setHibernateSessionFactory()方法,从而自动将HibernateSessionFactory实例注入到了HibernateSession中,供HibernateSession调用

 

 
public class HibernateSession implements HibernateSessionFactoryImp{
 
 private static final Log LOG = LogFactory.getLog(SessionService.class);
 
 private Session session;
 private Transaction transaction;
 private HibernateSessionFactory hsf;
 private boolean rollBackOnly;
 
 //返回一个Session实例,并开始一个事务
 public Session getSession() throws HibernateException {
  if (session==null) {
   session = hsf.getSessionFactory().openSession();
   transaction = session.beginTransaction();
  }
  return session;
 }
 
 //注入HibernateSessionFactory实例
 public void setHibernateSessionFactory(HibernateSessionFactory hsf) {
  this.hsf = hsf;
 }
 
 
  //关闭一个Session
 public void disposeSession() throws HibernateException {
  
  LOG.debug("disposing");
  if (session==null) return;
  if (rollBackOnly) {
   try {
    LOG.debug("rolling back");
    if (transaction!=null) transaction.rollback();
   }
   catch (HibernateException e) {
    LOG.error("error during rollback", e);
    throw e;
   }
   finally {
    session.close();
    session=null;
    transaction=null;
   }
  }
  else {
   try {
    LOG.debug("committing");
    if (transaction!=null) transaction.commit();
   }
   catch (HibernateException e) {
    LOG.error("error during commit", e);
    transaction.rollback();
    throw e;
   }
   finally {
    session.close();
    session=null;
    transaction=null;
   }
  }
 }
 //事务回滚
 public boolean isRollBackOnly() {
  return rollBackOnly;
 }
 public void setRollBackOnly(boolean rollBackOnly) {
  this.rollBackOnly = rollBackOnly;
 }
}
 
 
4.同样HibernateSessionImp.java也是一个接口,供AbstractAction实现,从而使Webwork自动调用其中的setHibernateSession()方法,将HibernateSession实例注入到AbstractAction中
 
public interface HibernateSessionImp {
 public void setHibernateSession(HibernateSession hs);
}

5.让我们来看看AbstractAction.java
 


 
 public abstract class AbstractAction extends ActionSupport implements HibernateSessionImp{
 
 private static final Log LOG = LogFactory.getLog(AbstractAction.class);
 
 private HibernateSession hs;
 
  
 //重写Webwork的execute()方法
 public String execute() throws Exception {
 
  // 如果有错返回到INPUT所指定的页面
  if ( hasErrors() ) {
   LOG.debug("action not executed, field or action errors");
   LOG.debug( "Field errors: " + getFieldErrors() );
   LOG.debug( "Action errors: " + getActionErrors() );
   return INPUT;
  }
  LOG.debug("executing action");
  return go();
 }
 
 protected abstract String go() throws HibernateException;
 
 //注入HibernateSession实例
 public void setSessionService(SessionService ss) {
  this.ss = ss;
 }
 
 public SessionService getSessionService() {
  return ss;
 }
 
 //返回Session实例
 protected Session getSession() throws HibernateException {
  return ss.getSession();
 }
 
 protected void setRollbackOnly() {
  ss.setRollBackOnly(true);
 }
 
 /**
  * 将需要保存的对象暂存在Webwork的Session中(此Session非彼Session)
  */
 protected Object get(String name) {
  return ActionContext.getContext().getSession().get(name);
 }
 /**
  * 从Webwork的Session(此Session非彼Session)中取出暂存的对象
  */
 protected void set(String name, Object value) {
  ActionContext.getContext().getSession().put(name, value);
  
 }
 



二.拦截器
 HibernateInterceptor.java
 


 
 public class HibernateInterceptor implements Interceptor {
 
 private static final Log LOG = LogFactory.getLog(HibernateInterceptor.class);
 
 public void destroy() {}
 public void init() {}
 public String intercept(ActionInvocation invocation) throws Exception {
  Action action = invocation.getAction();
  if ( !(action instanceof AbstractAction) ) return invocation.invoke();
  
  HibernateSession hs = ( (AbstractAction) action ).getHibernateSession();
  try {
   return invocation.invoke();
  }
  
  
  catch (Exception e) { 
   ss.setRollBackOnly(true);
   if (e instanceof HibernateException) {
    LOG.error("HibernateException in execute()", e);
    return Action.ERROR;
   }
   else {
    LOG.error("Exception in execute()", e);
    throw e;
   }
  }
  
  finally {
   try {
    hs.disposeSession();
   }
   catch (HibernateException e) {
    LOG.error("HibernateException in dispose()", e);
    return Action.ERROR;
   }
  }
 }
}

拦截器监视Action的一举一动,并随时截获异常信息,返回给页面.若无异常,则调用HibernateSession的disposeSession()方法,关闭一个Session. 

 

好了,所有具体的代码告一段落,在以上文件加入我们到的开发所定义的包之后,还需要在配置文件中加以定义.

三.配置文件
1.components.xml
<components>

    <component>
        <scope>request</scope>
        <class>com.sunbay.util.SessionService</class>
        <enabler>com.sunbay.util.SessionServiceInterface</enabler>
    </component>

    <component>
        <scope>application</scope>
        <class>com.sunbay.util.SessionFactoryService</class>
        <enabler>com.sunbay.util.SessionFactoryServiceInterface</enabler>
    </component>

</components>

只要components.xml放在WEB-INF目录下,并确认webwork-default.xml中有如下声明(当然你也可以定义自己的xml文件,并让xwork.xml包括进来):

<interceptor name="component" 
class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
<interceptor name="hibernate" 
class="你存放HibernateInterceptor文件的包名.HibernateInterceptor"/>

2.由于我们用到了日志,所以在WEB-INF目录下还要加入log4j.properties文件,该文件在Demo中有,几乎不要改动.


3.在xwork.xml中加入对webwork-default.xml的引用.


到这里我们快速搭建基于Webwork+Hibernate的Web应用已经完成,看看我们编写Action是多么方便吧.

在web应用中,一般我们对一个用例建立一个对应的Action,从而是整个应用结构清晰.


 
public class myAction extends AbstractAction{
 
 public myAction(){}
 
 
 public String go() throws HibernateException{
   
   //取得Session实例
   getSession().save(某个对象);
   
   rerurn SUCCESS;
   
 }
 
 

 
每一个Action都必须继承AbstractAction,并覆写go()方法即可.在go()方法中要取得session实例,只要用getSession()方法就可以了.试想我们要是在每一个Action中都载入Hibernate配置文件,生成Session Factory和Session实例是多么烦人啊! 

要想保存用户信息,只要用set()方法保存,要用时用get()方法取出就可以

在wen应用一开始,在xwork.xml文件中由于加入了对webwork-default.xml的引用,所以webwork又找到webwork-default.xml,通过其中的
<interceptor name="component" 
class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>webwork
又找到了
components.xml,于是,通用类的四个文件都被加入webwork的视线.拦截器自动调用HibernateSessionFactoryImp.java和HibernateSessionImp.java中的set方法,先将
HibernateSessionFactory实例注入到HibernateSession中,然后当在调用Action的候,又将HibernateSession的实例注入到了AbstractAction中,从而使继承AbstractAction
的每一个Action实例都有了HibernateSession实例,只要在go()中调用getSession()方法我们就有了session实例!
posted on 2006-06-13 08:11  封封  阅读(588)  评论(0编辑  收藏  举报