记录一下项目更新版本依赖踩坑
这个是项目最早的版本依赖
这里最初是最初是升级到 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 {@Beanpublic 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 {@Beanpublic 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*/@Beanpublic 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*/@Beanpublic 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());}@Beanpublic 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*/@BeanSecurityScheme 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 不兼容问题**/@Beanpublic 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: truelazy-initialization: truemvc:pathmatch:matching-strategy: ant_path_matcher
这边循环依赖 懒加载 包括2.6后整合swagger的依赖启动报错 一起配置了 然后这会是真的没有问题了 真是一波好几折