Intellij下搭建maven+mybatis+springMVC项目(各种遇到的坑总结)

本文详细介绍了使用Spring MVC搭建Web项目的全过程,从配置文件详解到各层实现,辅以实战经验分享常见问题及解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面会按照我亲身搭建项目的过程一步步做介绍,唉,,,只能说基础不扎实,坑一个个的往下跳呀~~~

1、配置文件

对于用Intellij创建maven项目的操作此处不再一一介绍,直接跳到XML文件的配置。首先对项目的文件结构图做一个展示(不能说这是最标准的web项目文件结构,但也差不多~~)

这里写图片描述

(1)web.xml

可以说是web项目的根基文件,对spring mvc、spring的主配置文件、jsp展示首页等等进行了配置。具体代码如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

    <!--系统上下文配置  spring主配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 配置spring核心servlet -->
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
        <!-- load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法) -->
        <load-on-startup>1</load-on-startup>
    </servlet>


    <!-- url-pattern配置为斜杠,会造成其它静态文件(js,css等)不能访问。如配为*.do,则不影响静态文件的访问 -->
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- charactor encoding -->
    <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>


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

1、决定了spring mvc的配置文件名称,之后在resources中新建时一定要命名为xxx-servlet.xml
2、决定了可访问的文件格式,一般为“/”
3、spring的核心servlet—DispatcherServlet一定要配置。

该配置文件指定了两个需要配置的xml文件applicationContext.xml和xxx-servlet.xml,均放在resources文件目录下。

(2)applicationContext.xml

这是一个系统级别的配置文件,定义了注入bean的标准以及方式,还有一些数据库配置文件、mabatis、事务管理等等,相当的重要!!! 博主在这个文件上被坑的很惨~~~ 先上代码:

<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: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-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <!--支持注解-->
    <context:annotation-config/>

    <!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <!-- 采用注释的方式配置bean,当配置扫描包的时候,可以省去配置这个context:annotation-config -->
    <!--<context:annotation-config />-->
    <!-- 组件扫描 -->
    <context:component-scan base-package="com.hester.study"/>

    <bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/web/"></property> <!-- 视图文件的前缀 -->
        <property name="suffix" value=".jsp"></property> <!-- 视图文件的后缀名 -->
        <!-- view是用什么显示,这里是jsp,还可以用velocity之类的 -->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
    </bean>


    <!-- 加载数据库配置文件 -->
    <context:property-placeholder location="classpath:mydb.properties"/>
    <!-- 配置数据源,使用dbcp -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
    </bean>


    <!--Mybatis的SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="prototype">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:sqlMapConfig.xml"/>
    </bean>

    <!--&lt;!&ndash;sqlSessionTemplate&ndash;&gt;
     <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
         <constructor-arg index="0" ref="sqlSessionFactory"/>
     </bean>-->

    <!--事务管理-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    <!--basePackage 指定Spring自动扫描什么包;sqlSessionTemplateBeanName 指定spring中定义删去了Template的bean名称;
    annotationClass-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.hester.study"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="annotationClass" value="org.springframework.stereotype.Repository"/>
    </bean>
</beans>
坑点:

1、 组件扫描这里,由于一开始没有理解这里边参数的具体含义,有些bean一直提示无法注入,心累~~ 如果项目不是很大,建议还是不要写的很复杂,直接配置要扫描的根目录就好了,不要再去搞什么exclude-filter和include-filter,当然这个如果原理很懂得话,大神请随便玩~~
2、ViewResolver这个bean配置一下,后面与前台交互的时候用的上,里面的两个属性有注释,应该可以看懂!
3、数据库的配置,这边博主是另外写了一个properties(定义了一些常量,方便以后管理),然后导入到这里。
4、sqlSessionFactory的配置,这边注释掉了sqlSessionTemplate的配置了,因为后者会覆盖前者,这里面加了两个重要属性,一个是数据源,两一个是mabatis的配置(文件导入法)。

(3)spring-servlet.xml

主要代码:

<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-3.1.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.1.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射-->
    <!--<mvc:annotation-driven/>-->

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 启动包扫描功能,以便注册带有@Controller@service@repository@Component等注解的类成为spring的bean -->
    <context:component-scan base-package="com.hester.study.*"/>

    <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/web/"/>    <!-- 前缀 -->
        <property name="suffix" value=".jsp"/>    <!-- 后缀 -->
    </bean>
</beans>
坑点

1、这个文件的一些基本配置跟applicationContext.xml有点相似,有一点不同是加了一个,这是在前台调试的时候添上的,json无法转换,然后上网搜的说这样配置一下就可以,(可能还有其他解决方案)

(4)sqlMapConfig.xml

这个是mabatis的配置文件(必配)。代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "http://mabatis.org//DTD Config3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <!--这个配置使全局的映射器启用或禁用缓存-->
        <setting name="cacheEnabled" value="true"/>

        <!--允许JDBC 生成主键。需要驱动器支持。如果设为了true,
       这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。-->
        <setting name="useGeneratedKeys" value="true"/>

        <!--配置和设定执行器,
            SIMPLE 执行器执行其它语句;
            REUSE 执行器可能重复使用prepared statements 语句;
            BATCH 执行器可以重复执行语句和批量更新-->
        <setting name="defaultExecutorType" value="REUSE"/>

        <!--全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。-->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias alias="UserMapper" type="com.hester.study.entity.User"/>
    </typeAliases>

    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>
坑点

1、typeAliases类型别名,用alias的值来取代type中冗余的值。需要注意的时,一旦这样定义之后,后面对entity中的bean的引用都要用alias里定义的值来取代。(不要跳坑哦~~)
2、mappers映射器,指定了映射SQL 语句的文件。注意路径要写正确,不然会找不到的。

(5)UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "http://mabatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 1.命名空间是唯一的,根据你的Dao接口来定制的,Select标签的id对应方法名称-->
<mapper namespace="com.hester.study.dao.IUserDao">
    <select id="findById" parameterType="int" resultType="UserMapper">
        select id,username as name,age,address from "user" where id = #{id}
    </select>
</mapper>
坑点

1、注意看resultType,这边就是我们在mybatis配置文件中定义的alias值。
2、SQL语句要写对哦,看清大小写和引号。(不然坑的你自己都不认识~~~)

2、Dao层实现

这边博主只写了一个dao类的接口用于测试,代码如下:

package com.hester.study.dao;
import com.hester.study.entity.User;
import org.springframework.stereotype.Repository;
/**
 *Created By wangjie27
 *@Description:
 *@Date: Created in  2017/8/9  13:42
 */
@Repository
public interface IUserDao {
 public User findById(Integer id);
}
坑点

1、千万不要忘记在接口前面加@Repository注解,然后spring不会给你注入的。

3、services层实现

这边有两部分,分别是service接口和实现类。
services接口的定义:

package com.hester.study.services;
import com.hester.study.entity.User;
/**
 * @Author: wangjie27
 * @Description:
 * @Date: Created in  2017/8/9 13:48
 * @Modified By:
 */

public interface IUserServices {
   public  User getUserfindById(Integer id);
}

services实现类的定义:

package com.hester.study.services.impl;
import com.hester.study.dao.IUserDao;
import com.hester.study.entity.User;
import com.hester.study.services.IUserServices;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
 * @Author: wangjie27
 * @Description:
 * @Date: Created in  2017/8/9 13:50
 * @Modified By:
 */

@Service("UserServiceImpl")
public class UserServiceImpl implements IUserServices{
    @Resource
    private IUserDao userDao;
    public User getUserfindById(Integer id) {
        return userDao.findById(id);
    }
}

4、controller层

具体代码如下:

package com.hester.study.action;
import com.hester.study.entity.User;
import com.hester.study.services.IUserServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Author: wangjie27
 * @Description:
 * @Date: Created in  2017/8/10 19:34
 * @Modified By:
 */
@Controller
public class UserController {
    @Autowired
    private IUserServices userServices;
    {
        userServices = null;
    }

    public UserController() {
    }

    @RequestMapping(value="/test/{id}")
    @ResponseBody
    /**
    * @Author: wangjie27
    * @Description: url的访问路径为http://localhost:8090/test/XX
    * @Date:   15:19
    */
    public ModelAndView findUserById(@PathVariable("id") int id){
        User user=userServices.getUserfindById(id);
        ModelAndView mvc=new ModelAndView();
        mvc.setViewName("welcome");
        mvc.addObject("users",user);//方法一
       // mvc.getModel().put("users",user);方法二
        return  mvc;
    }


    @RequestMapping(value="/test")
    @ResponseBody
    /**
    * @Author: wangjie27
    * @Description:  url的访问路径为http://localhost:8090/test?id=XX
    * @Date:   15:18
    */
    public ModelAndView findUserById2(int id){
        User user=userServices.getUserfindById(id);
        ModelAndView mvc=new ModelAndView();
        mvc.setViewName("welcome");
        mvc.addObject("users",user);
        // mvc.getModel().put("users",user);
        return  mvc;
    }
}
坑点

1、这边要注意一些springmcv的注解书写形式,它决定了url访问路径的格式。@controller、@RequsetMapping、@pathVarible等的具体用法就不一一描述了。
2、对ModelAndView一些附带参数的绑定,包括view的设置,一些数据的携带。

5、jsp

<!--isELIgnored设定为真,那么JSP中的表达式被当成字符串处理,false则反之,表示支持EL-->
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
    <title>hester</title>
</head>
<body>
${requestScope.users}
<br/>
</body>
</html>
坑点

1、这边在写的时候,由于对EL表达式不太了解,在坑里待了很久,结果在网友帮助下,加了isELIgnored=”false” 这一句,使得jsp能够支持EL,读懂${}这种形式,而不再当做字符串。

终于get到点,成功调试出来了。
完整代码在此: https://github.com/HesterWj/newWord
博主是个小菜鸟,以上是艰辛的探索史,有些坑还是值得参考的,阅读愉快!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值