跳至主要內容

swagger使用指南

Alooc...大约 5 分钟后端框架swaggerswagger

是什么:

Swagger是一个规范完整的API框架,用于生成、描述、调用和可视化Restful风格的Web服务的接口文档。

springfox是swagger的一个开源实现,用在以SpringBoot作为后台的开发框架中。swagger是一款流行的API管理管理。 springfox实现了Swagger UI 和Swagger-Core。 在SpringBoot开发中,可以很方便地使用maven和gradle引入。

Springfox 是一个集成了 Swagger,基于 Sring MVC/Spring Webflux 实现的一 个 Swagger 描述文件生成框架,通过使用它定义的一些描述接口的注解自动生成 Swagger 的描述文件,使 Swagger 能够展示并调用接口。springfox通过spring-plugin的方式将Plugin注册到Spring上下文中,然后使用这些plugin进行API的扫描工作,这里的扫描工作其实也就是构造Documentation的工作,把扫描出的结果封装成Documentation并放入到DocumentationCache内存缓存中,之后swagger-ui界面展示的API信息通过Swagger2Controller暴露,Swagger2Controller内部直接从DocumentationCache中寻找Documentation。是一个开源的API Doc的框架, 它的前身是swagger-springmvc,可以将我们的Controller中的方法以文档的形式展现。官方定义为: Automated JSON API documentation for API's built with Spring。

Springfox 是一个用于生成 Swagger 文档的开源框架。Swagger 是一种用于描述和定义 RESTful API 的规范,它提供了一种简单的方式来描述 API 的输入参数、输出结果和错误信息等。Springfox 提供了与 Spring 框架集成的功能,可以自动从代码中提取 API 的信息,并生成对应的 Swagger 文档。这样,开发人员可以通过 Swagger 文档来查看和测试 API,同时也方便了团队之间的沟通和协作。Springfox 还支持自定义扩展,可以根据项目的需求进行定制化配置。

怎么用:

1、示例

1、引入依赖

<!--springfox swagger官方Starter-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>${springfox-swagger.version}</version>
</dependency>

2、修改路径匹配策略

由于Spring默认的路径匹配策略为PATH_PATTERN_PARSER,而SpringFox假设为ANT_PATH_MATCHER,所以需要修改application.yml配置文件,添加如下配置;

spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER

PATH_PATTERN_PARSERopen in new window

3、添加配置文件

添加Swagger的Java配置,配置好Api信息和需要生成接口文档的类扫描路径,注意在SpringBoot2.6.x以上版本整合时由于兼容性问题需要配置一个BeanPostProcessor的Bean。

/**
 * Swagger相关配置
 */
@Configuration
public class SwaggerConfig {
    /**
     * 创建api应用
     */
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())//设置文档信息
                .select()//通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给swagger来展现
                .apis(RequestHandlerSelectors.basePackage("com.doku.swagger.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 创建文档的基本信息
     * @return
     */
    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("接口文档标题")
                .description("对于接口文档的描述")
                .contact(new Contact("用户名","主页链接","邮箱"))
                .version("1.0.0")
                .build();
    }

    /**
     * 解决springboot2.7.x与springfox3.0.0兼容问题【Failed to start bean 'documentationPluginsBootstrapper'】
     */
    @Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new 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);
                }
            }
        };
    }

}

4、测试

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Get Hello";
    }

    @PostMapping("/world")
    public String world() {
        return "Post World";
    }
}

5、访问

http://localhost:8088/swagger-ui/index.htmlopen in new window

http://localhost:8088/swagger-ui/open in new window

2、使用

1、注解

注解名称描述常用属性
@Api 用于类,标识这个类是Swagger的资源tags:给该类下的接口设置标签
@Tag 可用于类或方法,声明一个标签name:标签名称 description:标签描述
@ApiIgnore 忽略该类的文档生成value:添加备注
@ApiOperation 用于方法,用于描述一个HTTP请求方法value:给方法添加描述
@ApiParam 用于参数,用于描述请求参数value:参数描述 name:参数名称 defaultValue:参数默认值 required:参数是否必填 allowableValues:参数允许范围 type:参数类型
@ApiImplicitParam 代表一个单个API操作,与@ApiImplicitParams联用paramType:参数请求类型 dataTypeClass:参数值类型 其他类型同@ApiParam
@ApiImplicitParams 多个@ApiImplicitParam注解的集合参数为@ApiImplicitParam数组
@ApiModel 用于类,声明一个Swagger的模型value:模型名称 description:模型描述
@ApiProperty 用于参数,声明Swagger模型的属性或填充数据value:属性描述 name:属性名称 allowableValues:允许值
@ApiResponse 用于描述一个可能的返回结果responseCode:返回状态码 message:返回信息
@ApiResponses @ApiResponse的集合参数为@ApiResponse数组

2、其他配置

springfox:
  documentation:
    # 是否启用Swagger扫描代码生成文档
    enabled: true
    open-api:
      # 是否启用Swagger的open-api
      enabled: false
    swagger-ui:
      # 是否启用Swagger的Web UI
      enabled: true
      # 配置文档基础路径,此时路径为:/doc/swagger-ui/index.html
      base-url: /doc

3、集成security

改写swagger配置类

@Configuration
public class SwaggerConfig {
    /**
     * 创建api应用
     */
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())//设置文档信息
                .select()//通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给swagger来展现
                .apis(RequestHandlerSelectors.basePackage("com.doku.swagger.controller"))
                .paths(PathSelectors.any())
                .build()
                // 添加登录认证
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts())
                ;
    }

    private List<SecurityScheme> securitySchemes() {
        //设置请求头信息
        List<SecurityScheme> result = new ArrayList<>();
        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
        result.add(apiKey);
        return result;
    }

    private List<SecurityContext> securityContexts() {
        //设置需要登录认证的路径
        List<SecurityContext> result = new ArrayList<>();
        result.add(getContextByPath("/brand/.*"));
        result.add(getContextByPath("/redis/.*"));
        result.add(getContextByPath("/hi/.*"));
        result.add(getContextByPath("/sso/.*"));
        return result;
    }

    private SecurityContext getContextByPath(String pathRegex) {
        return SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex(pathRegex))
                .build();
    }

    private List<SecurityReference> defaultAuth() {
        List<SecurityReference> result = new ArrayList<>();
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        result.add(new SecurityReference("Authorization", authorizationScopes));
        return result;
    }

    /**
     * 创建文档的基本信息
     * @return
     */
    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("接口文档标题")
                .description("对于接口文档的描述")
                .contact(new Contact("用户名","主页链接","邮箱"))
                .version("1.0.0")
                .build();
    }


    /**
     * 解决springboot2.7.x与springfox3.0.0兼容问题【Failed to start bean 'documentationPluginsBootstrapper'】
     */
    @Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new 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);
                }
            }
        };
    }

}

4、使用knife4j美化界面

只需使用knife4j的依赖替换swagger3的依赖

	    <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.2</version>
        </dependency>
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.5