Spring 2.5.6 + Struts 2.1.6 + Hibernate 3.3.1 GA + Jboss 4.2.2 整合

首先就着手解決包的問題

從網上東拼西湊的文章中,然後一個一個包的測試,首先我先在Tomcat下測試的。所以其中多了幾個tomcat需要的commons包。

首先貼一下Web.xml文件的內容吧。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
>

    
<session-config>
        
<session-timeout>30</session-timeout>
    
</session-config>

    
<!-- log4j配置文件 -->
    
<context-param>
        
<param-name>log4jConfigLocation</param-name>
        
<param-value>/WEB-INF/classes/log4j.properties</param-value>
    
</context-param>

    
<!-- Spring配置文件位置 -->
    
<context-param>
        
<param-name>contextConfigLocation</param-name>
        
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
    
</context-param>

    
<!-- 加載Spring配置文件 -->
    
<listener>
        
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    
</listener>

    
<!--解決Hibernate延遲加載出現的問題,需要放到struts2過濾器之前-->
    
<filter>
        
<filter-name>lazyLoadingFilter</filter-name>
        
<filter-class>
            org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
    
</filter>

    
<!-- Struts過濾器 -->
    
<filter>
        
<filter-name>struts2</filter-name>
        
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    
</filter>

    
<!--解決Hibernate延遲加載出現的問題,仍需要放到struts2過濾器mapping之前-->
    
<filter-mapping>
        
<filter-name>lazyLoadingFilter</filter-name>
        
<url-pattern>*.action</url-pattern>
    
</filter-mapping>

    
<filter-mapping>
        
<filter-name>struts2</filter-name>
        
<url-pattern>/*</url-pattern>
        
<dispatcher>REQUEST</dispatcher>
        
<dispatcher>FORWARD</dispatcher>
    
</filter-mapping>

    
<filter>
        
<filter-name>EncodeFilter</filter-name>
        
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        
<init-param>
            
<param-name>encoding</param-name>
            
<param-value>UTF-8</param-value>
        
</init-param>
    
</filter>
    
<filter-mapping>
        
<filter-name>EncodeFilter</filter-name>
        
<url-pattern>/*</url-pattern>
    
</filter-mapping>

    
<welcome-file-list>
        
<welcome-file>index.jsp</welcome-file>
    
</welcome-file-list>
</web-app>

 

然後再貼一下applicationContext.xml文件的內容。畢竟是spring配置,最核心的東西,把所有其他框架整合到一起的樞紐。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop
="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context
="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd   
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd   
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>
    
<description>Spring公共配置文件</description>

    
<!-- 啓用註解 -->
    
<context:annotation-config />
    
<!-- 使用annotation 自動註冊bean,並保證@Required,@Autowired的屬性被注入 -->
    
<context:component-scan base-package="com.gts.cns" />

    
<!-- 定義數據源的Bean ,提供給Hibernate的sessionFactory-->
    
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        
<property name="jndiName" value="java:/MySqlDS" />
    
</bean>

    
<!--     定義數據源的Bean ,提供給Hibernate的sessionFactory-->
<!--        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">-->
<!--            <property name="driverClassName" value="com.mysql.jdbc.Driver">-->
<!--            </property>-->
<!--            <property name="url" value="jdbc:mysql://localhost:3306/TPig">-->
<!--            </property>-->
<!--            <property name="username" value="root"></property>-->
<!--            <property name="password" value="admin"></property>-->
<!--        </bean>-->

    
<!-- 定義Hibernate的sessionFactory,通過該Bean,可以獲得Hibernate的Session-->
    
<bean id="sessionFactory"
        class
="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        
<property name="dataSource">
            
<ref bean="dataSource" />
        
</property>

        
<!-- 自動掃描Class的hibernate映射文件 -->
        
<property name="packagesToScan">
            
<list>
                
<!--若寫成model.* 則映射不到,還沒有來得及看源代碼 -->
                
<value>*</value>
            
</list>
        
</property>

        
<property name="hibernateProperties">
            
<props>
                
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                
<prop key="hibernate.show_sql">true</prop>
            
</props>
        
</property>

        
<!-- 使用配置文件方式 -->
        
<!--        <property name="mappingResources">-->
        
<!--            <list>-->
        
<!--                <value>model/TbUser.hbm.xml</value>-->
        
<!--            </list>-->
        
<!--        </property>-->
    
</bean>

    
<!--======================== 事務配置 ========================-->
    
<!-- 配置事務管理器 -->
    
<bean id="transactionManager"
        class
="org.springframework.orm.hibernate3.HibernateTransactionManager">
        
<property name="sessionFactory">
            
<ref local="sessionFactory" />
        
</property>
    
</bean>

    
<!-- 配置事務特性 ,配置add、delete和update開始的方法,事務傳播特性爲required-->
    
<tx:advice id="txAdvice" transaction-manager="transactionManager">
        
<tx:attributes>
            
<tx:method name="insert*" propagation="REQUIRED" />
            
<tx:method name="delete*" propagation="REQUIRED" />
            
<tx:method name="update*" propagation="REQUIRED" />
            
<tx:method name="*" read-only="true" />
        
</tx:attributes>
    
</tx:advice>

    
<!--
        配置那些類的方法進行事務管理,當前com.gts.cns.*.service包中的子包、類中所有方法需要,還需要參考tx:advice的設置
    
-->
    
<aop:config>
        
<aop:pointcut id="allManagerMethod"
            expression
="execution (* com.gts.cns.*.service.*.*(..))" />
        
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" />
    
</aop:config>

</beans>

 

 

在裏面也包含了另一個使用Tomcat的DataSource,已經註釋起來了。我後面使用的Jboss,所以就先註釋起來了。

最後一個配置文件就是struts.xml的內容了

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd"
>
<struts>
    
<constant name="struts.action.extension" value="shtml" />
    
<constant name="struts.objectFactory" value="spring" />
    
<include file="struts-default.xml" />

    
<package name="default" extends="struts-default">
        
<interceptors>
            
<interceptor-stack name="defaultStack"></interceptor-stack>
        
</interceptors>

        
<global-results>
            
<result name="error">/error.jsp</result>
        
</global-results>
    
</package>

    
<include file="struts-login.xml" />
</struts>

 

 

爲了業務區分,我把struts文件放不同文件中

struts-login.xml 的內容

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd"
>
<struts>
    
<package name="user" extends="default">

        
<!--登錄界面 -->
        
<action name="login" class="com.gts.cns.login.action.UserLoginAction"
            method
="login">
            
<result name="success">
                /jsp/login.jsp
            
</result>
        
</action>
        
<action name="loginError" class="com.gts.cns.login.action.UserLoginAction"
            method
="error">
            
<result name="success">
                /jsp/error.jsp
            
</result>
        
</action>
        
    
</package>
</struts>

 

最後需要貼一下jboss數據庫連接的文件mysql-ds.xml。原始的文件在/jboss-4.2.2.GA/docs/examples/jca目錄下,然後就看你鏈接什麼數據庫了,我使用的是mysql,所以複製了mysql-ds.xml,把它複製到/jboss-4.2.2.GA/server/default/deploy目錄下面,因爲我的工程是部署在這個下面的。

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id: mysql-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ -->
<!--  Datasource config for MySQL using 3.0.9 available from:
http://www.mysql.com/downloads/api-jdbc-stable.html
-->

<datasources>
  
<local-tx-datasource>
    
<jndi-name>MySqlDS</jndi-name>
    
<connection-url>jdbc:mysql://127.0.0.1:3306/TPig</connection-url>
    
<driver-class>com.mysql.jdbc.Driver</driver-class>
    
<user-name>root</user-name>
    
<password>admin</password>
    
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    
<!-- should only be used on drivers after 3.22.1 with "ping" support
    <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
    
-->
    
<!-- sql to call when connection is created
    <new-connection-sql>some arbitrary sql</new-connection-sql>
      
-->
    
<!-- sql to call on an existing pooled connection when it is obtained from pool - MySQLValidConnectionChecker is preferred for newer drivers
    <check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
      
-->

    
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml -->
    
<metadata>
       
<type-mapping>mySQL</type-mapping>
    
</metadata>
  
</local-tx-datasource>
</datasources>

 

 

 

 接着我這裏貼一下我的測試代碼

Action部分

/**
 * Create by TPig
 * Since 2010上午09:43:36
 
*/
package com.gts.cns.login.action;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.gts.cns.base.BaseAction;
import com.gts.cns.login.service.IUserLoginService;

/**
 * 類說明:
 * Create by TPig
 * Since 2010上午09:43:36
 
*/
@SuppressWarnings(
"serial")
public class UserLoginAction extends BaseAction {

    
/**
     * 用戶登錄測試接口
     
*/
    @Autowired
    @Qualifier(
"userLoginService")
    
private IUserLoginService userLoginService;

    
/**
     * 
@return the name
     
*/
    
public String getName() {
        
return name;
    }

    
/**
     * 
@param name the name to set
     
*/
    
public void setName(String name) {
        
this.name = name;
    }

    
public String login() {
        
this.userLoginService.userTest();
        
this.name = "test";
        
return SUCCESS;
    }

    
public String error() {
        
return SUCCESS;
    }

    
private String name;

}

 

 

Service部分

/**
 * Create by TPig
 * Since 2010上午09:47:35
 
*/
package com.gts.cns.login.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gts.cns.base.impl.BaseServiceImpl;
import com.gts.cns.login.dao.IUserLoginDao;
import com.gts.cns.login.service.IUserLoginService;

/**
 * 類說明:
 * Create by TPig
 * Since 2010上午09:47:35
 
*/
@Service(
"userLoginService")
public class UserLoginServiceImpl extends BaseServiceImpl implements IUserLoginService {
    @Autowired
    
private IUserLoginDao userLoginDao;

    
/*
     * (non-Javadoc)
     * @see com.gts.cns.userlogin.service.IUserLoginService#userTest()
     
*/
    
public String userTest() {
        System.out.println(
"==============進入Service==================");
        
this.userLoginDao.daoTest();
        
return "test";
    }

}

 

 

Dao部分

/**
 * Create by TPig
 * Since 2010上午10:31:15
 
*/
package com.gts.cns.login.dao.impl;

import java.util.List;

import model.TbUser;

import org.springframework.stereotype.Repository;

import com.gts.cns.base.impl.BaseDaoImpl;
import com.gts.cns.login.dao.IUserLoginDao;

/**
 * 類說明:
 * Create by TPig
 * Since 2010上午10:31:15
 
*/
@Repository(
"userLoginDao")
public class UserLoginDaoImpl extends BaseDaoImpl implements IUserLoginDao {

    
/*
     * (non-Javadoc)
     * @see com.gts.cns.userlogin.dao.IUserLoginDao#daoTest()
     
*/
    @SuppressWarnings(
"unchecked")
    
public void daoTest() {
        System.out.println(
"=================進入DAO==================");
        String hql 
= "from TbUser";
        List
<TbUser> userList = this.getHibernateTemplate().find(hql);

        
for (TbUser tbUser : userList) {
            System.out.println(tbUser.getText());
        }
    }

}

 

 

Bean部分

/**
 * Create by TPig
 * Since 2010下午10:39:05
 
*/
package model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * 類說明:
 * Create by TPig
 * Since 2010下午10:39:05
 
*/
@Entity
@Table(name
="tb_user")
public class TbUser {
    @Id
    @GeneratedValue
    @Column(name
="id")
    
private int id;
    @Column(name
="user")
    
private String user;
    @Column(name
="text")
    
private String text;

    
/**
     * 構造函數
     
*/
    
public TbUser() {
    }

    
/**
     * 
@return the id
     
*/
    
public int getId() {
        
return id;
    }

    
/**
     * 
@param id the id to set
     
*/
    
public void setId(int id) {
        
this.id = id;
    }

    
/**
     * 
@return the user
     
*/
    
public String getUser() {
        
return user;
    }

    
/**
     * 
@param user the user to set
     
*/
    
public void setUser(String user) {
        
this.user = user;
    }

    
/**
     * 
@return the text
     
*/
    
public String getText() {
        
return text;
    }

    
/**
     * 
@param text the text to set
     
*/
    
public void setText(String text) {
        
this.text = text;
    }
}

 

 

  數據庫部分我就貼一下圖片吧

 

 這個是數據庫內容了

 

現在我把jboss啓動起來,因爲我使用MyEclipse的插件,所以JBoss的配置文件不需要更改

直接啓動起來後發現問題了。

Caused by: java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
    at org.springframework.orm.hibernate3.support.HibernateDaoSupport.checkDaoConfig(HibernateDaoSupport.java:117)
    at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
    ... 150 more

 其中主要看這條錯誤,告知是sessionFactory或者hibernateTemplate是空的,其實原本我也不知道是怎麼一回事,直接就google了,發現已經有人跟到hibernate源碼裏面去了,並且提示sessionFactory爲空的。我也就參照那位仁兄的建議,手動塞進去了。

代碼如下:

@Resource(name="sessionFactory")
    
public void setSuperSessionFactory(SessionFactory sessionFactory){
        
super.setSessionFactory(sessionFactory);
    }

這塊代碼我就寫在了BaseDaoImpl.java中,因爲我每一層之上都加了一個base層,我是考慮爲今後加統一功能的時候方便,現在就正好派上用場了。然後我再次啓動服務器。

問題又來了

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: java.lang.NoSuchMethodException: org.hibernate.validator.ClassValidator.<init>(java.lang.Class, java.util.ResourceBundle, org.hibernate.validator.MessageInterpolator, java.util.Map, org.hibernate.annotations.common.reflection.ReflectionManager)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:537)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:192)
    at org.springframework.beans.factory.annotation.InjectionMetadata.injectMethods(InjectionMetadata.java:117)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:302)
    ... 151 more

 

這個問題就比較折騰了,我當時也無從着手的感覺,網上搜索的也亂七八糟的,有點似是而非的感覺。偶然看到一帖中說到,jboss的hibernate老了,只要刪除就可以了。爲了以防萬一,我將jboss中的hibernate-*.jar全部貼到文件夾外面。然後重啓就正常了。

 

接着我再訪問這個項目的時候,console打印的消息就是:

14:14:51,203 INFO  [STDOUT] ==============進入Service==================
14:14:51,203 INFO  [STDOUT] =================進入DAO==================
14:14:51,515 INFO  [STDOUT] Hibernate: select tbuser0_.id as id0_, tbuser0_.text as text0_, tbuser0_.user as user0_ from tb_user tbuser0_
14:14:51,562 INFO  [STDOUT] 我來測試一下 

 

後面我一個包一個包的測試,證實了之前帖子中說的,hibernate-annotations.jar這個包的問題。只要將這個包刪除就可以了。jboss4.2.2服務器就完全正常了。因爲後續功能還沒加上去,所以是否還缺少包我就不得而知了,只能一步一步來。希望我遇到的問題的解決方案,能夠幫到各位吧。如果有錯誤,也請提出來。謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章