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

本文档详细介绍了如何在SpringBoot项目中集成Swagger3,包括创建独立模块、引入依赖、自定义注解、配置自动装配、配置对象、设置加载策略、处理不兼容问题等步骤。最后展示了在线API文档的访问方式和Swagger3资源映射路径。通过这些步骤,开发者可以便捷地为微服务添加API文档功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

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

操作步骤

1. 创建一个单独的模块(servicex-common-swagger3)
2. 在该模块中引入依赖
<!-- Swagger -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
</dependency>
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();
    }
}
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/");
    }
}
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);
        }
    }
}

注意

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

目录结构

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cloneme01

谢谢您的支持与鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值