Struts2.x 集成 Guice 与 warp-persist 大概

来源:互联网 发布:东方财富龙虎榜数据. 编辑:程序博客网 时间:2024/05/14 10:05

首先,在工程web.xml里载入struts2  guice

 

<filter>

        <filter-name>guice</filter-name>

        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>

    </filter>

 

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>guice</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>*.do</url-pattern>

    </filter-mapping>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>*.jsp</url-pattern>

    </filter-mapping>

struts2的mapping有点怪吧,因为跟fckeditor冲突了,把/*的mapping改成这样了,不想让fileupload的request被struts2拦截封装(http://blog.csdn.net/klafzeng/archive/2009/03/07/3967171.aspx)
在struts.mxl中加入
  <constant name="struts.objectFactory" value="guice" />
  <constant name="struts.action.extension" value="do" />
  <constant name="guice.module" value="youcity.blog.module.YouCityModule"/>
也可以写入strtus.property中,与struts.xml同级目录
意思分别是:
使用guice
struts的访问后缀为*.do
指定guice的Module
youcity.blog.module目录:
public class YouCityModule implements Module {
public void configure(Binder binder) {
binder.install(new PersistModule());
}
}
public class PersistModule extends AbstractModule {
private final static Logger log = Logger.getLogger(PersistModule.class);
@Override
protected void configure() {
log.info("GsModule configure .....");
bindConstant().annotatedWith(JpaUnit.class).to("blogPersist");
install(PersistenceService.usingJpa().across(UnitOfWork.REQUEST)
.transactedWith(TransactionStrategy.LOCAL)
.forAll(Matchers.any())
.buildModule());
log.info("GsModule bind ..... ");
}
}
blogPersist持久化配置,存在于classes/META-INF/persistence.xml
<persistence-unit name="blogPersist" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider> 
<class>youcity_src.youcity.blog.model.SUser</class>
<class>youcity_src.youcity.blog.model.Article</class>
<class>youcity_src.youcity.blog.model.Comment</class>
<properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
            <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/blog?useUnicode=true&amp;characterEncoding=UTF-8"/>
             <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value="myDB"/>
            <property name="hibernate.connection.pool_size" value="100"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect"/>
            <property name="hibernate.connection.autocommit" value="false"/>
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
</persistence-unit>
整合warp-persist
@ThreadSafe
public class SessionPerRequestInterceptor implements Interceptor {
    // not Serializable
    private transient Provider<EntityManagerFactory> emfProvider;
    
    @Inject
    public SessionPerRequestInterceptor(Provider<EntityManagerFactory> emfProvider) {
        // only use after the PersistenceService starts
       //注入JPA实体管理工厂
        this.emfProvider = emfProvider;
    }
    public String intercept(ActionInvocation ai) throws Exception {
        EntityManagerFactoryHolder.getCurrentEntityManager();      
        try {
            return ai.invoke();
        } finally {
            EntityManagerFactoryHolder.closeCurrentEntityManager();
        }
    }
    
    /**
     * @see com.opensymphony.xwork2.interceptor.Interceptor#init()
     */
    public void init() {}
    
    /**
     * @see com.opensymphony.xwork2.interceptor.Interceptor#destroy()
     */
    public void destroy() {
        if (emfProvider != null) {
            EntityManagerFactory emf = emfProvider.get();
            synchronized(emf) {
                if (emf.isOpen()) emf.close();
            }
        }
    }
    
    @Inject 
    public void start(PersistenceService service) {
        //注入warp-persist service并启动
        service.start();
    }
}
<interceptor name="sessionPerRequestInterceptor" class="com.wideplay.warp.jpa.SessionPerRequestInterceptor"/>
为什么做成拦截器?
该拦截器中的注入只运行一次,主要是:
<action name="list" class="youcity.blog.action.manage.ArticleAction" method="articleList">
<result>/manage/list.jsp</result>
<interceptor-ref name="sessionPerRequestInterceptor"/> 
</action>
配置到相应的操作中,每次调用intercept方法,关闭session提交数据(EntityManagerFactoryHolder.closeCurrentEntityManager();)