Struts2中由doubleselect标签引发的问题

来源:互联网 发布:手机找工作软件 编辑:程序博客网 时间:2024/05/16 09:54

想写关于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 struts2Unable 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 exceptiontag '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 exceptionExpression 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,之后报了以上错误。

有一下几点需要注意:

  1. 需要在页面中用s:form标签将doubleselect包绕
  2. 注意要填写 s:form中的name值
  3. .注意form是struts中的<s:form>,普通的html<form>同样报错

5.处理事务的不同手段

在项目中最开始我使用了Hibernate中的OpenSessionInView的模式,即在用户每次提交请求的时候都通过Filter开启事务,请求结束就关闭事务,如下

@Overridepublic 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处理事务的模式在不同的场合有不同地点用法,请大家酌情甄选。

阅读全文
0 0