记录: SSM项目Spring依赖全部升级到6,Tomcat从8升级到10

1,672 阅读2分钟

最近初学了一个SSM增删改查的web项目,原项目是用的Spring4和Tomcat8做的。我突发奇想,想将依赖全部升级到最新版并且将Tomcat也更新。

Tomcat8中用的Servlet包是javax.servlet,而Tomcat10中不再用javax,转为用jakarta-servlet-api.

Tomcat10支持jdk17,而Tomcat8不支持。

下面是原SSM的maven依赖,里面用的Spring相关的jar包全是4版本的。

<!--引入项目依赖的jar包 -->
   <!-- SpringMVC、Spring -->
   <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
   <dependencies>

       <!--引入pageHelper分页插件 -->
       <dependency>
           <groupId>com.github.pagehelper</groupId>
           <artifactId>pagehelper</artifactId>
           <version>5.0.0</version>
       </dependency>

       <!-- MBG -->
       <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
       <dependency>
           <groupId>org.mybatis.generator</groupId>
           <artifactId>mybatis-generator-core</artifactId>
           <version>1.3.5</version>
       </dependency>


       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>4.3.7.RELEASE</version>
       </dependency>

       <!-- 返回json字符串的支持 -->
       <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.8.8</version>
       </dependency>

       <!--JSR303数据校验支持;tomcat7及以上的服务器,
       tomcat7以下的服务器:el表达式。额外给服务器的lib包中替换新的标准的el
       -->
       <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
       <dependency>
           <groupId>org.hibernate</groupId>
           <artifactId>hibernate-validator</artifactId>
           <version>5.4.1.Final</version>
       </dependency>


       <!-- Spring-Jdbc -->
       <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-jdbc</artifactId>
           <version>4.3.7.RELEASE</version>
       </dependency>

       <!--Spring-test -->
       <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-test</artifactId>
           <version>4.3.7.RELEASE</version>
       </dependency>


       <!-- Spring面向切面编程 -->
       <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-aspects</artifactId>
           <version>4.3.7.RELEASE</version>
       </dependency>

       <!--MyBatis -->
       <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.4.2</version>
       </dependency>
       <!-- MyBatis整合Spring的适配包 -->
       <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis-spring</artifactId>
           <version>1.3.1</version>
       </dependency>

       <!-- 数据库连接池、驱动 -->
       <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid</artifactId>
           <version>1.2.0</version>
       </dependency>

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.31</version>
       </dependency>
       <!-- (jstl,servlet-api,junit) -->
       <!-- https://mvnrepository.com/artifact/jstl/jstl -->
       <dependency>
           <groupId>jstl</groupId>
           <artifactId>jstl</artifactId>
           <version>1.2</version>
       </dependency>

       <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.0.1</version>
           <scope>provided</scope>
       </dependency>


       <!-- junit -->
       <!-- https://mvnrepository.com/artifact/junit/junit -->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
       </dependency>
       <!-- Spring4和Thymeleaf整合包 -->
       <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
       <dependency>
           <groupId>org.thymeleaf</groupId>
           <artifactId>thymeleaf-spring4</artifactId>
           <version>3.0.12.RELEASE</version>
       </dependency>
       <!-- log4j日志 -->
       <dependency>
           <groupId>log4j</groupId>
           <artifactId>log4j</artifactId>
           <version>1.2.17</version>
       </dependency>
       <!-- slf4j日志门面的一个具体实现 -->
       <dependency>
           <groupId>ch.qos.logback</groupId>
           <artifactId>logback-classic</artifactId>
           <version>1.2.3</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-war-plugin -->
   </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-war-plugin</artifactId>
               <version>3.3.2</version>
           </plugin>
       </plugins>
   </build>

然后是将Spring相关的jar包都升级到版本6的依赖:

<!--引入项目依赖的jar包 -->
    <!-- SpringMVC、Spring -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependencies>

        <!--引入pageHelper分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.0.0</version>
        </dependency>

        <!-- MBG -->
        <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.1</version>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- 返回json字符串的支持 -->
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.14.1</version>
        </dependency>


        <!--JSR303数据校验支持;tomcat7及以上的服务器,
        tomcat7以下的服务器:el表达式。额外给服务器的lib包中替换新的标准的el
        -->
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </dependency>


        <!-- Spring-Jdbc -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--Spring-test -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>


        <!-- Spring面向切面编程 -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--MyBatis -->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.11</version>
        </dependency>

        <!-- MyBatis整合Spring的适配包 -->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.1</version>
        </dependency>


        <!-- 数据库连接池、驱动 -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
        </dependency>
        <!-- (jstl,servlet-api,junit) -->
        <!-- https://mvnrepository.com/artifact/jstl/jstl -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->



        <!-- junit -->
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- Spring6和Thymeleaf整合包 -->
        <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring6 -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring6</artifactId>
            <version>3.1.1.RELEASE</version>
        </dependency>

        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- slf4j日志门面的一个具体实现 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-war-plugin -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>

记录一下其中容易出错的地方:

1.因为更换了Tomcat版本,Tomcat10的web.xml和Tomcat8的web.xml的XML约束是不同的,原项目文件的web.xml文件的约束必须替换,否则更新后的SpringMVC包里面的Servlet你是无法将其设置到<servlet>标签中的,

这是因为更新后的依赖为jakarta-servlet-api,自然无法将这个类型赋值给以前的javax-servlet-api。

因此要更改web.xml文件的约束。从tomcat文件夹中自带的web.xml中可以拿到:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                          https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
      version="6.0">
      
    </web-app>

约束改为这样,就可以为<servlet>标签赋值了。

2.Tomcat10中可以直接设置请求和响应的编码了,不需要设置CharacterEncodingFilter了。

 <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                          https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
      version="6.0">
      <!-- Set the default request and response character encodings to UTF-8.   -->
         <request-character-encoding>UTF-8</request-character-encoding>
         <response-character-encoding>UTF-8</response-character-encoding>
    </web-app>

3.如果用了thymeleaf,一定要升级spring-thymeleaf整合包,不然会报错。

我之前因为用了thymeleaf视图解析器,spring-thymeleaf整合包是版本4,而Spring相关的依赖已经升级到了版本6,所以thymeleaf是无法使用的,DispatcherServlet自然也无法处理请求。

所以我更换了thymeleaf-spring6的依赖。

然而这还没完,还会继续报错,因为之前的SpringMVC的thymeleaf视图解析器的配置是这样的

<bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
   <property name="order" value="1"/>
   <property name="characterEncoding" value="UTF-8"/>
   <property name="templateEngine">
       <bean class="org.thymeleaf.spring4.SpringTemplateEngine">
           <property name="templateResolver">
               <bean class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
                   <!-- 视图前缀 -->
                   <property name="prefix" value="/WEB-INF/views/"/>
                   <!-- 视图后缀 -->
                   <property name="suffix" value=".html"/>
                   <property name="templateMode" value="HTML5"/>
                   <property name="characterEncoding" value="UTF-8" />
               </bean>
           </property>
       </bean>
   </property>
</bean>

可以看到,在配置<property name="templateMode" value="">的时候,是用了"HTML5"这个字符串,然而在thymeleaf-spring6中,会报错:无法将字符串赋值给templateMode这个属性。查看源码后,发现在spring6 thymeleaf整合包中,setTemplateMode这个方法的参数变为了final TemplateMode templateMode,而在spring4-thymeleaf整合包中,这个参数是String类型的。

//thymeleaf-spring4整合包的setTemplateMode方法
public final void setTemplateMode(String templateMode) {
    Validate.notNull(templateMode, "Cannot set a null template mode value");
    this.templateMode = TemplateMode.parse(templateMode);
}
//thymeleaf-spring6整合包的setTemplateMode方法
public final void setTemplateMode(final TemplateMode templateMode) {
    Validate.notNull(templateMode, "Cannot set a null template mode value");
    this.templateMode = templateMode;
}

TemplateMode是一个枚举类型

public enum TemplateMode {
    HTML(true, false, false),
    XML(false, true, false),
    TEXT(false, false, true),
    JAVASCRIPT(false, false, true),
    CSS(false, false, true),
    RAW(false, false, false);
    ...
}

可以看到,thymeaf-spring6中已经定义好了这些类型,所以<property name="templateMode" value="">的值只能从这里面选,设置为value="HTML",之后页面就可以被成功渲染了

//用了thymeleaf-spring6之后,thymeleaf视图解析器的配置
<bean id="viewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
    <property name="order" value="1"/>
    <property name="characterEncoding" value="UTF-8"/>
    <property name="templateEngine">
        <bean class="org.thymeleaf.spring6.SpringTemplateEngine">
            <property name="templateResolver">
                <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
                    <!-- 视图前缀 -->
                    <property name="prefix" value="/WEB-INF/views/"/>
                    <!-- 视图后缀 -->
                    <property name="suffix" value=".html"/>
                    <property name="templateMode" value="HTML"/>
                    <property name="characterEncoding" value="UTF-8" />
                </bean>
            </property>
        </bean>
    </property>
</bean>