首先,在工程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&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();)