springmvc与mybatis整合中的问题

今天在整合SpringMvc+Mybatis时碰到一些问题,网上找了很多资料,一直未找到问题关键点,浪费了不少时间,先将主要碰到的问题与解决方法记录下来。

问题:bean实例化失败,编译启动时问题如下:

严重: Servlet.service() for servlet [springmvc] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException

即空指针问题。之前配置文件是这样的。

<?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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans.xsd  
                        http://www.springframework.org/schema/context  
                        http://www.springframework.org/schema/context/spring-context.xsd  
                        http://www.springframework.org/schema/mvc  
                        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd">
    <!-- 自动扫描 -->
    <context:component-scan base-package="cn.zsf.spring.springMaven" />
    <!-- 引入配置文件 -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties" />
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${jdbc.initialSize}" />
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${jdbc.maxActive}" />
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${jdbc.maxIdle}" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${jdbc.minIdle}" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${jdbc.maxWait}" />
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation"  value="classpath:sqlMapConfig.xml"/>
        <!-- 自动扫描mapping.xml文件,**表示迭代查找,也可在sqlMapConfig.xml中单独指定xml文件-->
        <property name="mapperLocations" value="classpath:cn/zsf/spring/springMaven/mapping/*.xml" />
    </bean>
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">  
    	<constructor-arg index="0" ref="sqlSessionFactory"/>  
	</bean> 

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

我在UserService中注入

package cn.zsf.spring.springMaven.service;

import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.zsf.spring.springMaven.dao.UserMapper;
import cn.zsf.spring.springMaven.pojo.User;

@Service
public class UserService {
    private static Logger logger = Logger.getLogger(UserService.class);
    
    @Autowired
    private SqlSessionTemplate sqlSession;
    
    @Autowired
    private UserMapper userMapper;
  
    
    public User get(int id){
        logger.info(sqlSession.toString());
        return  userMapper.selectByPrimaryKey(id);
    }
    
    public void setUserMapper(UserMapper userMapper){
        this.userMapper = userMapper;
    }
    
    public UserMapper getUserMapper(){
        return userMapper;
    }
    
    
}

在启动时就报错,sqlSession注入失败,userMapper也找不到可用的bean,错误信息为:

ERROR [web.context.ContextLoader] Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'homeController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.zsf.spring.springMaven.dao.UserMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)


造成sqlSession、userMapper都无法注入成功,原因是配置错误,未配置mybatis mapper接口,在spring-mybatis.xml中

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">  
    	<constructor-arg index="0" ref="sqlSessionFactory"/>  
	</bean> 
后面添加

<!-- 配置mybatis mapper接口 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.zsf.spring.springMaven.**.dao"/>
        <property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/>
    </bean>
即可;


另外碰到一个问题,错误提示信息

严重: Servlet.service() for servlet [springmvc] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
    at cn.zsf.spring.springMaven.service.UserService.get(UserService.java:46)

在HomeController中调用 userService.get(1)方法, 错误原因为:在我直接手动进行service初始化, UserService userService = new UserService();  这是一个低级错误,因UserService中有注入sqlsession和userMapper,并注册为Service,通过手动new的方式,是无法完成这两个属性的注入的,因此调用自然也就错误了。 其必须通过

@Autowired

private UserMapper userMapper

的方式进行注入引用。


这里附上其他的配置文件(可正常使用):

sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC  
    "-//mybatis.org//DTD Config 3.0//EN"  
    "http://mybatis.org/dtd/mybatis-3-config.dtd">  
<configuration>  
    <typeAliases>
        <typeAlias type="cn.zsf.spring.springMaven.pojo.User" alias="UserEntry" />
    </typeAliases>
</configuration>

applicationContent.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:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
   
   <!-- 此行语句使得resource autowired 等四个注解可以使用 -->
   <context:component-scan base-package="cn.zsf.spring.springMaven" /> 
   
   <!-- 配置读取外部配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    
    <context:annotation-config />
    
    <!-- 事务扫描开始(开启@Tranctional) -->
    <tx:annotation-driven transaction-manager="transactionManager" />
    
    
</beans>

spring-mvc.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:p="http://www.springframework.org/schema/p"    
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd    
http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"
default-lazy-init="true">

	<!-- 启动事务添加配置 -->
    <context:component-scan base-package="cn.zsf.spring.springMaven">  
        <!-- 排除扫描service标签 -->
        <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> --> 
    </context:component-scan>
    
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    	<property name="messageConverters">
    		<list>
    			<ref bean="mappingJacksonHttpMessageConverter"/>
    			<ref bean="utf8StringHttpMessageConverter" />
    		</list>
    	</property>
    </bean>
    
    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
        <property name="supportedMediaTypes">  
            <list>  
                <value>text/plain;charset=UTF-8</value>
                <value>text/html;charset=UTF-8</value>  
                <value>application/json;charset=UTF-8</value>
            </list>  
        </property>  
    </bean>  
    <bean id="utf8StringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/plain;charset=UTF-8</value>
                <value>text/html;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>
     
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
    
    <!-- 当配置了<mvc:annotation-driven/>后,会自动加载org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping和
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter,所以如果显示的配置则需去掉配置<mvc:annotation-driven/> -->
    <!--<mvc:annotation-driven/>-->
    

</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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_3_0.xsd">

  <display-name>Zsf Web Application</display-name>
 
  <!-- 配置web.xml,使其具有springmvc特性,主要配置两处,一个是ContextLoaderListener,一个是DispatcherServlet -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml,
        classpath*:spring-mybatis.xml,
        </param-value>
    </context-param>
    
    <!-- 配置ContextLoaderListener表示,该工程要以spring的方式启动。启动时会默认在/WEB-INF目录下查找applicationContext.xml
作为spring容器的配置文件,该文件里可以初始化一些bean -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- 字符集过滤器 -->  
    <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>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- spring mvc 配置 -->
    <!-- 配置DispatcherServlet表示,该工程将采用springmvc的方式。启动时也会默认在/WEB-INF目录下查找XXX-servlet.xml作为配置文件,
        XXX就是DispatcherServlet的名字,该文件中将配置两项重要的mvc特性:HandlerMapping,负责为DispatcherServlet这个前端控制器的请求查找Controller;
        ViewResolver,负责为DispatcherServlet查找ModelAndView的视图解析器。
        此处使用指定的配置文件spring-mvc.xml -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <!--<param-value>/WEB-INF/classes/spring-mvc-servlet.xml</param-value>-->
            <param-value>/WEB-INF/classes/spring-mvc.xml</param-value>
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
    </welcome-file-list>
    
    
</web-app>





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值