文章目录
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 { /** * 检查客户端版本是否有效 */ @Autowired private ICheckClientVersionHandler checkClientVersionHandler; /** * 请求处理前处理 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public 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 { /** * 检查客户端版本是否有效 */ @Autowired private ICheckClientVersionHandler checkClientVersionHandler; /** * 请求处理前处理 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public 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 { @Override public 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 { @Override public void addFormatters(FormatterRegistry registry) { //仅对Path方式传入的参数生效 registry.addFormatterForFieldType(String.class, new StringFormatter()); registry.addFormatterForFieldType(LocalDateTime.class, new LocalDateTimeFormatter()); } }