文章目錄
- Spring boot 2.0 升級到 3.3.1 的相關問題 (一)
- 攔截器Interceptor的變動
- 問題介紹
- 解決方案
- WebMvcConfigurerAdapter 自定義Mvc配置
- 問題介紹
- 解決方案
Spring boot 2.0 升級到 3.3.1 的相關問題 (一)
攔截器Interceptor的變動
問題介紹
在2.0 版本可以通過繼承org.springframework.web.servlet.handler.HandlerInterceptorAdapter
類來實現一個攔截器,在2.4.0 版本開始標記為棄用,在3.3.1 版本已經沒有這個類了,需要使用新的方式來實現。
解決方案
直接實現 org.springframework.web.servlet.HandlerInterceptor
接口即可。
原代碼:
import com.abc.springboot.frame.constant.FrameConstant;
import com.abc.springboot.frame.pojo.dto.SystemSecurityRequestDTO;
import com.abc.springboot.frame.utils.RequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 檢查客戶端版本號攔截器*/
@Slf4j
public class CheckClientVersionInterceptor extends HandlerInterceptorAdapter {/*** 檢查客戶端版本是否有效*/@Autowiredprivate ICheckClientVersionHandler checkClientVersionHandler;/*** 請求處理前處理* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {//獲取請求參數SystemSecurityRequestDTO requestDTO = RequestUtils.getAndSetSystemSecurityRequestDTO(request);//校驗客戶端版本號try{boolean checkResult = checkClientVersionHandler.checkClientVersion(requestDTO,request.getHeader(FrameConstant.HTTP_HEADER_CLIENT_VERSION),request.getHeader(FrameConstant.HTTP_HEADER_CLIENT_TYPE));if(!checkResult){log.info("版本號不支持【{}】【{}】",requestDTO.getMethod(),requestDTO.getUri());request.getRequestDispatcher(FrameConstant.APPLICATION_URL_CLIENT_VERSION_VERIFY_FAILED).forward(request, response);return false;}return true;}catch (Exception e){log.warn("記錄系統請求日志失敗。",e);return false;}}
}
新代碼
import com.abc.springboot.frame.constant.FrameConstant;
import com.abc.springboot.frame.pojo.dto.SystemSecurityRequestDTO;
import com.abc.springboot.frame.utils.RequestUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;/*** 檢查客戶端版本號攔截器*/
@Slf4j
public class CheckClientVersionInterceptor implements HandlerInterceptor {/*** 檢查客戶端版本是否有效*/@Autowiredprivate ICheckClientVersionHandler checkClientVersionHandler;/*** 請求處理前處理* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {//獲取請求參數SystemSecurityRequestDTO requestDTO = RequestUtils.getAndSetSystemSecurityRequestDTO(request);//校驗客戶端版本號try{boolean checkResult = checkClientVersionHandler.checkClientVersion(requestDTO,request.getHeader(FrameConstant.HTTP_HEADER_CLIENT_VERSION),request.getHeader(FrameConstant.HTTP_HEADER_CLIENT_TYPE));if(!checkResult){log.info("版本號不支持【{}】【{}】",requestDTO.getMethod(),requestDTO.getUri());request.getRequestDispatcher(FrameConstant.APPLICATION_URL_CLIENT_VERSION_VERIFY_FAILED).forward(request, response);return false;}return true;}catch (Exception e){log.warn("記錄系統請求日志失敗。",e);return false;}}
}
WebMvcConfigurerAdapter 自定義Mvc配置
問題介紹
在2.0 版本可以通過繼承org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
類來實現自定義Mvc攔截器,在2.4.0 版本開始標記為棄用,在3.3.1 版本已經沒有這個類了,需要使用新的方式來實現。
解決方案
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
類在 Spring Framework 5.0
之后被標記為已棄用,并在 Spring Boot 2.0
中不再推薦使用 。
替代方案有兩種:
直接實現 WebMvcConfigurer
接口:
這是官方推薦的替代方法。WebMvcConfigurer
接口提供了多種默認方法(即帶有實現的方法),允許開發者只實現所需的配置方法,而不必要實現接口中的所有方法。這種方式不會影響 Spring Boot 自身的 @EnableAutoConfiguration
,允許 Spring Boot 的自動配置生效 。
繼承 WebMvcConfigurationSupport
類:
另一種方法是繼承 WebMvcConfigurationSupport
類。這個類提供了 Spring MVC 的默認配置,通過繼承它,可以覆蓋特定的方法來自定義配置。但請注意,使用這種方式將覆蓋 Spring Boot 的自動配置,因此如果某個方法沒有被重寫,可能會導致相關功能的缺失,比如靜態資源的處理 。
總結來說,如果你需要進行一些簡單的自定義配置,并且想要保留 Spring Boot 的自動配置功能,推薦直接實現 WebMvcConfigurer
接口。如果你需要更全面的控制 Spring MVC 的配置,可以考慮繼承 WebMvcConfigurationSupport
類,但要確保所有必要的配置都被正確覆蓋和實現。
原代碼
import com.abc.utils.formatter.LocalDateTimeFormatter;
import com.abc.utils.formatter.StringFormatter;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import java.time.LocalDateTime;/*** 自定義的Mvc配置,用于配置格式化程序* @author 徐明龍 XuMingLong 2022-03-17*/
@Configuration
public class CustomWebMvcFormattersConfigurer extends WebMvcConfigurerAdapter {@Overridepublic void addFormatters(FormatterRegistry registry) {//僅對Path方式傳入的參數生效registry.addFormatterForFieldType(String.class, new StringFormatter());registry.addFormatterForFieldType(LocalDateTime.class, new LocalDateTimeFormatter());}
}
新代碼
import com.abc.utils.formatter.LocalDateTimeFormatter;
import com.abc.utils.formatter.StringFormatter;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.time.LocalDateTime;/*** 自定義的Mvc配置,用于配置格式化程序* @author 徐明龍 XuMingLong 2022-03-17*/
@Configuration
public class CustomWebMvcFormattersConfigurer implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {//僅對Path方式傳入的參數生效registry.addFormatterForFieldType(String.class, new StringFormatter());registry.addFormatterForFieldType(LocalDateTime.class, new LocalDateTimeFormatter());}
}