前面写过一篇如何建立 一个最基础的 Spring 4 MVC Maven 项目,现在是要在此基础上使用 SpringFox 来生成 Swagger 文档以及 SwaggerUI。Swagger 2 是基于 OpenAPI3.0 的实现,SpringFox 是用于在 Spring 项目中生成 Swagger 文档及 UI, 主要包括两个组件 springfox-swagger2
和 springfox-swagger-ui
。
本文是基于普通的 Spring MVC 项目的实例,而非针对 SpringBoot 项目,实际运用应该大同小异,无外乎 SpringBoot 中有许多自动配置项。并且本文也不涉及到 Swagger 众多注解的具体用法,具体请查看源代码或相关文档。
开始本文的示例,首先需要搭建起 Spring MVC 项目,具体做法请参考 一个最基础的 Spring 4 MVC Maven 项目。
对应于两个组件 springfox-swagger2
和 springfox-swaager-ui
的应用,从大尺度上讲有两方面的内容,分别是
一:生成 Swagger 2 的 JSON API 文档
使用第一个组件 springfox-swagger2
能够让项目运行期自动生成 Swagger 2 的 JSON API 文档,分两步走
添加 springfox-swagger2 依赖
在项目的 pom.xml 文件中加入依赖配置
1 2 3 4 5 |
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> |
截止目前,springfox 官方已释放出 springfox-swagger2:2.9.0, 但是在 Maven 的中央仓库中只有 2.8.0 版,所就采用 2.8.0 版本
Spring 的 Java Config 中启用 @EnableSwagger2
如今多用 Java 代码作为 Spring 的配置,在 Java Config 中类上面加上注解 @EnableSwagger2, 如下
1 2 3 4 5 |
@EnableWebMvc @EnableSwagger2 @ComponentScan(basePackages= "controller") public class WebAppConfig { } |
假设项目中已创建有 UserController,并且应用的上下文是 "swagger-test", 这时候用 mvn tomcat7:run
启动 Tomcat,我们就可以访问 URL http://localhost:8080/swagger-test/v2/api-docs
这就是一个符合 OpenAPI3 的 Swagger2 的 API 描述文档,我们可以通过第三方的 SwaggerUI 来引入该文档进行展示,比如官方的 SwaggerUI 可以从这里下载 https://swagger.io/download-swagger-ui/。
如果是多个系统的 API 描述文件要集中一个中心 UI 去显示的话,那么我们让 springfox-swagger2 在运行期产生 /v2/api-docs
内容就足够了。
要是仍然觉得要更多担当,当前应用中还想把 SwaggerUI 也托管起来的话,我们还有 springfox-swagger-ui 值得一试,就是接下来的任务
二:启动 SwaggerUI 展示前面生成的 JSON 文档
这里要用到第二个组件 springfox-swagger-ui
, 当然 springfox-swagger2
是它的前提。这个 SwaggerUI 不仅漂亮的归类显示了所有的 API, 关键它还非常实用,你可以通过该 UI 发送实实在在的 HTTP 请求,对每一个 API 进行在线测试,这是非开发人员喜爱的功能。
有两个步骤
添加 springfox-swagger-ui 依赖
在 pom.xml 文件中加上
1 2 3 4 5 |
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> |
同样的原因,采用 2.8.0 版本
暴露 /swagger-ui.html
页面
为了使得 /swagger-ui.html
页面有效,必须完善前面的 WebAppConfig
配置类,完整代码如下
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 |
@EnableWebMvc @EnableSwagger2 // v2/api-docs @ComponentScan(basePackages = {"controller"}) public class WebAppConfig extends WebMvcConfigurerAdapter { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder().title("RESTful API document").version("2.0") .contact(new Contact("Yanbin", "http://localhost:8080/", "fantasia@sina.com")).build(); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } } |
其中上面加亮的方法 addResourceHandlers(...)
将会激活 /swagger-ui.html
页面。其余两个方法只是润色 Swagger JSON 文件内容的,是可选的,当然也会展示在 UI 上的。
为了让 /swagger-ui.html
获得更诱人的显示效果,将创建两个 Controller 类 -- UserController 和 OrderController。由于本例重点不在代码本身,因而以图片方式显示代码
有了这两个 Controller 类,以及足够覆盖常见的 HTTP method 之后,再来浏览一下 http://localhost:8080/swagger-ui.html
非常写意的不同颜色表现了 HTTP 的各种不同操作的准确含义。想当年我还是在没听说过 Swagger 的情况下在网络上千辛万苦找啊找,记录了这篇 如果要给 RESTful 每种 HTTP Method 类型指示一种颜色。2014 年写的,这算是与 Swagger 的首回合交上运。对比前后两张图,现在的颜色比之从前更显圆润了。
上面的 swagger-ui, 点击每一个条目,可以展开,可以看到参数的具体描述,样例,填入参数,发送请求,可以看到完整的请求响应数据。另外关于 Swagger 的注解,如 @Api, @ApiImplicitParam, @ApiModel, @ApiOperation, @ApiParam, @ApiResponse, @Tag 等不在本文讨论之列。
链接:
- Setting Up Swagger 2 with a Spring REST API
- Springfox Reference Documentation
- 使用springfox+swagger2书写API文档
[2018-05-03]: 目前想要使用 springfox-swagger2:2.9.0 或 springfox-swagger-ui:2.9.0, 需在 pom.xml 文件中加上第三方的 Maven 仓库
1 2 3 4 5 6 |
<repositories> <repository> <id>springfox-repo</id> <url>https://dl.bintray.com/springfox/maven-repo/</url> </repository> </repositories> |
[2021-10-18]: WebMvcConfigurerAdapter
已被 Deprecated, 请使用接口 WebMvcConfigurer
替代,因为接口中有默认实现方法,它与原来的类效果是一样的。
我们项目中正在使用的就是这个。
有个问题想请教,我想加载到实现某个接口所有实现类或者继承某个类的所有子类,不依赖Spring的话,有什么好的思路能读取到吗?我看到网上有一些,是根据当前接口文件或者抽象类的路径类获取的,这样不太靠谱。
用 google 搜索 "java list all subclasses", https://www.google.com/search?q=java+list+all+subclasses&oq=list+all+subclass&aqs=chrome.1.69i57j0l5.7438j1j1&sourceid=chrome&ie=UTF-8
https://stackoverflow.com/questions/492184/how-do-you-find-all-subclasses-of-a-given-class-in-java?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
别告诉我作为技术人员还用百度找技术资料哦
?没办法,国内现在vpn都很难上都,几乎很多都被禁掉了
我们自己把自己束缚了起来。
Field field = ClassLoader.class.getDeclaredField("classes");
field.setAccessible(true);
List<Class> vector = (List<Class>)field.get(ClassLoader.getSystemClassLoader());
List<Class> classes = new ArrayList<>();
for(Class clazz : vector){
if(Super.class.isAssignableFrom(clazz) && !clazz.equals(Super.class)){
classes.add(clazz);
System.out.println(clazz.getSimpleName());
}
}
我现在用这种方式实现的,没有用第三方的包来实现,不知道你有没有更好的方式,如果不用第三方,如何去优化下,因为现在这种情况,会加载所有的类进来,然后要遍历把所有的子类过滤出来,感觉性能不高,虽然时间来讲很快。
如果是启动那一些全部加载,其实很快的,有些第三方库也是这么做的。
嗯,我看了一下时间,还是挺快的,暂时打算就先这样了