您的位置:首页 > 其它

快速搭建起基于Webwork与Hibernate的web应用

2012-04-24 14:27 375 查看
快速搭建起基于Webwork与Hibernate的web应用.

快速搭建起基于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 />

<interceptor />

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 />webwork又找到了

components.xml,于是,通用类的四个文件都被加入webwork的视线.拦截器自动调用HibernateSessionFactoryImp.java和HibernateSessionImp.java中的set方法,先将

HibernateSessionFactory实例注入到HibernateSession中,然后当在调用Action的候,又将HibernateSession的实例注入到了AbstractAction中,从而使继承AbstractAction

的每一个Action实例都有了HibernateSession实例,只要在go()中调用getSession()方法我们就有了session实例!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: