重温SSM框架整合(XML版)以及踩坑

前言

之前我用的都是配置类,因为我对于xml是深痛恶绝;但是在教同学用xml配的时候,状况频出,坏了,难道这么简单的我都还不会

首先要知道我们SSM工程中整合的是什么,怎么整合

需要整合的技术:

  • spring
  • springMvc
  • mybatis
  • log4j2(或其他日志)

然后我们需要maven的坐标,进行依赖的导入(都SSM,不会还不会maven吧)

        <!-- mybatis核心依赖 -->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.5.13</version>
       </dependency>
       <!-- spring整合mybatis依赖 -->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis-spring</artifactId>
           <version>3.0.2</version>
       </dependency>
       <!-- mysql驱动 -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.33</version>
       </dependency>
       <!-- 数据库驱动 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-jdbc</artifactId>
           <version>6.0.7</version>
       </dependency>
       <!-- 数据库连接池HikariCP -->
       <dependency>
           <groupId>com.zaxxer</groupId>
           <artifactId>HikariCP</artifactId>
           <version>5.0.1</version>
       </dependency>
       <!-- servlet依赖 -->
       <dependency>
           <groupId>org.apache.tomcat</groupId>
           <artifactId>tomcat-servlet-api</artifactId>
           <version>10.1.11</version>
       </dependency>
       <!-- springMVC依赖 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>6.0.9</version>
       </dependency>

注意!有spring-webmvc就够了,里面包含了spring-context、spring-core等

在这里插入图片描述

开整

这就是基本的配置文件了
在这里插入图片描述

整合mybatis

配置的思路很简单,spring是大管家,首先我们把数据库相关的交由spring容器管理,再把SqlSessionFactory给spring代理,就能实现和mybatis整合

这里推荐还是把数据库的信息独立成一个配置文件。推荐命名为db.properties或jdbc.properties

ok,独立出我们的数据库配置文件后,就可以愉快 的在spring管理数据源了

    <!-- 添加属性文件配置 -->
    <context:property-placeholder location="classpath:application.properties" />
    
    <!-- 连接池配置 -->
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

这里我使用了Hikari连接池,用啥都行

还记得嘛,mybatis的SqlSessionFactoryBean需要配置数据源,所以:

    <!-- spring管理sessionFactory -->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 指定MyBatis配置文件的位置 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 指定mapper文件的路径 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

最后我们还需要配置mapper的扫描器,把mybatis代理的mapper进行管理

    <!-- mapper扫描器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sessionFactory" />
    </bean>

mybatis的一些推荐设置与日志整合

话不多说,直接上log4j2的配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">

    <Appenders>
        <Console name="stdout" target="SYSTEM_OUT">
            <PatternLayout pattern="%5level [%t] - %msg%n"/>
        </Console>
    </Appenders>

    <Loggers>
        <Logger name="com.example.mapper" level="trace"/>
        <Root level="error" >
            <AppenderRef ref="stdout"/>
        </Root>
    </Loggers>

</Configuration>

在mybatis里面我们要设置日志的实现为LOG4J2

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!-- 开启驼峰转换 -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
        <setting name="logImpl" value="LOG4J2"/>
    </settings>

    <typeAliases>
        <package name="com.example.domain"/>
    </typeAliases>
</configuration>

可以看到,我还开启了驼峰转换和配置实体类的包别名,有什么用?

  • 根据工程规范,数据库表的字段与实体类字段对应,如uid --> uid,uname --> uname,这样是可以的,但是名字长了就不好命名了。推荐使用数据库字段使用下划线命名,实体类字段使用驼峰命名,如user_id --> userId。
  • 配置实体类的包别名,我们在mapper.xml文件中就不用写全限定类名了

整合springMvc

整合springMvc会稍微麻烦一点,需要注意扫描包不要冲突了

我们先来整理一下springMvc中需要配置什么:

  • 视图解析器,这是必要的,经过servlet后就到我们springMvc处理了
  • 扫描控制层
    <!-- 开启注解驱动 -->
    <mvc:annotation-driven />

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".html"></property>
    </bean>

如果你用配置类来写,会知道RootConfigClassesServletConfigClasses两个概念,简单来说spring容器和springMvc容器存在父子管理,子容器可以访问父容器,父容器不能访问子容器

而spring容器是父容器!

所以我们扫描控制层,不能和spring扫的重叠了,这里介绍两种写法

第一种
spring配置文件

    <!-- Spring容器中注册非@controller注解的Bean -->
    <context:component-scan base-package="com.example">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

springMvc配置文件

    <!-- SpringMvc容器中注册controller注解的Bean -->
    <context:component-scan base-package="com.example" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

第二种
spring配置文件

    <!--  多个扫描路径用逗号分割  -->
    <context:component-scan base-package="com.example.service,com.example.domain"></context:component-scan>

springMvc配置文件

<context:component-scan base-package="com.example.controller"></context:component-scan>

web.xml加载spriing和springMvc的生命周期

都是web工程,肯定逃不开配置web.xml的了,除非你用配置类

这里有两个核心:

  1. spring服务需要在Tomcat一启动就提供,所以我们要配置监听器
  2. servlet的请求要交由springMvc处理
    <!-- 配置Spring监听器启动,在服务器启动的时候最先启动 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
    </listener>

    <!-- servlet请求交由springMvc处理 -->
    <servlet>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:springMvc.xml;
                classpath:applicationContext.xml;
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

到现在就配置完了,可以启动你的Tomcat服务器进行测试了

踩坑

1. web.xml配置

一开始配置spring监听器竟然给我报错

Servlet.init() for servlet springDispatcherServlet threw exception。Error creating bean with name ‘userController’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory

直接人傻了,在网上找了半圈发现,web.xml中引入配置contextConfigLocation有两种写法,全部写到servlet中的init-parm中就没有问题,部分写到context-parm中就会报上述错误

我原来的web.xml代码

    <!-- 配置Spring监听器启动,在服务器启动的时候最先启动 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml;</param-value>
    </context-param>

    <!-- servlet请求交由springMvc处理 -->
    <servlet>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:springMvc.xml;
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet

修改后:

    <!-- 配置Spring监听器启动,在服务器启动的时候最先启动 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
    </listener>

    <!-- servlet请求交由springMvc处理 -->
    <servlet>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:springMvc.xml;
                classpath:applicationContext.xml;
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

2. controller无法正常工作

我进行如下检查:

  1. springMvc配置文件中注解驱动有没有开启
  2. springMvc容器扫描的是否和spring容器冲突
  3. 有没有加上controller注解
  4. web.xml有没有配置springMvc拦截请求

发现就是web.xml出现了问题,所以有了踩坑1,这里做一个排查思路的分享

3. Tomcat无法解析html文件

因为我配之后使用html文件进行测试,发现怎么都是404

首先,要确保你的html页面不在WEB-INF目录下;

其次,web.xml里放行了html文件:

    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>/</url-pattern>
        <url-pattern>*html</url-pattern>
    </servlet-mapping>

这样还是无法解决,就去Tomcat的conf目录下找到web.xml文件,在大概450行左右,修改成:
在这里插入图片描述

感谢以下文章提供解决的思路

  • https://blog.csdn.net/weixin_39722651/article/details/88191467
  • https://www.cnblogs.com/xiaotong1223/p/9233169.html

如果需要源码,请移步我的gitee仓库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值