Swagger 3.0 天天刷屏,真的香吗? (2)

总之还是和之前一样配置,根据官方文档要求,需要在配置类上加一个@EnableOpenApi注解。

文档如何分组?

我们都知道,一个项目可能分为前台,后台,APP端,小程序端.....每个端的接口可能还相同,不可能全部放在一起吧,肯定是要区分开的。

因此,实际开发中文档肯定是要分组的。

分组其实很简单,Swagger向IOC中注入一个Docket即为一个组的文档,其中有个groupName()方法指定分组的名称。

因此只需要注入多个Docket指定不同的组名即可,当然,这些文档的标题、描述、扫描的路径都是可以不同定制的。

如下配置两个Docket,分为前台和后台,配置类如下:

@EnableOpenApi @Configuration @EnableConfigurationProperties(value = {SwaggerProperties.class}) public class SwaggerConfig { /** * 配置属性 */ @Autowired private SwaggerProperties properties; @Bean public Docket frontApi() { return new Docket(DocumentationType.OAS_30) //是否开启,根据环境配置 .enable(properties.getFront().getEnable()) .groupName(properties.getFront().getGroupName()) .apiInfo(frontApiInfo()) .select() //指定扫描的包 .apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage())) .paths(PathSelectors.any()) .build(); } /** * 前台API信息 */ private ApiInfo frontApiInfo() { return new ApiInfoBuilder() .title(properties.getFront().getTitle()) .description(properties.getFront().getDescription()) .version(properties.getFront().getVersion()) .contact( //添加开发者的一些信息 new Contact(properties.getFront().getContactName(), properties.getFront().getContactUrl(), properties.getFront().getContactEmail())) .build(); } /** * 后台API */ @Bean public Docket backApi() { return new Docket(DocumentationType.OAS_30) //是否开启,根据环境配置 .enable(properties.getBack().getEnable()) .groupName("后台管理") .apiInfo(backApiInfo()) .select() .apis(RequestHandlerSelectors.basePackage(properties.getBack().getBasePackage())) .paths(PathSelectors.any()) .build(); } /** * 后台API信息 */ private ApiInfo backApiInfo() { return new ApiInfoBuilder() .title(properties.getBack().getTitle()) .description(properties.getBack().getDescription()) .version(properties.getBack().getVersion()) .contact( //添加开发者的一些信息 new Contact(properties.getBack().getContactName(), properties.getBack().getContactUrl(), properties.getBack().getContactEmail())) .build(); } }

属性配置文件SwaggerProperties如下,分为前台和后台两个不同属性的配置:

/** * swagger的属性配置类 */ @ConfigurationProperties(prefix = "spring.swagger") @Data public class SwaggerProperties { /** * 前台接口配置 */ private SwaggerEntity front; /** * 后台接口配置 */ private SwaggerEntity back; @Data public static class SwaggerEntity { private String groupName; private String basePackage; private String title; private String description; private String contactName; private String contactEmail; private String contactUrl; private String version; private Boolean enable; } }

此时的文档截图如下,可以看到有了两个不同的分组:

Swagger 3.0 天天刷屏,真的香吗?

如何添加授权信息?

现在项目API肯定都需要权限认证,否则不能访问,比如请求携带一个TOKEN。

在Swagger中也是可以配置认证信息,这样在每次请求将会默认携带上。

在Docket中有如下两个方法指定授权信息,分别是securitySchemes()和securityContexts()。在配置类中的配置如下,在构建Docket的时候设置进去即可:

@Bean public Docket frontApi() { RequestParameter parameter = new RequestParameterBuilder() .name("platform") .description("请求头") .in(ParameterType.HEADER) .required(true) .build(); List<RequestParameter> parameters = Collections.singletonList(parameter); return new Docket(DocumentationType.OAS_30) //是否开启,根据环境配置 .enable(properties.getFront().getEnable()) .groupName(properties.getFront().getGroupName()) .apiInfo(frontApiInfo()) .select() //指定扫描的包 .apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage())) .paths(PathSelectors.any()) .build() .securitySchemes(securitySchemes()) .securityContexts(securityContexts()); } /** * 设置授权信息 */ private List<SecurityScheme> securitySchemes() { ApiKey apiKey = new ApiKey("BASE_TOKEN", "token", In.HEADER.toValue()); return Collections.singletonList(apiKey); } /** * 授权信息全局应用 */ private List<SecurityContext> securityContexts() { return Collections.singletonList( SecurityContext.builder() .securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{new AuthorizationScope("global", "")}))) .build() ); }

以上配置成功后,在Swagger文档的页面中将会有Authorize按钮,只需要将请求头添加进去即可。如下图:

Swagger 3.0 天天刷屏,真的香吗?

如何携带公共的请求参数?

不同的架构可能发请求的时候除了携带TOKEN,还会携带不同的参数,比如请求的平台,版本等等,这些每个请求都要携带的参数称之为公共参数。

那么如何在Swagger中定义公共的参数呢?比如在请求头中携带。

在Docket中的方法globalRequestParameters()可以设置公共的请求参数,接收的参数是一个List<RequestParameter>,因此只需要构建一个RequestParameter集合即可,如下:

@Bean public Docket frontApi() { //构建一个公共请求参数platform,放在在header RequestParameter parameter = new RequestParameterBuilder() //参数名称 .name("platform") //描述 .description("请求的平台") //放在header中 .in(ParameterType.HEADER) //是否必传 .required(true) .build(); //构建一个请求参数集合 List<RequestParameter> parameters = Collections.singletonList(parameter); return new Docket(DocumentationType.OAS_30) ..... .build() .globalRequestParameters(parameters); }

以上配置完成,将会在每个接口中看到一个请求头,如下图:

Swagger 3.0 天天刷屏,真的香吗?

粗略是一个BUG

作者在介绍自动配置类的时候提到了一嘴,现在来简单分析下。

OpenApiAutoConfiguration这个自动配置类中已经导入OpenApiDocumentationConfiguration这个配置类,如下一段代码:

@Import({ OpenApiDocumentationConfiguration.class, ...... })

@EnableOpenApi的源码如下:

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) @Target(value = {java.lang.annotation.ElementType.TYPE}) @Documented @Import(OpenApiDocumentationConfiguration.class) public @interface EnableOpenApi { }

从源码可以看出:@EnableOpenApi这个注解的作用就是导入OpenApiDocumentationConfiguration这个配置类,纳尼???

既然已经在自动配置类OpenApiAutoConfiguration导入了,那么无论需不需要在配置类上标注@EnableOpenApi注解不都会开启Swagger支持吗?

测试一下:不在配置类上标注@EnableOpenApi这个注解,看看是否Swagger运行正常。结果在意料之中,还是能够正常运行。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxwpx.html