您的位置:首页 > 编程语言 > Java开发

初学springMVC搭建框架过程及碰到的问题

2016-07-24 14:22 288 查看
  刚刚开始学spring框架,因为接了一个网站的项目,想用spring+springMVC+hibernate整合来实现它,现在写下搭建框架的过程及碰到的问题。希望给自己看到也能让大家看到不要踏坑。

一、创建Maven项目

  我选用的IDE是Intellij idea2016.2 Ultimate,使用的Maven来创建web项目,这样可以省去很多我自己找依赖包下载的时间,因为Maven有中央仓库统一管理可以通过配置pom.xml文件到Maven仓库上去获取需要的包,点击File->New project,在左边栏选择Maven,如图所示:


点Next,如图所示:



GroupId和Artifactid和version都是项目的唯一标识,接下来就一路next,选择项目的路径点Finish,等待创建好项目后会多出两个文件夹和web.xml文件,先不去管它,因为是springmvc项目,数据持久化用的是hibernate,所以要引入spring和springMVC还有hibernate的相关包文件,最终的pom.xml文件是这样的:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.springapp</groupId>
<artifactId>intepop</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>intepop Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.1.1.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- http://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>

<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.10.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
</dependencies>
<build>
<finalName>intepop</finalName>
</build>
</project>


用到了mysql数据库,所以还添加了mysql的驱动。

好了,包都引入了,接下来开始配置spring以及hibernate

二、创建MVC目录结构

  MVC结构有Model,View,Controller三个部分组成,Model是一些基本的Java Bean,也就是POJO类,View一般为jsp页面,Controller用来处理网站的请求。首先在project structure中选择Modules,在main文件夹下新建一个文件夹名叫java,点击Make as Sources,用来保存java代码。

接下来在java文件夹下创建controller的包,名为DesignerUserController,然后创建进行数据库操作的接口IUserDao,服务接口IUserManager,以及他们的实现类UserDao,UserManager,创建完成后的目录结构如下:



PS:UserManager类其实应该放到serviceImpl文件夹下

目录结构创建好之后,开始配置spring的配置文件。

三、配置spring和Hibernate

  在WEB-INF目录下右键选择NEW->XML configure File->Spring Config,取名为mvc-dispatcher-servlet,新建后,点击右上角configure,setup frameworks,点OK,这样,IDE就识别XML文件为springMVC的配置文件。在配置文件中,首先要开启的是springmvc对静态资源的访问

<!--开启静态资源访问-->
<mvc:default-servlet-handler/>


  接下来是要开启springMVC的注解功能,因为在spring中我们使用注解的方法来进行相关定义,可以省去很多的配置,但是这个注解也让我绕了一些弯路,这个等下会说到。

<!--开启注解-->
<mvc:annotation-driven/>
<context:annotation-config />


  然后是配置<context:component-scan>标签,这个标签的作用是spring可以自动去扫描base-pack下面或者子包下面的Java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean,我就直接配置了所有的包让它扫描注解创建bean,所以我的是这样的:

<context:component-scan base-package="com.springapp.*"/>


  最后配置springMVC的视图解析器,视图解析器的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,它是这么配置的:

<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>


前缀表示这些视图是在哪个文件夹下,后缀表示解析器要将这些视图渲染成的格式。

整体的xml文件就是这样:

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启静态资源访问--> <mvc:default-servlet-handler/>
<!--开启注解--> <mvc:annotation-driven/> <context:annotation-config />
<!--指定controller所在包并扫描注解-->
<context:component-scan base-package="com.springapp.*"/>

<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>


  接下来,我们要配置数据源,sessionFactory以及事务:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--给userDao的实现类提供注入的sessionFactory对象-->
<bean id="userDaoImpl" class="com.springapp.daoImpl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://×××××××××××××××××××××××××××××××××××××××××:3306/designerdb?useUnicode=true"/>
<property name="username" value="intepop"/>
<property name="password" value="INTEpop2016"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<!-- 可以加多个包 -->
<value>com.springapp.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.connection.url">
jdbc:mysql://××××××××××××××××××××××××××××:3306/designerdb
</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
</props>
</property>
</bean>
<!--spring的事务管理器,用它来管理hibernate的session-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--设置事务的属性,延迟加载,事务的传播特性-->
<bean id="transactionBase" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
lazy-init="true" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="modify*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="get*">PROPAGATION_NEVER</prop>
</props>
</property>
</bean>
<!--处理异常-->
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>


  最后,我们来配置web.xml文件,首先加入一个servlet名叫mvc-dispatcher(名字可以随便修改),url-pattern为/,表示拦截所有请求,并交给springMVC的后台控制器来管理。

<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>


  然后为了能处理中文请求和乱码问题,需要加入一个encodingFilter

<filter>
<filter-name>encodingFilter</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


  到这里,spring和hibernate的配置算是结束了,接下来就是编写代码。

四、编写代码

Service层:

IUserManager

package com.springapp.service;

import com.springapp.model.UserinfoEntity;

import java.util.List;

/**
* Created by Wwei5 on 2016/7/18.
*/
public interface IUserManager {
void registerDesigner(UserinfoEntity user);
List<UserinfoEntity> getAllDesigner();
UserinfoEntity getDesigner(String id);
boolean updateDesigner(UserinfoEntity user);
}


UserManager

package com.springapp.service;

import com.springapp.dao.IUserDao;
import com.springapp.model.UserinfoEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
* Created by Wwei5 on 2016/7/18.
*/
@Service
@Transactional
public class UserManager implements IUserManager{
@Autowired
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
private IUserDao userDao;

public void registerDesigner(UserinfoEntity user) {
userDao.registerDesigner(user);
}

public List<UserinfoEntity> getAllDesigner() {
return userDao.getAllDesigner();
}

public UserinfoEntity getDesigner(String id) {
return userDao.getDesigner(id);
}

public boolean updateDesigner(UserinfoEntity user) {
return userDao.updateDesigner(user);
}
}


Dao层:

IUserDao

package com.springapp.dao;

import com.springapp.model.UserinfoEntity;

import java.util.List;

/**
* Created by Wwei5 on 2016/7/18.
*/
public interface IUserDao {
void registerDesigner(UserinfoEntity user);
List<UserinfoEntity> getAllDesigner();
UserinfoEntity getDesigner(String id);
boolean updateDesigner(UserinfoEntity user);
}


DaoImpl:

package com.springapp.daoImpl;

import com.springapp.dao.IUserDao;
import com.springapp.model.UserinfoEntity;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* Created by Wwei5 on 2016/7/18.
*/
@Service
@Transactional
public class UserDaoImpl implements IUserDao {

public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Autowired(required = false)
private SessionFactory sessionFactory;
public Session getSession(){
return sessionFactory.getCurrentSession();
}
public void registerDesigner(UserinfoEntity user) {
getSession().save(user);
sessionFactory.getCurrentSession().getTransaction().commit();
}

public List<UserinfoEntity> getAllDesigner() {
String hql="from userinfo";
Query query=sessionFactory.getCurrentSession().createQuery(hql);
return query.list();
}

public UserinfoEntity getDesigner(String id) {
String hql="from userinfo u where u.userid=?";
Query query=sessionFactory.getCurrentSession().createQuery(hql);
query.setString(0,id);
return (UserinfoEntity)query.uniqueResult();
}

public boolean updateDesigner(UserinfoEntity user) {
return false;
}
}


Model:

package com.springapp.model;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

/**
* Created by Wwei5 on 2016/7/18.
*/
@Entity
@Table(name = "userinfo", schema = "designerdb", catalog = "")
public class UserinfoEntity {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(length=32,nullable = false)
private String userid;
@Column(length=25)
private String username;
@Column(length=25)
private String password;
@Column(length=25)
private String realname;
@Column(length=2)
private String sex;
@Column(length=3)
private Integer age;
@Column(length=18)
private String idnumber;
@Column(length=11)
private String telephone;
@Column(length=100)
private String emailAddress;
@Column(length=25)
private String phone;
@Column(length=100)
private String workPlace;
@Column(length=500)
private String workExperience;
@Column(length=1000)
private String address;
@Column(length=100)
private String graduateSchool;
@Column(length=200)
private String awardedInfo;
@Column(length=100)
private String seniority;
@Column(length=100)
private String industry;
@Column(length=500)
private String district;

@Id
@Column(name = "userid")
public String getUserid() {
return userid;
}

public void setUserid(String userid) {
this.userid = userid;
}

@Basic
@Column(name = "username")
public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

@Basic
@Column(name = "password")
public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Basic
@Column(name = "realname")
public String getRealname() {
return realname;
}

public void setRealname(String realname) {
this.realname = realname;
}

@Basic
@Column(name = "sex")
public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

@Basic
@Column(name = "age")
public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

@Basic
@Column(name = "idnumber")
public String getIdnumber() {
return idnumber;
}

public void setIdnumber(String idnumber) {
this.idnumber = idnumber;
}

@Basic
@Column(name = "telephone")
public String getTelephone() {
return telephone;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

@Basic
@Column(name = "emailAddress")
public String getEmailAddress() {
return emailAddress;
}

public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}

@Basic
@Column(name = "phone")
public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

@Basic
@Column(name = "workPlace")
public String getWorkPlace() {
return workPlace;
}

public void setWorkPlace(String workPlace) {
this.workPlace = workPlace;
}

@Basic
@Column(name = "workExperience")
public String getWorkExperience() {
return workExperience;
}

public void setWorkExperience(String workExperience) {
this.workExperience = workExperience;
}

@Basic
@Column(name = "address")
public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Basic
@Column(name = "graduateSchool")
public String getGraduateSchool() {
return graduateSchool;
}

public void setGraduateSchool(String graduateSchool) {
this.graduateSchool = graduateSchool;
}

@Basic
@Column(name = "awardedInfo")
public String getAwardedInfo() {
return awardedInfo;
}

public void setAwardedInfo(String awardedInfo) {
this.awardedInfo = awardedInfo;
}

@Basic
@Column(name = "seniority")
public String getSeniority() {
return seniority;
}

public void setSeniority(String seniority) {
this.seniority = seniority;
}

@Basic
@Column(name = "industry")
public String getIndustry() {
return industry;
}

public void setIndustry(String industry) {
this.industry = industry;
}

@Basic
@Column(name = "district")
public String getDistrict() {
return district;
}

public void setDistrict(String district) {
this.district = district;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UserinfoEntity that = (UserinfoEntity) o;

if (userid != null ? !userid.equals(that.userid) : that.userid != null) return false;
if (username != null ? !username.equals(that.username) : that.username != null) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
if (realname != null ? !realname.equals(that.realname) : that.realname != null) return false;
if (sex != null ? !sex.equals(that.sex) : that.sex != null) return false;
if (age != null ? !age.equals(that.age) : that.age != null) return false;
if (idnumber != null ? !idnumber.equals(that.idnumber) : that.idnumber != null) return false;
if (telephone != null ? !telephone.equals(that.telephone) : that.telephone != null) return false;
if (emailAddress != null ? !emailAddress.equals(that.emailAddress) : that.emailAddress != null) return false;
if (phone != null ? !phone.equals(that.phone) : that.phone != null) return false;
if (workPlace != null ? !workPlace.equals(that.workPlace) : that.workPlace != null) return false;
if (workExperience != null ? !workExperience.equals(that.workExperience) : that.workExperience != null)
return false;
if (address != null ? !address.equals(that.address) : that.address != null) return false;
if (graduateSchool != null ? !graduateSchool.equals(that.graduateSchool) : that.graduateSchool != null)
return false;
if (awardedInfo != null ? !awardedInfo.equals(that.awardedInfo) : that.awardedInfo != null) return false;
if (seniority != null ? !seniority.equals(that.seniority) : that.seniority != null) return false;
if (industry != null ? !industry.equals(that.industry) : that.industry != null) return false;
if (district != null ? !district.equals(that.district) : that.district != null) return false;

return true;
}

@Override
public int hashCode() {
int result = userid != null ? userid.hashCode() : 0;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + (realname != null ? realname.hashCode() : 0);
result = 31 * result + (sex != null ? sex.hashCode() : 0);
result = 31 * result + (age != null ? age.hashCode() : 0);
result = 31 * result + (idnumber != null ? idnumber.hashCode() : 0);
result = 31 * result + (telephone != null ? telephone.hashCode() : 0);
result = 31 * result + (emailAddress != null ? emailAddress.hashCode() : 0);
result = 31 * result + (phone != null ? phone.hashCode() : 0);
result = 31 * result + (workPlace != null ? workPlace.hashCode() : 0);
result = 31 * result + (workExperience != null ? workExperience.hashCode() : 0);
result = 31 * result + (address != null ? address.hashCode() : 0);
result = 31 * result + (graduateSchool != null ? graduateSchool.hashCode() : 0);
result = 31 * result + (awardedInfo != null ? awardedInfo.hashCode() : 0);
result = 31 * result + (seniority != null ? seniority.hashCode() : 0);
result = 31 * result + (industry != null ? industry.hashCode() : 0);
result = 31 * result + (district != null ? district.hashCode() : 0);
return result;
}
}


到了这一步,我开始碰到问题了,我现在贴出来的代码都是我改动好之后的了,在一开始我的报错是这样的

root cause

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.springapp.service.IUserManager com.springapp.controller.HomeController.userManager; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userManager': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.springapp.service.UserManager.setUserDao(com.springapp.dao.IUserDao); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'IUserDao': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.springapp.daoImpl.UserDaoImpl.setSessionFactory(org.hibernate.SessionFactory); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:629)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:677)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:548)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2508)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2497)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:722)


经过一番改动后,这个错不再报了,但是sessionFactory自动注入失败,值为null,于是我查了好多的资料,最后找到了解决的办法,我原来有一个hibernate-beans文件,用来配置类的bean,但是其实有了@Service注解之后,spring是会自动扫描组件的,所以我把那个文件删了,没有贴出来。第二点,我原来在hibernateProperties的props里没有加数据库方言,现在我给加上了。这个问题最重要的一点也是我在搭建框架的时候忽略的一点,就是在web.xml里一定要加上listener,ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。所以我在web.xml里加入了

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-import.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


到此,sessionFactory不再为null,但是当我调用getCurrentSession().save()方法保存数据到数据库的时候又出现了新的问题,No Hibernate Session bound to thread, and configuration does not allow和No CurrentSessionContext configured!错。这两个问题是因为hibernate交给了spring管理,在调用getCurrentSession的时候需要把session绑定到当前线程上,这个时候就要在hibernate的配置文件中的hibernateProperties中添加

<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>


从spring3.1开始,SessionFactory.getCurrentSession()的后台实现是可拔插的。因此,引入了新的扩展接口 (org.hibernate.context.CurrentSessionContext)和新的配置参数 (hibernate.current_session_context_class),以便对什么是“当前session”的范围和上下文 (scopeand context)的定义进行拔插。

因为getCurrentSession和openSession方法是有不同的,采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()创建的session则不会。采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()创建 的session必须手动关闭。sessionFactory.getCurrentSession()可以完成一系列的工作,当调用时,hibernate将session绑定到当前线程,事务结束后,hibernate将session从当前线程中释放,并且关闭session。当再次调用getCurrentSession()时,将得到一个新的session,并重新开始这一系列工作。

还有一个问题,spring为我们解决hibernate的Session的关闭与开启问题。

Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Session 范围之内进行。如果 Service 层返回一个启用了延迟加载功能的领域对象给 Web 层,当 Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的 Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常。

用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象。

而Spring为我们提供的OpenSessionInViewFilter过滤器为我们很好的解决了这个问题。OpenSessionInViewFilter的主要功能是用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象。

OpenSessionInViewFilter 过滤器将 Hibernate Session 绑定到请求线程中,它将自动被 Spring 的事务管理器探测到。所以 OpenSessionInViewFilter 适用于 Service 层使用HibernateTransactionManager 或 JtaTransactionManager 进行事务管理的环境,也可以用于非事务只读的数据操作中。

所以,需要在web.xml中加入一个filter

<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


到这里,我的网站框架搭建完成了,碰到的错误也解决了,这些都写下来,算是一份笔记吧。希望大家能看到后避免和我发生同样的错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: