• SpringBoot - SWAGGER3公共模块的抽象集成与使用(三)


    写在前面

    用于集成SWAGGER3。
    SpringBoot - Swagger2的集成与使用(一)
    SpringBoot - SWAGGER2公共模块的抽象集成与使用(二)

    操作步骤

    1. 创建一个单独的模块(servicex-common-swagger3)
    2. 在该模块中引入依赖
    <!-- Swagger -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-boot-starter</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3. 自定义SWAGGER3注解
    4. 创建自动装配SWAGGER3的对象
    /**
     * 自动装配SWAGGER3
     * @author ROCKY
     */
    
    @Configuration
    @EnableOpenApi
    @EnableAutoConfiguration
    @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
    public class SwaggerAutoConfiguration {
    
        // 默认的排除路径, 排除SPRING BOOT默认的错误处理路径和端点
        private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
    
        private static final String BASE_PATH = "/**";
    
        @Bean
        @ConditionalOnMissingBean
        public SwaggerProperties swaggerProperties() {
            return new SwaggerProperties();
        }
    
        @Bean
        public Docket api(SwaggerProperties swaggerProperties) {
            // BASE-PATH的处理
            if (swaggerProperties.getBasePath().isEmpty()) {
                swaggerProperties.getBasePath().add(BASE_PATH);
            }
            // SWAGGER会解析的URL规则的处理, 将配置的需要解析的URL规则放进LIST中
            List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
            swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path)));
    
            // 在BASE-PATH基础上需要排除的URL规则的处理, 将配置的需要排除的URL规则放进LIST中
            if (swaggerProperties.getExcludePath().isEmpty()) {
                swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
            }
            List<Predicate<String>> excludePath = new ArrayList<>();
            swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
    
            ApiSelectorBuilder builder = new Docket(DocumentationType.OAS_30)
                    .host(swaggerProperties.getHost())
                    .apiInfo(apiInfo(swaggerProperties))
                    .select()
                    .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
    
            swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
            swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
            return builder.build().globalRequestParameters(getGlobalOperationParameters()).pathMapping("/");
    
        }
    
        private List<RequestParameter> getGlobalOperationParameters() {
            List<RequestParameter> parameters = Arrays.asList(
                    new RequestParameterBuilder().name("token").description("令牌").in(ParameterType.HEADER).query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))).build(),
                    new RequestParameterBuilder().name("requestId").description("请求ID").in(ParameterType.HEADER).query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))).build(),
                    new RequestParameterBuilder().name("Content-Type").description("内容类型").in(ParameterType.HEADER).query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)).defaultValue("application/json")).build()
            );
            return parameters;
        }
    
        // 文档基本信息
        private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
            return new ApiInfoBuilder()
                    .title(swaggerProperties.getTitle())
                    .description(swaggerProperties.getDescription())
                    .license(swaggerProperties.getLicense())
                    .licenseUrl(swaggerProperties.getLicenseUrl())
                    .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
                    .contact(new Contact(swaggerProperties.getContact().getName(),
                                         swaggerProperties.getContact().getUrl(),
                                         swaggerProperties.getContact().getEmail()))
                    .version(swaggerProperties.getVersion())
                    .build();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    5. 创建SWAGGER3配置对象
    6. 配置场景启动器的加载策略
    7. 编译打包…
    8. 在线API文档

    http://微服务的IP或者LOCALHOST:微服务的端口号/swagger-ui/index.html

    9. SWAGGER3资源映射路径
    /**
     * SWAGGER3资源映射路径
     * @author ROCKY
     */
    @Configuration
    public class SwaggerWebConfiguration implements WebMvcConfigurer {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            /** swagger-ui 地址 */
            registry.addResourceHandler("/swagger-ui/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    10. SWAGGER3在SPRING-BOOT-2.6.x不兼容问题的处理
    /**
     * SWAGGER3在SPRING-BOOT-2.6.x 不兼容问题的处理
     * @author ROCKY
     */
    @Component
    public class SwaggerBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
            }
            return bean;
        }
    
        private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
            List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
                    .collect(Collectors.toList());
            mappings.clear();
            mappings.addAll(copy);
        }
    
        @SuppressWarnings("unchecked")
        private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
            try {
                Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                field.setAccessible(true);
                return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new IllegalStateException(e);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注意

    在上面的步骤中如果没有具体操作,请参照前面的博文:
    SpringBoot - SWAGGER2公共模块的抽象集成与使用(二)

    目录结构

    在这里插入图片描述

  • 相关阅读:
    报告下载|《云原生安全威胁分析报告》
    FSC商标门户网站重置密码操作指南
    Golang net/http 标准库源码学习
    MySQL8小时连接超时断开问题
    什么是人力资源管理系统?hr系统功能介绍
    rk3588编译atlas200
    Python 解释器的安装过程
    5-13sqli暴力破解在sqli漏洞中的应用
    ZFS了解
    R语言ggplot2可视化:使用ggpubr包的ggdonutchart函数可视化甜甜圈图(donut chart)、为甜甜圈图不同区域添加标签
  • 原文地址:https://blog.csdn.net/goodjava2007/article/details/125545773