Spring+SpringMVC+MyBatis 整合(+拦截器) 详:

发布时间:2026/11/6 9:36:23
Spring+SpringMVC+MyBatis 整合(+拦截器) 详:

Spring+SpringMVC+MyBatis 整合(+拦截器) 详:

目前为止博客基本已将掌握SpringMVC 相关的知识点;
终于来到了最终时刻 SSM 三大框架整合;

搭建SSM 框架的程序架构

SSM 框架整合其实就是:Mybatis + Spring + SpringMVC 的整合;
前面学习我们知道 :
Mybatis : 是一个ORM 数据持久层框架;
SpringMVC : 是一个优秀的 Web框架
它们是一个独立的框架, 而Spring框架提供 Ioc 和 Aop 相当适用的功能;
-------可以将 Mybatis 和 SpringMVC 操作对象交给Spring容器进行解耦管理, 大大增强系统灵活性,便于功能扩展
-------还能通过Spring 提供服务简化编码, 减少开发工作量…提高开发效率.
------- 对于SpringMVC 来说它本来就是 Spring的一部分可以说整合过程就是:“无缝连接~性能卓越”

开始SSM 整合:

1. 新建一个 Web.Project 工程,并导入相关的 Jar

2. 数据库模型对象:

就是实体类:一般我喜欢在src下建一个包:com.wsm.entity包; 存放所有实体类;

3.系统工具:

系统工具就是一般会定义一个包: 存储一些常用的类 方法之类似于工具一样的。随时用随时掉~ Page 泛型分页类~

4. Dao数据访问接口:

Dao 数据持久层, 进行数据操作的…
一般我在src下建一个包:com.wsm.Dao包; 存放所有Dao接口类;每个类型接口描述每一种类型的操作~
applicationContext-mybatis.xml 配置文件 扫描包com.wsm.Dao包实现包所有接口…完成数据库持久化操作~

5. service 业务逻辑层:

看到这儿是不是就眼熟了:service——Dao——entity 很想以前写的经典的三层架构; (不了解记不清也没关系…)
业务逻辑层:

前端控制器接收——客户端请求——内部存储Service类对象, 调用对应方法将参数传给 Service
Service业务逻辑层将数据封装处理后——通过Dao实例——调用Dao的方法实现数据库操作
并接收Dao的返回结果——返回值控制器——Model——在到浏览器客户端展示…

总而言之就是, Service 中存在Dao实例, 对前端参数处理给Dao 接收Dao返回结果, 在返回值控制器——页面输出;
详情可结合之前的实例代码:
MyBatis和Spring整合详解:
SpringMVC体系结构
请结合看虽然是分开的并且的控制器输出不过…就这样吧

6. 配置文件:

SSM框架需要两个核心配置文件:
Spring+Mybatis 的核心配置文件:applicationContext-mybatis.xml一般我取的名字;
SpringMVC 的核心配置文件:applicationContext-mvc.xml一般我取的名字;
与上面的 web.xml 就是针对于这个的处理, 个人一般先写这个… 随便啦, 程序运行时候先执行的是 web.xml
由web.xml 引入Spring核心配置文件的加载…

applicationContext-mybatis.xml
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="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"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"><!-- 引入命名空间:context --><context:component-scanbase-package="com.wsm."/><!-- 扫描包下注解:注意对应项目包名~ --><!-- 数据源 --><beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"><propertyname="driverClassName"value="com.mysql.jdbc.Driver"/><propertyname="url"value="jdbc:mysql://localhost:3306/项目名别忘换了"></property><!-- 对于url连接,有时候会出现关键子建议使用: <![CDATA[ ... ]]> 包含,避免 < & 等关键字;--><propertyname="username"value="root"></property><propertyname="password"value="ok"></property></bean><!-- 连接工厂: --><beanid="SqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"><propertyname="dataSource"ref="dataSource"></property><!-- 固定name引用数据源bean --><propertyname="configLocation"value="classpath:mybatis-config.xml"></property><!-- 引入:mybatis-config.xml个人喜欢起的文件名可换~ --></bean><!-- MapperScannerConfigurer方式:解决多个Dao映射类,底层实现Dao接口的实例,进行数据库的操作..方法(); --><beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"><propertyname="sqlSessionFactoryBeanName"value="SqlSessionFactory"></property><!-- value="引用上面的连接工厂Id" --><propertyname="basePackage"value="com.wsm.dao"></property><!-- 可以包含多个包, value="包1,包2" --></bean><!-- 还可以进行事务的处理... --></beans>

上面文件依赖于:mybatis-config.xmlMybatis核心配置文件,Mybatis 中引入了 SqlMapper.xml 文件映射

mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTD Config 3.0//EN""mybatis-3-config.dtd"><configuration><settings><settingname="logImpl"value="LOG4J"/><!-- 设置MyBatis的log日志实现为LOG4J,即使用log4j实现日志功能。 --><!--设置resultMap的自动映射级别,NONE(禁止自动匹配),PARTIAL(默认)自动匹配所有属性,有内部嵌套(association、collection)的除外 且 数据库列与实体类名相同,FULL(自动匹配所有属性)比PARTIAL更强! --><settingname="autoMappingBehavior"value="FULL"/></settings><mappers><mapperresource="mapper/引入Mapper文件.xml"/></mappers></configuration>

详情请见:
MyBatis和Spring整合详解:
Spring IOC 和 AOP的扩展

程序运行:web.xml——applicationContext-mybatis.xml——mybatis.config.xml——sql映射文件。- 。 -

applicationContext-mvc.xml
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 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"><!-- 引入命名空间:context --><context:component-scanbase-package="com.wsm.controller"/><!-- 扫描包下注解:注意对应项目包名,扫描控制器包~ --><!-- 使Spring支持mvc注解驱动:别忘了命名空间 mvc --><mvc:annotation-driven/><!-- 配置视图解析器(ViewResolver): --><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- <property name="prefix" value="前缀"></property> --><propertyname="suffix"value=".jsp"></property></bean><!-- 静态资源的加载:参考下方连接SpringMVC 扩展 --><!-- 支持文件上传:参考下方连接 --><!-- 配置拦截器: 本篇讲解...请查看目录 --><!-- 多视图解析器:不是很清楚... --></beans>

SpringMVC 扩展
文件上传

除了这两个主要的核心配置文件还有一些扩展的…)…
log4j.properties
database.properties
…

7. Web.xml 配置

每一个 web项目都有一个 web.xml文件;
部署启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml 进行配置…
SSM框架需要两个核心配置文件:
Spring+Mybatis 的核心配置文件:applicationContext-mybatis.xml一般我取的名字;
SpringMVC 的核心配置文件:applicationContext-mvc.xml一般我取的名字;

<?xml version="1.0" encoding="UTF-8"?><web-appxmlns: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"version="3.0"><display-name>xxxxxx</display-name><!-- 描述的项目名 title --><!-- 监听器: web项目使用前: 启动对Spring容器加载; --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><!-- 指定Spring-mybatis配置文件的位置路径 --><param-value>classpath:applicationContext-mybatis.xml</param-value></context-param><!-- 配置SpringMVC核心控制器:DispatcherServlet DispatcherServlet:是SpringMVC的核心,负责接收请求 和 响应操作; --><servlet><servlet-name>mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 初始化参数:通过contextConfigLocation 属性来指定SpringMVC配置文件的位置; --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-mvc.xml</param-value></init-param><!-- 值 1 : 配置标记服务器启动时候加载DispatcherServlet --><load-on-startup>1</load-on-startup></servlet><!-- 通过servlet-mapping: 指定对应的Servlet --><servlet-mapping><servlet-name>mvc</servlet-name><!-- 指定对于的Servletname --><url-pattern>/</url-pattern><!-- / 匹配所有的请求(不包含.jsp) /* 包含.jsp 即所有的请求都会经过 url-pattern --></servlet-mapping><!-- 详情请见: --><!-- 解决项目中的控制器 中文参数乱码问题:请见下方超链接..(过滤器) --></web-app>

详情请参考:
web.xml监听器.
servlet配置详解.
控制器中文参数过滤器.

8.前端控制层 controller

就像以前的Servlet 请参考:SpringMVC体系结构


SpringMVC配置拦截器HandlerInterceptor:


在介绍SpringMVC拦截器前,先介绍一下SpringMVC的流程
1、 用户发送请求,经过前端控制器Dispacherservlet(Controller的核心)将请求交给对应的处理器映射HandlerMapping处理

2、HandlerMapping处理请求,返回HandlerExecutionChain(可能包含拦截器,一定包含自定义的Controller(handler))

上图步骤3:HandlerMapping接口,返回一个HandlerExecutionChain类

HandlerExecutionChain类:由一个handler和若干的HandlerInterceptor构成。
那么这个类的作用就显而易见了,就是将拦截器和handler组合起来执行。就是对handle进行了包装。

上图有关于 HandlerExecutionChain 类方法的说明: 总而言之就是对, 所有拦截器的操作;

3、 前端控制器将Controller交给处理器适配器HandlerAdapter处理,处理完成后,返回MV对象(ModelAndView)

4、 前端控制器将MV交给视图解析器处理ViewResolver,处理的过程:将MV拆分成Model和view两个对象,并且将model渲染到view视图上,并且将view返回给前端控制器。

5、 最后,前端控制器将视图响应给用户。


springMVC拦截器的实现一般有两种方式
  • 第一种方式是要定义的拦截器的类,要实现了Spring的HandlerInterceptor 接口
  • 第二种方式是继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter

继承接口方式实现类要重写所有方法, 考虑到Java单根性 就出现了抽象类, 好处可以选择性重写~

HandlerInterceptor接口方法:

preHandle():
这个方法在业务处理器处理请求之前被调用,SpringMVC 中的Interceptor 是链式的调用的,参考上图;
该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束;
后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法;
如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
有点类似于AOP 的前置增强, 每次此请求前都会执行的代码…如果返回false 则后面都不会执行;
postHandle():
这个方法在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用;
所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。
有点类似于AOP 的后置增强, Controller 中代码执行完了 , 都开始返回页面了执行…
afterCompletion():
该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。
该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。 有点类似于AOP 的最终增强.

拦截器常用于:

举个例子:
A登录网站查看个人信息消费记录啥啥啥的
B复制了A登录的URL 随便找个电脑,登录之间在URL 中粘贴A的URL; B页面上也看到了A的信息…
是的没错, 不信你可以试试, 而且我听说早期的qq 就可以直接改URL 来进入他人qq空间…(可惜我知道的太晚哎!)
想这种需要事实验证登录状态 而且是否本人的安全性问题…此时就需要拦截器对于每次请求拦截下来检查;
合法了才让你通过~ 不然滚蛋!
实现

  • src 中建一个包: com.wsm.interceptors 存放一些拦截器类;
  • 包中声明一个拦截器类, 本次使用继承抽象类方式;
    PowerInterceptor .Java
packagecom.zb.interceptors;importjava.io.PrintWriter;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter;importcom.zb.entity.User;publicclassPowerInterceptorextendsHandlerInterceptorAdapter{@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{//重写抽象类方法preHandle(); 三个参数 request response handler//登录成功用户都是存在session 中的吧~就直接通过session name形式取到对应的 loginUser用户;Useruser=(User)request.getSession().getAttribute("loginUser");System.out.println("========="+request.getRequestURI());//这里要注意登录时候 loginUser本就不存在就如果不做判断永远null 永远无法执行下一步了//对于静态资源也是一种请求, 所以对一些特殊的请求,拦截器是不拦直接放行的~(城门士兵拦将军?)//request.getRequestURI(); 获取URL中非服务器/域名 即:http://localhost:8080/news/main/list.jsp 返回:/news/main/list.jsp//startsWith(“”); / startsWith(“”,int); Java String类方法, 检查字符串中是否存在对应的前缀 返回true; +int 表示从第几个字符开始与比较参数;if(request.getRequestURI().startsWith("/myrole/login")||request.getRequestURI().startsWith("/myrole/static")){returntrue;//上述方法显而易见, myrole 就是项目名~ login/static 就是请求名, 注意这里是SpringMVC login也可以是对应控制器注解的 对应名~}//user !=null 表示已登录,返回true 放行~if(user!=null){System.out.println("用户登录成功");returntrue;}//如果取不到 loginUser登录用户为null 表示未登录无法访问!返回false;//并跳转至 login页面使其登录System.out.println("用户没有登录");PrintWriterout=response.getWriter();out.println("<html>");out.println("<script>");out.println("window.open ('"+request.getContextPath()+"/index.jsp','_self')");out.println("</script>");out.println("<html>");returnfalse;}}

applicationContext-mvc.xml配置拦截器:

!--配置拦截器, 多个拦截器,顺序执行 --><mvc:interceptors><mvc:interceptor><!-- /**的意思是所有文件夹及里面的子文件夹 /*是所有文件夹,不含子文件夹 /是web项目的根目录 --><mvc:mappingpath="/**"/><!-- 需排除拦截的地址:遇到这样的请求并不会拦截验证~直接通过~ --><!-- <mvc:exclude-mapping path="/userController/login"/> 有时候因为版本问题失效可按照上了手动Java代码实现..--><beanid="commonInterceptor"class="com.wsm.interceptors.PowerInterceptor"></bean><!--这个类就是我们自定义的Interceptor --></mvc:interceptor><!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 --></mvc:interceptors>