微服务之Swagger
spring boot下建议使用:
https://github.com/SpringForAll/spring-boot-starter-swagger
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
Swagger使用
1. Swagger UI
按以下步骤配置,项目启动后访问:
http://localhost:8080/swagger-ui.html
1.1 添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
1.2 配置类
@Configuration
@EnableSwagger2
public class Swagger2 {
public static final String SWAGGER_SCAN_BASE_PACKAGE = "abc.boot.examples.web";
public static final String VERSION = "1.0.0";
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))//api接口包扫描路径
.paths(PathSelectors.any())//可以根据url路径设置哪些请求加入文档,忽略哪些请求
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Swagger2 接口文档示例")//设置文档的标题
.description("更多内容请关注:http://www.abc.com")//设置文档的描述->1.Overview
.version(VERSION)//设置文档的版本信息-> 1.1 Version information
.contact(new Contact("ABC Boot", "http://www.abc.comt", ""))//设置文档的联系方式->1.2 Contact information
.termsOfServiceUrl("www.abc.com")//设置文档的License信息->1.3 License information
.build();
}
}
1.3 注解使用
@ApiOperation
@ApiOperation(value="获取用户列表", notes="获取所有用户列表",produces = "application/json")
@RequestMapping(value="/users", method= RequestMethod.GET)
public List<User> getUserList() {
List<User> r = new ArrayList<User>(users.values());
return r;
}
@ApiResponses
@ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息",produces = "application/json")
// ApiResponses 增加返回结果的描述
@ApiResponses(value = {@ApiResponse(code = 405,message = "Invalid input",response = Integer.class)}) (1)
@ApiImplicitParam(name = "id",value = "用户ID",dataType = "int",paramType = "path") (2)
@RequestMapping(value="/users/{id}", method= RequestMethod.GET)
public User getUser(@PathVariable Integer id) {
return users.get(id);
}
(1) 在默认Response的基础上增加新的Response说明
(2) 使用ApiImplicitParam描述接口参数
@ApiImplicitParams
@ApiOperation(value="更新用户名称", notes="更新指定用户的名称")
@RequestMapping(value="/users/{id}", method= RequestMethod.POST)
@ApiImplicitParams({ (1)
@ApiImplicitParam(name = "id",value = "用户ID",paramType = "path",dataType = "int"), (2)
@ApiImplicitParam(name = "userName",value = "用户名称",paramType = "form",dataType = "string")
})
public void updateUserName(@PathVariable Integer id,@RequestParam String userName){
User u = users.get(id);
u.setName(userName);
}
(1) 使用ApiImplicitParams描述多个参数
(2) 使用ApiImplicitParam时,需要指定paramType,这样也便于swagger ui 生成参数的输入格式。
paramType 有五个可选值 : path, query, body, header, form
@ApiParam
@ApiOperation(value="创建用户-传递简单对象", notes="传递简单对象",produces = "application/json")
@RequestMapping(value="/users-1", method= RequestMethod.POST)
//可以不加ApiParam注解,需要给参数添加描述时可以使用这个注解,或者使用ApiImplicitParams注解 (1)
public Map postUser(@RequestParam String userName,@ApiParam("地址") @RequestParam(required = false) String address) {
User user = new User();
user.setId(Math.round(10));
user.setName(userName);
user.setAddress(address);
users.put(user.getId(), user);
return ImmutableMap.of("user",user);
}
(1) 使用ApiParam描述接口参数
ApiImplicitParam 与 ApiParam 的区别
ApiImplicitParam: This is the only way to define parameters when using Servlets or other non-JAX-RS environments.
- 对Servlets或者非 JAX-RS的环境,只能使用 ApiImplicitParam。
- 在使用上,ApiImplicitParam比ApiParam具有更少的代码侵入性,只要写在方法上就可以了,但是需要提供具体的属性才能配合swagger ui解析使用。
- ApiParam只需要较少的属性,与swagger ui配合更好。
传递复杂对象 By ModelAttribute
@ApiOperation(value="创建用户-传递复杂对象", notes="传递复杂对象DTO, url参数拼接",produces = "application/json")
@RequestMapping(value="/users-2", method= RequestMethod.POST)
//传递对象推荐使用ModelAttribute注解
public Map postUser2(@ModelAttribute User user) { (1)
users.put(user.getId(),user);
return ImmutableMap.of("user",user);
}
(1) ModelAttribute 是Spring mvc的注解,这里Swagger可以解析这个注解,获得User的属性描述
@ApiModel
@ApiModel(value = "User", description = "用户对象")
public class User {
@ApiModelProperty(value = "ID")
private Integer id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "地址")
private String address;
@ApiModelProperty(value = "年龄",access = "hidden")
private int age;
@ApiModelProperty(value = "性别")
private int sex;
.......
}
传递复杂对象 By RequestBody
@ApiOperation(value="创建用户-传递复杂对象", notes="传递复杂对象DTO,json格式传递数据",produces = "application/json")
@RequestMapping(value="/users-3", method= RequestMethod.POST)
//json格式传递对象使用RequestBody注解
public User postUser3(@RequestBody User user) {
users.put(user.getId(),user);
return user;
}
PathVariable
@ApiOperation(value="删除用户- PathVariable", notes="根据url的id来指定删除对象")
@RequestMapping(value="/users/{id}", method = RequestMethod.DELETE)
public void deleteUser(@PathVariable Integer id) { (1)
users.remove(id);
}
(1) PathVariable是Spring 的注解,对于这种简单的参数,就可以不用写ApiParam来描述接口参数。
数组的描述
@ApiOperation(value="删除用户-传递数组", notes="删除对象,传递数组")
@RequestMapping(value="/users/deleteByIds", method = RequestMethod.DELETE)
public void deleteUser(@ApiParam("用户ID数组") @RequestParam Integer[] ids) { (1)
for (int id:ids){
users.remove(id);
}
}
(1) 这里用ApiParam为数组参数添加描述
1.4 可选配置
在application.properties中加入以下配置,用于设置测试请求的host,默认在swagger ui上做请求测试时都是以/users/1为路径发送请求。
如果需要改变请求的根路径,就需要配置这个参数:
springfox.documentation.swagger.v2.host = yourapp.abc.com
配置获取api docs json数据的请求路径 ,默认为/v2/api-docs:
springfox.documentation.swagger.v2.path = /api
2. springfox-staticdocs 生成静态文档

2.1 Maven 配置
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-staticdocs</artifactId>
<version>2.2.2</version>
<scope>test</scope>
</dependency>
2.2 生成json文件
编写Junit测试,这样在测试环节就可以将api-docs的json数据写入文档,便于下一步生成asciidoc文件。
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoBootApplication.class)
public class Swagger2MarkupTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
public void createSpringfoxSwaggerJson() throws Exception {
String outputDir = "src/docs/json"; //将api-docs的json数据写入文件
MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
String swaggerJson = response.getContentAsString();
Files.createDirectories(Paths.get(outputDir));
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8)) {
writer.write(swaggerJson);
}
}
}
2.3 配置Maven Plugin
配置以下两个插件:
swagger2markup-maven-plugin,该插件将json文件转为asciidoc
asciidoctor-maven-plugin, 该插件将asciidoc转为html/pdf
执行Maven命令 : mvn swagger2markup:convertSwagger2markup process-resources
生成的html文档存储在src\main\resources\META-INF\resources\docs目录下。
启动DemoBootApplication,直接访问http://localhost:8080/docs/index.html。
<pluginRepositories>
<pluginRepository>
<id>jcenter-snapshots</id>
<name>jcenter</name>
<url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url>
</pluginRepository>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>jcenter-releases</id>
<name>jcenter</name>
<url>http://jcenter.bintray.com</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<!-- First, use the swagger2markup plugin to generate asciidoc -->
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>${swagger2markup.plugin.version}</version>
<dependencies>
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-import-files-ext</artifactId>
<version>${swagger2markup.extension.version}</version>
</dependency>
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>${swagger2markup.version}</version>
</dependency>
</dependencies>
<configuration>
<!--The URL or file path to the Swagger specification-->
<swaggerInput>${swagger.input}</swaggerInput>
<outputDir>${generated.asciidoc.directory}</outputDir>
<config>
<!--设置输出文件的语言:ASCIIDOC, MARKDOWN, CONFLUENCE_MARKUP-->
<swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
<!--设置目录的展现方式-->
<swagger2markup.pathsGroupedBy>TAGS</swagger2markup.pathsGroupedBy>
<!--扩展Overview的内容,可以增加一些自定义的内容-->
<!--<swagger2markup.extensions.dynamicOverview.contentPath>${project.basedir}/src/docs/asciidoc/extensions/overview</swagger2markup.extensions.dynamicOverview.contentPath>
<swagger2markup.extensions.dynamicDefinitions.contentPath>${project.basedir}/src/docs/asciidoc/extensions/definitions</swagger2markup.extensions.dynamicDefinitions.contentPath>
<swagger2markup.extensions.dynamicPaths.contentPath>${project.basedir}/src/docs/asciidoc/extensions/paths</swagger2markup.extensions.dynamicPaths.contentPath>
<swagger2markup.extensions.dynamicSecurity.contentPath>${project.basedir}src/docs/asciidoc/extensions/security</swagger2markup.extensions.dynamicSecurity.contentPath>-->
</config>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>convertSwagger2markup</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Run the generated asciidoc through Asciidoctor to generate
other documentation types, such as PDFs or HTML5 -->
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.3</version>
<!-- Include Asciidoctor PDF for pdf generation -->
<dependencies>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>1.5.0-alpha.11</version>
</dependency>
<!-- Comment this section to use the default jruby artifact provided by the plugin -->
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>${jruby.version}</version>
</dependency>
<!-- Comment this section to use the default AsciidoctorJ artifact provided by the plugin -->
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj</artifactId>
<version>${asciidoctorj.version}</version>
</dependency>
</dependencies>
<!-- Configure generic document generation settings -->
<configuration>
<!--默认指向 ${basedir}/src/main/asciidoc-->
<sourceDirectory>${asciidoctor.input.directory}</sourceDirectory>
<!--an override to process a single source file; 默认指向 ${sourceDirectory} 中的所有文件-->
<!--<sourceDocumentName>index.adoc</sourceDocumentName>-->
<attributes>
<doctype>book</doctype>
<toc>left</toc>
<toclevels>3</toclevels>
<numbered></numbered>
<hardbreaks></hardbreaks>
<sectlinks></sectlinks>
<sectanchors></sectanchors>
<generated>${generated.asciidoc.directory}</generated>
</attributes>
</configuration>
<!-- Since each execution can only handle one backend, run
separate executions for each desired output type -->
<executions>
<execution>
<id>output-html</id>
<phase>generate-resources</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html5</backend>
<outputDirectory>${asciidoctor.html.output.directory}</outputDirectory>
</configuration>
</execution>
<!-- 生成PDF -->
<!--<execution>
<id>output-pdf</id>
<phase>generate-resources</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>pdf</backend>
<outputDirectory>${asciidoctor.pdf.output.directory}</outputDirectory>
</configuration>
</execution>-->
</executions>
</plugin>
</plugins>
</build>
3. 其他说明
3.1 如何修改/v2/api-docs路径?
swagger-ui是通过获取接口的json数据渲染页面的,即通过swagger的注解将生成接口的描述服务,默认地址为/v2/api-docs,如果需要改变这个请求地址,可以在properties中配置springfox.documentation.swagger.v2.path。
3.2 如何设置所有请求的统一前缀?
默认请求都是以 / 根路径开始,如果我们的应用不是部署在根路径,比如以/platform部署,则可以通过一下方式设置请求的统一前缀。
@Bean
public Docket createV1RestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
.paths(PathSelectors.any())
.build()
.pathMapping("/platform"); // 在这里可以设置请求的统一前缀
}
3.3 接口文档中1.4和1.5的信息生成
接口文档中的 1.4和 1.5 则通过以下方式生成:
1.4 URI scheme
// 可以通过在properties中设置 springfox.documentation.swagger.v2.host属性
Host : localhost
// 待确认
BasePath : /
该Host也是swagger-ui发送测试请求的Host, 通常我们会将将接口文档部署在测试服务器,这样就需要设置Host,
否则请求都是通过localhost发送,请求不到测试服务器的接口。
1.5 Tags
@Api(value = "/v1/users",tags = "Users",description = "用户接口V1")
tags由Api注解的tags标签设置,如果不设置,则以类名作为tag
3.4 设置响应对象的Example
通过ApiModelProperty注解的example属性设置响应对象的示例:
@ApiModelProperty(value = "ID",example = "1")
private Integer id;
@ApiModelProperty(value = "姓名",example = "Admin")
private String name;
@ApiModelProperty(value = "地址",example = "171")
private String address;
@ApiModelProperty(value = "年龄",access = "hidden",example = "20")
private int age;
@ApiModelProperty(value = "性别",example = "1")
private int sex;
@ApiModelProperty(value = "生日",example = "2000-10-22")
链接
http://www.jianshu.com/p/b730b969b6a2
微服务之Swagger的更多相关文章
- springcloud+gateway微服务整合swagger
单一的微服务集成swagger: maven: <dependency> <groupId>io.springfox</groupId> <artifactI ...
- 使用 Zuul 聚合多个微服务的 Swagger 文档
在 Spring Boot 中集成 Swagger 可参考之前的文章:Spring Boot 2 集成 Swagger, 在各个微服务中的配置与之相同:本文仅介绍在 Zuul 中的配置 在 Zuul ...
- Ocelot网关统一查看多个微服务asp.net core项目的swagger API接口
0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 一.准备 前提需要下载安装consul,项目需要懂添加swagger 统一在网关中配置多个微服务的swagger,需要用到服务注册 ...
- 微服务电商项目发布重大更新,打造Spring Cloud最佳实践!
Spring Cloud实战电商项目mall-swarm地址:转发+关注 私信我获取地址 系统架构图 系统架构图 项目组织结构 mall├── mall-common-- 工具类及通用代码模块├─ ...
- 使用 ASP.NET Core 3.1 的微服务开发指南
使用 ASP.NET Core 3.1 的微服务 – 终极详细指南 https://procodeguide.com/programming/microservices-asp-net-core/ A ...
- 微服务架构下使用Spring Cloud Zuul作为网关将多个微服务整合到一个Swagger服务上
注意: 如果你正在研究微服务,那必然少不了服务之间的相互调用,哪么服务之间的接口以及api就必须生成系统的管理文档了.如果你希望更好的管理你的API,你希望有一个工具能一站式地解决API相关的所有事情 ...
- 分享一个集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo+SkyWalking的微服务开发框架
集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo的微服务开发框架 Github源代码地址 htt ...
- .Net Core微服务入门全纪录(完结)——Ocelot与Swagger
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 前言 上一篇[.Net Core微服务入门全纪录(八)--Docker Compose与容器网络]完成了docker-compose.y ...
- .NET Core 中的 Swagger 应用与微服务场景下的Swagger Api 集成显示
Swagger 与 OpenAPI 的历史来源: Swagger 项目于 2015 年捐赠给 OpenAPI Initiative,此后被称为 OpenAPI.这两个名称可以互换使用.但是," ...
随机推荐
- Vue#组件
组件: 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能. 使用: ...
- ListView列表的简单案例
在android开发中ListView它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示.抽空把对ListView的使用做了整理,并写了个小例子 列表示例图: BaseActivity pa ...
- call()与apply()
1.obj1.method1.call(obj2,argument1,argument2) call的作用就是把obj1的方法放到obj2上使用 2. add 来替换 sub,add.call(sub ...
- python split函数
Python split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串 例 current_month = "2013-01-02" y ...
- 浅谈Margin和Padding值设置成百分数的布局
转自:问说网http://www.uedsc.com/discussion-margin-and-padding-values.html Margin和Padding是我们在网页设计经常使用到的CSS ...
- java-集合3
浏览以下内容前,请点击并阅读 声明 Queue接口(队列) 需要对一些列的元素进行处理前,我们可以把他们放到Queue对象中,除了继承Collection接口的方法外,队列还有一些插入,删除和检查操作 ...
- CodeForces 515C. Drazil and Factorial
C. Drazil and Factorial time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- jquery:closest和parents的主要区别
closest和parents的主要区别是:1,前者从当前元素开始匹配寻找,后者从父元素开始匹配寻找:2,前者逐级向上查找,直到发现匹配的元素后就停止了,后者一直向上查找直到根元素,然后把这些元素放进 ...
- 【转】前端工程筹建NodeJs+gulp+bower
转自:http://www.myexception.cn/javascript/1781968.html npm nodejs 安装过程中会自动安装npm,nodejs安装程序会在环境变量中添加两个变 ...
- 在AngularJs中怎么设置请求头信息(headers)及不同方法的比较
在AngularJS中有三种方式可以设置请求头信息: 1.在http服务的在服务端发送请求时,也就是调用http()方法时,在config对象中设置请求头信息:事例如下: $http.post('/s ...