想写关于doubleselect的一个小Demo,
可以从Oracle数据库中提取并可以显示级联效果
直接就想到的是用Hibernate来和数据库交互,用Struts2来页面显示以及页面跳转
但过程并没有想象的name顺利
首先建立如下项目结构:
其中出现各种问题:
1.NoClassDefFoundError
启动服务器时报错如下:
报错:
严重: Exception starting filter struts2
javax.servlet.ServletException: java.lang.NoClassDefFoundError: org/hibernate/HibernateException
错误原因:同时出现了两种框架连到一起的问题 ,发现引用的jar包出现了问题,我在解决问题前和解决问题后都没有在以上的路径中找到该类,但是最后还是解决了问题,这里给大家提供一下我整合的Hibernate&struts2的jars整合包
http://download.csdn.net/detail/tctctttccc/9920715
2.Unable to load configuration
启动服务器时
报错:
严重: Exception starting filter struts2
Unable to load configuration. - [unknown location]
........................
Caused by: Unable to load configuration. - [unknown location]
........................
Caused by: The following packages participate in cycles: default - [unknown location]
.......................
错误原因:后来发现package中的extends参数本应该是“struts-default”却变成了“default”,
3.SessionFactory过期项
在查找服务器启动报错的过程中在HibernateSessionFactory类中发现了这个过期项
提示deprecate,是不赞成这么写的
错误原因:查找一番,发现在Hibernate的版本升级过程中,已经有了更好创建sessionFactory的选择
public class HibernateSessionFactory {
private static Configuration cfg;
private static SessionFactory sessionFactory;
private static ServiceRegistry buildServiceRegistry;
static {
try {
cfg = new Configuration().configure();
buildServiceRegistry = new ServiceRegistryBuilder()
.applySettings(cfg.getProperties())
.buildServiceRegistry();
sessionFactory = cfg.buildSessionFactory(buildServiceRegistry);
} catch (HibernateException e) {
// TODO Auto-generated catch block
throw new RuntimeException("hibernate初始化失败",e);
}
}
public static Session getSession(){
//一个用户可产生一个不同的session
return sessionFactory.getCurrentSession();
}
}
后来发现虽然那种过时的方法不影响运行,但是还是建议使用新版本的优化方法
.
4.could not be resolved as a collection/array/map/enumeration/iterator type.
报错:
严重: Servlet.service() for servlet jsp threw exception
tag 'doubleselect', field 'list', name 'street': The requested list key 'map.keySet()' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]
代码:
<s:doubleselect list="map.keySet()" name="street"
listKey="district_Id" listValue="district_Name"
doubleList="map.get(top)" doubleName="district"
doubleListKey="street_Id" doubleListValue="street_Name"/>
错误原因:
doubleselect的标签中的list变量出现了问题,
回到action类中也没有异常的报错
首先就要按照提示进行检查,
是否对应的list变量不符合其应有的类型要求?
也有可能是action没有对应的get方法取得对应的list值,
亦或是action中没有set方法将list值赋值
总之做到正确的关联就能解决这个问题了
5.Expression parameters.formName is undefined on line xx, column xx in template/simple/doubleselect.ftl.
报错:
严重: Servlet.service() for servlet jsp threw exception
Expression parameters.formName is undefined on line 150, column 43 in template/simple/doubleselect.ftl.
The problematic instruction:
----------
==> ${parameters.formName} [on line 150, column 41 in template/simple/doubleselect.ftl]
in include "/${parameters.templateDir}/simple/doubleselect.ftl" [on line 25, column 1 in template/xhtml/doubleselect.ftl]
----------
Java backtrace for programmers:
----------
freemarker.core.InvalidReferenceException: Expression parameters.formName is undefined on line 150, column 43 in template/simple/doubleselect.ftl.
错误原因:本来就想写个简单的demo,在jsp中就只写了doubleselect,之后报了以上错误。
有一下几点需要注意:
- 需要在页面中用s:form标签将doubleselect包绕
- 注意要填写 s:form中的name值
- .注意form是struts中的
<s:form>
,普通的html<form>
同样报错
5.处理事务的不同手段
在项目中最开始我使用了Hibernate中的OpenSessionInView的模式,即在用户每次提交请求的时候都通过Filter开启事务,请求结束就关闭事务,如下
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
Transaction tx = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
chain.doFilter(req, resp);
tx.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if (tx != null) {
tx.rollback();
System.out.println("rollback");
}
}
}
实现最终的需求回过头来看这个模式其实并没有在这个Hibernate和struts2的整合Demo上派上用场,因为我又在struts2中的拦截器中进行了对acting的拦截,并将事务融入了action中,如下:
public class TranInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation ai) throws Exception {
// TODO Auto-generated method stub
Transaction tx = null;
String invoke = null;
try {
tx = HibernateSessionFactory.getSession().beginTransaction();
System.out.println("enter Interceptor");
invoke = ai.invoke();
tx.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if (tx != null) {
tx.rollback();
System.out.println("rollback");
}
}
return invoke;
}
}
配置文件可参照之前写的《 Struts2 Interceptor 拦截器的使用流程 》:
http://blog.csdn.net/tctctttccc/article/details/76639478
通过拦截器同样也实现了请求和事务的相互融合,拦截器中处理事务和OpenSessionInView处理事务的模式在不同的场合有不同地点用法,请大家酌情甄选。