原文:https://www.jianshu.com/p/3494c84b4be3
前言
Spring Boot已經發布2.0有4個月多,多了很多新特性,一些坑也慢慢被填上,最近有空,就把本博客中Spring Boot干貨系列對應的源碼從1.5X升級到Spring Boot 2.0,順便整理下升級的時候遇到的一些坑,做個記錄。后續的教程就以最新的2.03版本為主。
正文
閑話不多說,本篇基於上一篇的源碼chapter13為參考,直接升級到2.0.3.RELEASE,然后看着一堆報錯開搞。在修改的過程中記錄下來,方便后續升級的朋友少踩一些坑。
依賴 JDK 版本升級
2.x 至少需要 JDK 8 的支持,2.x 里面的許多方法應用了 JDK 8 的許多高級新特性,所以你要升級到 2.0 版本,先確認你的應用必須兼容 JDK 8。
另外,2.x 開始了對 JDK 9 的支持。
第三方類庫升級
2.x 對第三方類庫升級了所有能升級的穩定版本,一些值得關注的類庫升級我給列出來了。
- Spring Framework 5+
- Tomcat 8.5+
- Flyway 5+
- Hibernate 5.2+
- Thymeleaf 3+
啟動類報錯
問題:
啟動類SpringBootServletInitializer標紅報錯,導入的類不對。
原因:
Spring Boot 部署到 Tomcat 中去啟動時需要在啟動類添加SpringBootServletInitializer,2.0 和 1.0 有區別。
解決方案:
package com.dudu; import com.dudu.util.MyMapper; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @SpringBootApplication //啟注解事務管理 @EnableTransactionManagement // 啟注解事務管理,等同於xml配置方式的 <tx:annotation-driven /> @MapperScan(basePackages = "com.dudu.dao", markerInterface = MyMapper.class) public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
配置文件報錯
問題:
配置文件中項目名稱配置報錯:server.context-path: /spring
原因:
大量的Servlet專屬的server.* properties被移到了server.servlet下:
由此可以看出一些端倪,那就是server不再是只有servlet了,還有其他的要加入。
解決方案:
server.context-path: /spring改成server.servlet.context-path: /spring既可
Web Starter 作為傳遞依賴
問題:
工程用的模板是thymeleaf,啟動報錯提示找不到spring-boot-starter-web
原因:
以前有幾個 Spring Boot starter 是依賴於 Spring MVC 而傳遞的spring-boot-starter-web。在 Spring WebFlux 新的支持下,spring-boot-starter-mustache,spring-boot-starter-freemarker並spring-boot-starter-thymeleaf不再依賴它。開發者有責任選擇和添加spring-boot-starter-web或spring-boot-starter-webflux。
解決方案:
導入spring-boot-starter-web既可
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Thymeleaf 3.0 默認不包含布局模塊
問題:
啟動項目的時候發現首頁空白,查看后台也沒有任何的報錯信息
原因:
Spring Boot 2.0 中spring-boot-starter-thymeleaf 包默認並不包含布局模塊,需要使用的時候單獨添加。
解決方案:
<dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> </dependency>
攔截器過時
問題:
升級后,WebMvcConfigurerAdapter提示過時
原因:
升級后的springBoot,使用了java8的特性 default 方法,所以直接實現 WebMvcConfigurer 這個接口即可。
解決方案:
舊:
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter
新:
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer
靜態資源被攔截
問題:
訪問系統的時候登錄樣式沒有加載
原因:
1.5版本時候META-INF/resources / resources / static / public 都是spring boot 認為靜態資源應該放置的位置,會自動去尋找靜態資源,而在spring boot 2.0則對靜態資源也進行了攔截,當攔截器攔截到請求之后,但controller里並沒有對應的請求時,該請求會被當成是對靜態資源的請求。此時的handler就是 ResourceHttpRequestHandler,就會拋出上述錯誤。
解決方案:
解決辦法就是,在攔截器那里排除靜態資源的請求路徑
/** java * 攔截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { // addPathPatterns 用於添加攔截規則 // excludePathPatterns 用戶排除攔截 registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatternss("/toLogin","/login","/assets/**","/js/**"); }
assets就是我放靜態文件的目錄
全局異常特殊處理
問題:
上一篇提到過的有些錯誤你可能想特殊對待處理的,現在對應代碼標紅,找不到對應的類
原因:
新版本后該方法去掉了,需要換成新的方法處理
解決方案:
舊代碼:
@Configuration public class ContainerConfig { @Bean public EmbeddedServletContainerCustomizer containerCustomizer(){ return new EmbeddedServletContainerCustomizer(){ @Override public void customize(ConfigurableEmbeddedServletContainer container) { container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500")); container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404")); } }; } }
新代碼:
@Configuration public class ContainerConfig implements ErrorPageRegistrar { @Override public void registerErrorPages(ErrorPageRegistry registry) { ErrorPage[] errorPages = new ErrorPage[2]; errorPages[0] = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"); errorPages[1] = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"); registry.addErrorPages(errorPages); } }
暫時處理了以上幾個錯誤后,項目就可以啟動了,還有其他隱藏的錯誤后續遇到了再補充。
作者:嘟爺MD
鏈接:https://www.jianshu.com/p/3494c84b4be3
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。
