刚刚开始学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>

到这里,我的网站框架搭建完成了,碰到的错误也解决了,这些都写下来,算是一份笔记吧。希望大家能看到后避免和我发生同样的错误。

初学springMVC搭建框架过程及碰到的问题的更多相关文章

  1. 【SpringMVC】SpringMVC搭建框架

    开发环境 IDE:idea 2019.3.2 构建工具:maven3.5.4 服务器:tomcat 9.0.30 Spring版本:5.3.1 创建maven工程 添加打包方式:war 引入依赖 &l ...

  2. springMVC,spring,mybatis全注解搭建框架--第一步,让框架跑起来

    自己从事java开发工作也有一年多了,自己却没有亲手搭建一个完整的框架.于是今天自己动手搭建一个,过程中遇到一些问题,倒腾了大半天终于搞定了. 现在给大家分享一下过程,自己也记录下来,以后学习参考使用 ...

  3. SSM(Spring +SpringMVC + Mybatis)框架搭建

    SSM(Spring +SpringMVC + Mybatis)框架的搭建 最近通过学习别人博客发表的SSM搭建Demo,尝试去搭建一个简单的SSMDemo---实现的功能是对用户增删改查的操作 参考 ...

  4. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)

    1. 前言 最近在写毕设过程中,重新梳理了一遍SSM框架,特此记录一下. 附上源码:https://gitee.com/niceyoo/jeenotes-ssm 2. 概述 在写代码之前我们先了解一下 ...

  5. 新手搭建springmvc+mybits框架的经验分享

    1.搭建过程中遇到的问题: ①由于是第一次使用springmvc框架,对它的认识真的很浅,只知道他属于spring旗下的产品,仅此而已.于是搭建过程中确实遇到不少麻烦,因为之前的项目都是老师带着做的, ...

  6. Spring+SpringMvc+Mybatis框架集成搭建教程

    一.背景 最近有很多同学由于没有过SSM(Spring+SpringMvc+Mybatis , 以下简称SSM)框架的搭建的经历,所以在自己搭建SSM框架集成的时候,出现了这样或者那样的问题,很是苦恼 ...

  7. 使用intellij idea搭建MAVEN+springmvc+mybatis框架

    原文:使用intellij idea搭建MAVEN+springmvc+mybatis框架 1.首先使用idea创建一个maven项目 2.接着配置pom.xml,以下为我的配置 <projec ...

  8. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建四:配置springmvc

    在用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试的基础上 继续进行springmvc的配置 一:配置完善web.xml文件

  9. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试

    这一部分的主要目的是 配置spring-service.xml  也就是配置spring  并测试service层 是否配置成功 用IntelliJ IDEA 开发Spring+SpringMVC+M ...

随机推荐

  1. cocos2d_android 瞬间动作

    该文章所写的瞬间动作主要有CCFlipX,CCFlipY,CCHide,CCShow 当中CCFlipX是以Y轴为中心旋转,CCFlipY是以X轴为中心旋转,CCHide将精灵对象隐藏,CCShow将 ...

  2. 依赖注入及AOP简述(九)——单例和无状态Scope .

    三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依 ...

  3. 在 Parallels Desktop 中,全屏模式使用 Win7,唤醒时黑屏

    在Parallels Desktop中,全屏模式下使用Win7,如果Mac电脑自动休眠了,则无法再次唤醒了,唤醒时黑屏. 博主的Mac是2014款MBPR,键盘上所有的键都试过,还是无法唤醒电脑,每次 ...

  4. Android 常用 adb 命令总结

    Android 常用 adb 命令总结 针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命 ...

  5. jQuery ZeroClipboard中Flash定位不准确的解决方案

    转自波斯马,原文地址<jQuery ZeroClipboard中Flash定位不准确的解决方案> jQuery ZeroClipboard支持在多种浏览器中复制内容到剪贴板,IE.Fire ...

  6. python基础之python中if __name__ == '__main__': 的解析

    当你打开一个.py文件时,经常会在代码的最下面看到if __name__ == '__main__':,现在就来介 绍一下它的作用. 模块是对象,并且所有的模块都有一个内置属性 __name__.一个 ...

  7. (转)python struct简介

    最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结. 了解c语言 ...

  8. Inno Setup教程

    一.简介 Inno Setup是一款免费的安装制作软件,小巧.简便.精美是其最大特点,支持pascal脚本,能快速制作出标准Windows2000风格的安装界面,足以完成一般安装任务.该软件用Delp ...

  9. Scala基础入门-代码碎片

    import scala.util.control._ import java.util.Date object Test { def main(args: Array[String]) { // v ...

  10. 001OC的结构解析

    Xcode通过.m扩展名来表示文件使用的是OC代码,C编译器处理.c文件,c++编译器处理cpp文件.所有编译工作默认由LLVM处理,这个编译器能够理解C语言的全部3个变体. #import<F ...