本文为转载
快速搭建起基于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实例!
快速搭建起基于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实例!