简介:这份源码资源面向Java Web初学者与需要巩固SSM整合流程的开发者,解决从零搭建Spring+SpringMVC+MyBatis项目时环境配置繁琐、依赖版本易冲突的问题。资源基于IDEA2021、Tomcat9.0与MySQL8.0.25环境整理,可直接导入运行,适合课程设计、毕业设计或自学练手场景。压缩包共105个文件,约22.34MB,其中52个jar包提供框架与数据库驱动依赖,28个xml文件承担Spring、SpringMVC及MyBatis的核心配置,另有java源码、jsp页面、properties配置与class编译文件,覆盖控制层、业务层、持久层及实体类的完整分层结构。目前已有3136人学习下载,说明其整合思路具备一定参考价值。读者可借此理清SSM各层职责划分、配置文件加载顺序与依赖注入关系,对照Book相关模块理解增删改查的调用链路,并掌握IDEA下Tomcat部署与MySQL连接的排错方法,为后续过渡到SpringBoot打下基础。
1. 零基础也能搭:SSM 框架到底是什么,为什么值得你花一个周末搞懂
如果你刚开始学 Java Web,大概率听过“SSM”这个词,然后被一堆缩写劝退。别慌,我第一次接触的时候也这样。你可以把 SSM 想象成开一家小餐馆:Spring 是店长,负责统筹所有人和事;Spring MVC 是前台,负责接待客人、把菜单传到后厨;MyBatis 是后厨的采购员,专门负责跟仓库(数据库)打交道。三个角色各司其职,合在一起就是一套能跑起来的 Web 应用骨架。这套源码就是带你从零把这三个角色请进 IDEA2021,一步步搭出一个能运行的完整项目。适合刚学完 Java 基础、想动手做一个真实 Web 项目的新手,不需要你懂框架原理,跟着敲就行。
2. 动手之前先想清楚:为什么新手要从 SSM 搭起
2.1 不搭一遍,你永远不知道 Web 项目怎么跑起来
很多新手学 Java 的路径是:语法 → 集合 → 多线程 → 然后直接跳到 Spring Boot。中间缺了一环——一个请求从浏览器发出,到数据库返回数据,再渲染成页面,这中间到底经过了哪些代码?SSM 搭建的过程,就是把这根链条一节一节接给你看。你会亲手配置 web.xml,知道 DispatcherServlet 是怎么接管请求的;你会写 spring-mybatis.xml,明白数据库连接池是怎么被注入的;你会写 Controller,看到 @RequestMapping 如何把 URL 映射到方法上。这些环节在 Spring Boot 里被自动配置藏起来了,新手直接上手容易一头雾水。先搭一遍 SSM,相当于把黑匣子拆开看了一遍,后面再用 Spring Boot 就是“哦,原来它帮我做了这些”。
2.2 面试和课程设计里,SSM 还是绕不开的硬通货
你去翻翻招聘要求,很多中小公司的 Java 岗位依然写着“熟悉 SSM 框架”。为什么?因为大量存量项目还在用这套组合,维护和二次开发都需要能看懂 XML 配置的人。另外,高校的课程设计、毕业设计里,SSM 出现的频率极高,因为它的结构清晰、分层明确,老师一眼就能看出你哪里写了业务逻辑、哪里写了数据库操作。你花一个周末把这份源码跑通,改一改,就能变成自己的课程设计底子。这不是让你停留在 SSM,而是用它当跳板——先能跑通一个完整项目,再去学 Spring Boot 的自动配置,你会比直接上手的人理解深得多。
2.3 这份源码解决的核心问题:把散落的知识点串成一条线
你单独学 Spring 的 IoC、单独学 MyBatis 的映射、单独学 Servlet 的请求处理,每个都懂一点,但合在一起就不知道怎么组织。这份源码的价值在于,它给了一个可运行的最小完整结构:pom.xml 里依赖怎么配、web.xml 里怎么注册前端控制器、applicationContext.xml 里怎么扫描包、mapper 文件放在哪里、jsp 页面怎么取数据。你照着搭一遍,这些零散的知识点就自动归位了。而且 IDEA2021 这个版本对新手比较友好,Maven 依赖下载和 Tomcat 配置都有图形化引导,不容易在环境上卡死。
3. 从零迈出第一步:环境准备和项目骨架搭建
3.1 先检查你电脑上有没有这三样东西
在打开 IDEA 之前,先确认三件事:JDK 版本、Maven 版本、Tomcat 版本。这份源码基于 JDK 8 或 JDK 11 都可以跑,建议用 JDK 8,因为很多老项目的依赖对高版本 JDK 兼容性不好。Maven 用 3.6 以上,IDEA2021 自带 Maven 也可以,但建议自己装一个独立版本,方便在命令行排查问题。Tomcat 用 8.5 或 9.0,不要用 Tomcat 10,因为 Tomcat 10 把 javax.servlet 包名改成了 jakarta.servlet,这份源码里的 web.xml 和依赖还是旧的命名空间,用 Tomcat 10 会直接报 404 或 ClassNotFound。
检查方法很简单,打开命令行输入:
java -version mvn -v如果 java -version 显示 1.8 开头,mvn -v 显示 3.6 以上,就基本没问题。Tomcat 不用命令行检查,后面在 IDEA 里配置时再选路径。
提示:如果你电脑上装了多个 JDK,一定要在 IDEA 的 Project Structure 里把 SDK 和 Language Level 都设成 8,否则编译时可能报“无效的目标发行版”。
3.2 用 IDEA2021 新建 Maven Web 项目
打开 IDEA2021,点击 File → New → Project,左侧选 Maven,勾选“Create from archetype”,然后选org.apache.maven.archetypes:maven-archetype-webapp。这个模板会自动生成 webapp 目录和 web.xml,省得你手动建。填好 GroupId 和 ArtifactId,比如com.example和ssm-demo,一路 Next 到 Finish。
建好之后,你会看到项目结构里有一个 src/main/webapp 目录,里面有个 index.jsp 和 WEB-INF/web.xml。这时候项目还不能跑,因为缺 Java 源码目录。右键 src/main,新建 Directory,命名为 java,然后右键这个 java 目录,Mark Directory as → Sources Root。同样,在 src/main 下新建 resources 目录,Mark Directory as → Resources Root。这两个目录分别放 Java 代码和配置文件,是 Maven 的标准结构,新手容易漏掉 resources 目录,导致配置文件放错位置。
3.3 在 pom.xml 里补上 SSM 需要的依赖
打开 pom.xml,在<dependencies>标签里加入 Spring、Spring MVC、MyBatis、数据库驱动、连接池、JSTL 等依赖。这里给一个最小可用的依赖清单,版本号用稳定的,不要追最新:
<dependencies> <!-- Spring 核心 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.20</version> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.20</version> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <!-- MyBatis 与 Spring 整合 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency> <!-- 数据库驱动,这里以 MySQL 为例 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.9</version> </dependency> <!-- JSTL 用于 JSP 页面 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Servlet API,作用域 provided --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies>加完之后点一下 IDEA 右上角的 Maven 刷新按钮,等依赖下载完。如果下载慢,可以在 Maven 的 settings.xml 里配一个国内镜像,这里不展开。依赖报红是新手最常见的问题,先检查 Maven 仓库路径和网络,再检查版本号是否写错。
注意:
javax.servlet-api的 scope 必须是 provided,因为 Tomcat 运行时自带这个包,如果你打成 compile 会导致冲突。
4. 把三层配置串起来:Spring、Spring MVC、MyBatis 各管什么
4.1 web.xml:整个 Web 项目的入口
web.xml 放在 src/main/webapp/WEB-INF 下,它是 Servlet 容器的配置文件。SSM 项目里,web.xml 主要做两件事:注册 Spring 的 ContextLoaderListener,让 Spring 容器在 Web 应用启动时加载;注册 Spring MVC 的 DispatcherServlet,让它拦截所有请求。代码如下:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.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 MVC 前端控制器 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 字符编码过滤器,防止中文乱码 --> <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> </web-app>这里的关键是contextConfigLocation指向的配置文件路径。classpath:表示从 resources 目录下找。ContextLoaderListener 加载的是父容器,通常放 Service 和 Dao 的配置;DispatcherServlet 加载的是子容器,放 Controller 和视图解析器。两个容器是父子关系,子容器能访问父容器的 Bean,反过来不行。新手容易把两者搞混,导致 Controller 里注入 Service 失败。
4.2 applicationContext.xml:Spring 管 Service 和 Dao
在 src/main/resources 下新建 applicationContext.xml,内容如下:
<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" 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"> <!-- 扫描 Service 层 --> <context:component-scan base-package="com.example.service"/> <!-- 加载数据库配置 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!-- 扫描 Mapper 接口 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.mapper"/> </bean> <!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> </beans>这段配置做了四件事:扫描 Service 包、读取数据库属性文件、创建 Druid 连接池、配置 MyBatis 的 SqlSessionFactory 和 Mapper 扫描。mapperLocations指向 resources/mapper 目录下的 XML 映射文件,basePackage指向 Mapper 接口所在的包。新手常犯的错误是包名写错,比如 Service 实际在com.example.service.impl下,但只扫描了com.example.service,导致 Bean 找不到。
4.3 spring-mvc.xml:Spring MVC 管 Controller 和视图
在 src/main/resources 下新建 spring-mvc.xml:
<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: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"> <!-- 只扫描 Controller --> <context:component-scan base-package="com.example.controller"/> <!-- 开启注解驱动 --> <mvc:annotation-driven/> <!-- 静态资源放行 --> <mvc:default-servlet-handler/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>component-scan只扫描 Controller 包,不要把 Service 也扫进来,否则事务配置可能不生效。mvc:annotation-driven注册了处理 JSON、格式化日期等功能的默认组件。default-servlet-handler让静态资源(css、js、图片)不被 DispatcherServlet 拦截。视图解析器的 prefix 和 suffix 决定了 Controller 返回的字符串对应哪个 JSP 文件,比如返回"index"就会找/WEB-INF/jsp/index.jsp。
4.4 db.properties 和 MyBatis 映射文件
在 resources 下新建 db.properties:
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm_demo?useSSL=false&serverTimezone=UTC&characterEncoding=utf8 jdbc.username=root jdbc.password=你的密码注意 MySQL 8 的驱动类是com.mysql.cj.jdbc.Driver,不是旧的com.mysql.jdbc.Driver。URL 里加上serverTimezone和characterEncoding,否则可能报时区错误或中文乱码。
然后在 resources 下新建 mapper 目录,放一个 UserMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.UserMapper"> <select id="selectAll" resultType="com.example.entity.User"> SELECT * FROM user </select> </mapper>对应的 Mapper 接口放在com.example.mapper包下:
package com.example.mapper; import com.example.entity.User; import java.util.List; public interface UserMapper { List<User> selectAll(); }Service 层调用 Mapper,Controller 调用 Service,这样三层就串起来了。新手写的时候注意 namespace 必须和接口全限定名一致,id 必须和方法名一致,否则启动时报“Invalid bound statement”。
5. 避坑指南:新手搭建 SSM 最容易翻车的五个地方
5.1 启动报 404,所有页面都找不到
现象:Tomcat 启动没报错,但访问任何 URL 都是 404。 原因:DispatcherServlet 的 url-pattern 配成了/*而不是/。/*会拦截 JSP 请求,导致 JSP 也被当成 Controller 处理。 解决:把 web.xml 里的<url-pattern>/*</url-pattern>改成<url-pattern>/</url-pattern>。另外检查 Tomcat 的 Application context 是否设成了/,如果设成了/ssm_demo,访问时要加前缀。
5.2 注入失败,报 NoSuchBeanDefinitionException
现象:启动时提示找不到某个 Service 或 Mapper Bean。 原因:包扫描路径没覆盖到,或者 Mapper 接口没有和 XML 映射文件对应上。 解决:检查 applicationContext.xml 里的base-package是否包含了 Service 实现类所在的包;检查 MapperScannerConfigurer 的basePackage是否包含了 Mapper 接口所在的包;检查 mapperLocations 的路径是否匹配 XML 文件的实际位置。
5.3 中文乱码,页面显示问号
现象:表单提交的中文在数据库里变成乱码,或者页面显示乱码。 原因:字符编码过滤器没配,或者数据库连接 URL 没加 characterEncoding。 解决:web.xml 里加上 CharacterEncodingFilter,并设置 encoding 为 UTF-8;db.properties 的 URL 里加上characterEncoding=utf8;JSP 页面顶部加上<%@ page contentType="text/html;charset=UTF-8" language="java" %>。
5.4 事务不生效,插入数据后回滚失败
现象:Service 方法抛异常,但数据库里的数据没有回滚。 原因:Spring 的事务管理默认只对 RuntimeException 回滚,如果抛的是 checked exception,不会回滚;另外如果 Service 类没有被 Spring 代理,事务也不会生效。 解决:在 Service 类或方法上加@Transactional(rollbackFor = Exception.class);确保 Service 类被 Spring 扫描到,并且是通过接口注入的(JDK 动态代理)或者开启了 CGLIB 代理。
5.5 Tomcat 启动慢或报内存溢出
现象:Tomcat 启动要很久,或者直接报 OutOfMemoryError。 原因:Maven 依赖重复或冲突,或者 Tomcat 的 JVM 内存设置太小。 解决:在 pom.xml 里用mvn dependency:tree检查冲突,排除重复依赖;在 IDEA 的 Tomcat 配置里,VM options 加上-Xms512m -Xmx1024m;如果项目不大,检查是不是引入了不必要的依赖。
6. 跑通之后下一步学什么:从 SSM 到能写自己的业务
6.1 先把这个 Demo 改成你自己的小项目
跑通源码之后,不要急着学新框架。先做一件事:把表结构改掉,换成你自己想做的业务。比如把 user 表改成 book 表,字段改成书名、作者、价格,然后改 Mapper XML、Service、Controller 和 JSP。这一步的目的是让你体验“改一处、动全身”的感觉,理解分层的意义。我第一次改的时候,忘了改 Mapper 的 namespace,启动直接报错,找了半小时才发现。从那以后我每次改包名或类名,都强制走一遍“接口 → XML → Service → Controller → JSP”的检查链。
6.2 补上前端和 RESTful 接口的缺口
SSM 原生的 Controller 返回 JSP 页面,但现在更多场景是前后端分离,Controller 返回 JSON。你可以在现有项目里加一个@ResponseBody的方法,返回Map或实体类,然后用浏览器或 Postman 访问,看能不能拿到 JSON。这一步会逼你理解mvc:annotation-driven背后的消息转换器是怎么工作的。如果返回 JSON 时报 406,通常是缺少 Jackson 依赖,在 pom.xml 里加上jackson-databind即可。
6.3 用 Spring Boot 重写一遍,对比差异
当你对 SSM 的配置流程熟悉之后,用 Spring Boot 重写同一个业务。你会发现:web.xml 没了,取而代之的是@SpringBootApplication;applicationContext.xml 没了,取而代之的是@Configuration和@Bean;MyBatis 的配置变成了application.yml里的几行。这时候你就能真正理解 Spring Boot 的“约定优于配置”到底省了什么。下面是一个 Spring Boot 整合 MyBatis 的最小配置示例,你可以对照 SSM 的 XML 看:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ssm_demo?useSSL=false&serverTimezone=UTC username: root password: 你的密码 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity同样的功能,SSM 需要三个 XML 文件加一个 web.xml,Spring Boot 只需要一个 yml。不是 Spring Boot 更“高级”,而是它把配置自动化了。你先手写一遍 SSM,再用 Spring Boot,就不会被自动配置搞晕。
6.4 学习路径建议:按这个顺序走,不容易断档
如果你现在刚跑通 SSM,接下来的学习顺序建议是:先补 SQL 和数据库设计,因为业务逻辑最终都落在表结构上;然后学 Maven 的依赖管理和多模块,因为真实项目不会只有一个模块;接着学 Spring Boot 的自动配置原理,但不要一上来就啃源码,先看官方文档的“How it works”章节;最后学 Spring Security 或 Shiro 做权限,以及 Redis 做缓存。每一步都拿一个具体的小功能练手,比如用户登录、商品列表、订单提交。不要只看视频不动手,SSM 这种配置类的东西,看十遍不如自己搭一遍。
提示:如果你在搭建过程中遇到版本冲突,优先检查 JDK 版本和 Tomcat 版本,这两个是新手翻车最多的地方。
希望帮到你。
本文还有配套的精品资源,点击获取