-
背景
日常前后端分离开发中,由于项目中接口众多,有时候前后端联调接口查看不方便,以及每个产品版本的接口不能更加直观的查看。 -
swagger介绍
Swagger是一个接口文档生成工具,同时提供接口测试调用的辅助功能 -
分版本效果展示
- v100版本接口
- v101版本接口
- v100版本接口
-
代码详解
- 好了,版本效果已经展示了,现在我们直接上干货,可以看到我们除了正常的swagger标签外,新增了一个版本@ApiVersion标签, 答案就在这个标签上
@RestController @RequestMapping("/web/swaggerdemo") public class SwaggerDemoController { @ApiOperation(value = "测试demo1", notes = "测试demo1") @ApiImplicitParam(name = "version", value = "版本号, v100", example = "v100", required = true, paramType = "header", dataType = "String") @ApiVersion(group = {"v100"}) @PostMapping("/demo1/{version}") public JsonResultAdapter<SwaggerDemoResponse> demo1(@PathVariable("version") String version) { if ("v100".equals(version)) { SwaggerDemoResponse swaggerDemoResponse = new SwaggerDemoResponse(); swaggerDemoResponse.setDemoValue(1); return JsonResultAdapter.success(swaggerDemoResponse); } return JsonResultAdapter.apiError(); } @ApiOperation(value = "测试demo2", notes = "测试demo2") @ApiImplicitParam(name = "version", value = "版本号, v100", example = "v100", required = true, paramType = "header", dataType = "String") @ApiVersion(group = {"v100", "v101"}) @PostMapping("/demo2/{version}") public JsonResultAdapter<SwaggerDemoResponse> demo2(@PathVariable("version") String version) { if ("v101".equals(version)) { SwaggerDemoResponse swaggerDemoResponse = new SwaggerDemoResponse(); swaggerDemoResponse.setDemoValue(1); return JsonResultAdapter.success(swaggerDemoResponse); } return JsonResultAdapter.apiError(); } }- @ApiVersion, 新增标签ApiVersion
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ApiVersion { /** * 接口版本号(对应swagger中的group) * * @return String[] */ String[] group() default {""}; }- 核心配置, 我们看这段代码,通过判断接口上标签是否包含该标签来实现分版本控制,最后注册到容器中\
@PostConstruct public void postProcessBeanFactory() throws BeansException { List<Docket> list = this.docketFactory(); if (null != list) { list.forEach(o -> configurableListableBeanFactory.registerSingleton(o.getGroupName(), o)); } } public Docket docketInstance(String version, String web) { List<ApiKey> apiKeys = apiSecurity(); return new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo()).select() .apis(o -> { if (null != o) { Optional<ApiVersion> annotation = o.findAnnotation(ApiVersion.class); if (annotation.isPresent() && Arrays.asList(annotation.get().group()).contains(version)) { RequestHandlerKey requestHandlerKey = o.key(); for (String mapping : requestHandlerKey.getPathMappings()) { if (mapping.toLowerCase().startsWith(web)) { return true; } } } } return false; }) .paths(PathSelectors.any()) .build() .groupName(version + "-" + "接口") .ignoredParameterTypes(HttpServletResponse.class, HttpServletRequest.class) .securitySchemes(apiKeys); } public List<Docket> docketFactory() { List<Docket> list = new ArrayList<>(); List<String> versions = swaggerProperties.getVersions(); if (!CollectionUtils.isEmpty(versions)) { versions.forEach(o -> { list.add(this.docketInstance(o, "/web")); }); } return list; }4. 其他配置类
@ConfigurationProperties( prefix = "fant.swagger", ignoreUnknownFields = true ) @Data public class SwaggerProperties { private boolean enable = false; /** * 分组名称是否正序排序 */ private boolean groupAsc = true; /** * 扫描包 */ private String packages = "com.fant.web"; /** * 标题 */ private String title = "默认接口"; /** * 说明 */ private String description = "默认访问接口"; /** * 版本 */ private String version = "1.0.0"; /** * 分组名称 */ private String groupName = "web-api"; /** * url */ private String url = "http://127.0.0.1:8080/"; /** * 接口版本 */ private List<String> versions; private String serviceUrl = "http://127.0.0.1:8080/"; private String licenseUrl = "http://127.0.0.1:8080/"; private String authorName = "fant"; private String authorEmail = "api@xx.com"; private List<String> tokenKeyNames = Arrays.asList("token"); private List<String> authKeyNames = Arrays.asList("Authorization"); public boolean isEnable() { return enable; } public void setEnable(boolean enable) { this.enable = enable; } } -
分组排序
- 上述我们已经介绍了怎么去分版本来展示接口,但是swagger默认排序是升序,这样如果版本多,就会造成我们需要下拉到最后,下面我们介绍下swagger的分组名称排序,通过查看源码得知,排序是在springfox.documentation.swagger.web.InMemorySwaggerResourcesProvider.get()方法中进行排序
- 而swagger的默认排序重写的compareTo方法是根据版本,再根据名称升序排序,所以可以重写该类,然后通过参数配置随时改变分组排序
- 上述我们已经介绍了怎么去分版本来展示接口,但是swagger默认排序是升序,这样如果版本多,就会造成我们需要下拉到最后,下面我们介绍下swagger的分组名称排序,通过查看源码得知,排序是在springfox.documentation.swagger.web.InMemorySwaggerResourcesProvider.get()方法中进行排序