记录一下项目更新版本依赖踩坑
这个是项目最早的版本依赖
这里最初是最初是升级到 2.5.7 偷了个懒 这个版本的兼容性比较强 就选了这版本 也不用去修改就手动的去换了一下RabbitMQ的依赖 因为这边项目有AMQP 风险预警
1.spring-amqp版本低于2.4.17的用户应升级到2.4.17
2.spring-amqp是3.0.0至3.0.9版本的用户应升级至3.0.10
之前用的是starter 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>3.0.10</version>
</dependency>
然后打包后发现并没有什么用 版本依旧是跟着springboot走的 就手动换成了单个依赖
单个依赖
<properties>
<spring-amqp.version>2.4.17</spring-amqp.version>
<spring-rabbit.version>2.4.17</spring-rabbit.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- rabbit mq 配置 -->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>${spring-amqp.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>${spring-rabbit.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
就在我也觉得没啥问题的时候 发现 swagger 在线下运行是正常的 到线上就显示不出来 一开始是以为升级版本后跨域的影响 毕竟后台管理明显提示是有跨域 好嘛 那就改跨域
这里 着重就是改了一个 addAllowedOriginPattern
修改前
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
/* 是否允许请求带有验证信息 */
corsConfiguration.setAllowCredentials(true);
/* 允许访问的客户端域名 */
corsConfiguration.addAllowedOrigin("*");
/* 允许服务端访问的客户端请求头 */
corsConfiguration.addAllowedHeader("*");
/* 允许访问的方法名,GET POST等 */
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
修改后
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
/* 是否允许请求带有验证信息 */
corsConfiguration.setAllowCredentials(true);
/* 允许访问的客户端域名 */
corsConfiguration.addAllowedOriginPattern("*");
/* 允许服务端访问的客户端请求头 */
corsConfiguration.addAllowedHeader("*");
/* 允许访问的方法名,GET POST等 */
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
心想这下总该好了吧 结果一上线又是swagger访问不到 甚至连响应返回的数据都不是json的了 我想着难道 Filter 也要跟着改 这块要改的话变动有点大 心一横 不行就把swagger升级到3.0 说不定就是版本问题
引了最新版本的Knife4j
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
修改config
@EnableOpenApi
@Configuration
public class SwaggerConfig {
private static final String SPLITOR = ";";
public static Predicate<RequestHandler> basePackage(final String basePackage) {
return input -> declaringClass(input).map(handlerPackage(basePackage)).orElse(true);
}
private static Optional<Class<?>> declaringClass(RequestHandler input) {
return Optional.ofNullable(input.declaringClass());
}
private static Function<Class<?>, @Nullable Boolean> handlerPackage(final String basePackage) {
return input -> {
// 循环判断匹配
for (String strPackage : basePackage.split(SPLITOR)) {
boolean isMatch = input.getPackage().getName().startsWith(strPackage);
if (isMatch) {
return true;
}
}
return false;
};
}
/**
* 配置基本信息
* @return
*/
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("xxxx sss端API接口文档")
.description("swagger app restful api")
.termsOfServiceUrl("https://xxx.xxx.xxx")
.contact(new Contact("Dotclv","",""))
.version("1.0")
.build();
}
/**
* 配置文档生成最佳实践
* @param apiInfo
* @return
*/
@Bean
public Docket createRestApi(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo)
.groupName("SwaggerGroupOneAPI")
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.paths(PathSelectors.any())
.build()
.securitySchemes(Collections.singletonList(securityScheme()))
.globalOperationParameters(setHeaderToken());
}
@Bean
public Docket groupCommon() {
return new Docket(DocumentationType.OAS_30)
.apiInfo(this.apiInfo())
.ignoredParameterTypes(ModelAttribute.class)
.groupName("通用模块")
.select()
//此包路径下的类,才生成接口文档
.apis(basePackage("xxx.xxx.xxxx.common"))
//加了ApiOperation注解的类,才生成接口文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build()
.securitySchemes(Collections.singletonList(securityScheme()))
.securityContexts(securityContexts());
}
/**
* 新增 securityContexts 保持登录状态
*/
private List<SecurityContext> securityContexts() {
return new ArrayList(
Collections.singleton(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build())
);
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return new ArrayList(
Collections.singleton(new SecurityReference(DefContants.X_ACCESS_TOKEN, authorizationScopes)));
}
/***
* oauth2配置
* 需要增加swagger授权回调地址
* http://localhost:8888/webjars/springfox-swagger-ui/o2c.html
* @return
*/
@Bean
SecurityScheme securityScheme() {
return new ApiKey(DefContants.X_ACCESS_TOKEN, DefContants.X_ACCESS_TOKEN, "header");
}
/**
* JWT token
*
* @return
*/
private List<Parameter> setHeaderToken() {
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> pars = new ArrayList<>();
tokenPar.name(DefContants.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
pars.add(tokenPar.build());
return pars;
}
/**
* 增加如下配置可解决Spring Boot 6.x 与Swagger 3.0.0 不兼容问题
**/
@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
String basePath = webEndpointProperties.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
}
private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}
}
你以为完了 不不 它又出问题了 升级到3.0 本地运行没有一点问题 但是一打包到线上运行就报错mapstruct 转换异常 什么swagger-2.0的错误 我就纳闷了我用的是3.0啊 咋报2.0的错误 千搜万搜 找了一堆没有用的解释文章 后面在一个github的评论区看到一老哥说 运行时和编译时依赖不一样
心想这还玩个花 加个依赖试试
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<artifactId>mapstruct</artifactId>
<groupId>org.mapstruct</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
后面编译运行果然没有问题 swagger也正常了 接口也返回数据也正常了 真难
改都改到这了算了 直接升springboot 版本到2.x最后一个版本算了 就又改了 parent 的版本到2.7.16 后面在运行就没有其他问题了 但是它又报循环依赖 好嘛 这个还要手动配置
spring:
main:
allow-circular-references: true
lazy-initialization: true
mvc:
pathmatch:
matching-strategy: ant_path_matcher
这边循环依赖 懒加载 包括2.6后整合swagger的依赖启动报错 一起配置了 然后这会是真的没有问题了 真是一波好几折