文章目录
- 1、启动类报错
- 2、日志类报错
- 3、Thymeleaf 3.x 默认不包含布局模块
- 4、Spring Boot 2.x 去掉了findOne()方法
- 5、Spring Boot 2.x 插入数据会报错
由于工作项目中目前还是采用的是 Spring Boot 1.x ,私下学习 2.x 的时候,将项目从 Spring Boot 1.x 升级到 2.x 的时候所踩的坑记录下来。
1、启动类报错
Spring Boot 部署到 Tomcat 中去启动时需要在启动类添加 SpringBootServletInitializer,2.x 和 1.x 有区别。该问题重新导入包即可。
// 1.x
import org.springframework.boot.web.support.SpringBootServletInitializer;
// 2.x
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class UserManageApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(UserManageApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(UserManageApplication.class, args);
}
}
2、日志类报错
Spring Boot 2.x 默认不包含 log4j,建议使用 slf4j 。
#1.x
import org.apache.log4j.Logger;
protected Logger logger = Logger.getLogger(this.getClass());
改为:
#2.x
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
protected Logger logger = LoggerFactory.getLogger(this.getClass());
3、Thymeleaf 3.x 默认不包含布局模块
当我将 Pom 包升级到 2.x 之后,访问首页的时候一片空白什么都没有,查看后台也没有任何的报错信息,首先尝试着跟踪了 http 请求,对比了一下也没有发现什么异常,在查询 Thymeleaf 3.x 变化时才发现:Spring Boot 2.x 中spring-boot-starter-thymeleaf 包默认并不包含布局模块,需要使用的时候单独添加,添加布局模块如下:
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
添加相关依赖后,发现日志中有这么一个警告信息:
2019-11-26 21:37:15.247 WARN 9616 --- [nio-8080-exec-4] n.n.u.t.decorators.DecoratorProcessor : The layout:decorator/data-layout-decorator processor has been deprecated and will be removed in the next major version of the layout dialect. Please use layout:decorate/data-layout-decorate instead to future-proof your code. See https://github.com/ultraq/thymeleaf-layout-dialect/issues/95 for more information.
2019-11-26 21:37:15.441 WARN 9616 --- [nio-8080-exec-4] n.n.u.t.expressions.ExpressionProcessor : Fragment expression "layout" is being wrapped as a Thymeleaf 3 fragment expression (~{...}) for backwards compatibility purposes. This wrapping will be dropped in the next major version of the expression processor, so please rewrite as a Thymeleaf 3 fragment expression to future-proof your code. See https://github.com/thymeleaf/thymeleaf/issues/451 for more information.
修改以前的布局标签 layout:decorator 为 layout:decorate 即可。
#1.x
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorator="layout">
改为:
#2.x
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorate="~{layout}">
还有一点,当 Spring Boot 为 1.x 版本的时候,导入 thymeleaf 模块会自动包含 web 模块。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
如图所示,spring-boot-starter-thymeleaf会自动包含spring-boot-starter-web,所以我们就不需要单独引入web依赖了。
但是当 Spring Boot 升级为 2.x 的时候,就需要单独导入 web 模块了。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
最后给出完整的 pom.xml 文件。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>chapter6</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>chapter6</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--通用mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.1.5</version>
</dependency>
<!--pagehelper 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
相关依赖包的版本信息如下:
关于 Spring Boot 2.x 和 thymeleaf 模块版本匹配问题需要小心注意。
4、Spring Boot 2.x 去掉了findOne()方法
以前的findOne()方法其实就是根据传入的 Id 来查找对象,所以在 Spring Boot 2.0 的 Repository 中我们可以添加findById(long id)来替换使用。
例如:
User user=userRepository.findOne(Long id)
改为手动在 userRepository 手动添加 findById(long id)方法,使用时将 findOne()调用改为 findById(long id)。
User user=userRepository.findById(long id)
delete()方法和 findOne()类似也被去掉了,可以使用 deleteById(Long id)来替换,还有一个不同点是 deleteById(Long id)默认实现返回值为 void。
Long deleteById(Long id);
改为
//delete 改为 void 类型
void deleteById(Long id);
当然我们还有一种方案可以解决上述的两种变化,就是自定义 Sql,但是没有上述方案简单不建议使用。
@Query("select t from Tag t where t.tagId = :tagId")
Tag getByTagId(@Param("tagId") long tagId);
5、Spring Boot 2.x 插入数据会报错
错误信息如下:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
....
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '299' for key 'PRIMARY'
报错提示的是主键冲突,跟踪数据库的数据发现并没有主键冲突,最后才发现是 Spring Boot 2.x 需要指定主键的自增策略,这个和 Spring Boot 1.x 有所区别,1.x 会使用默认的策略。
#2.x 需要在所有的主键上面显示的指明自增策略。
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;