@javazjm
2017-10-30T10:42:35.000000Z
字数 8390
阅读 2683
Springboot
swagger
JApiDocs
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
在Application.java同级创建Swagger2的配置类
@Configuration // 让Spring来加载该类配置
@EnableSwagger2 // 启用Swagger2
public class Swagger2Config {
/**
* 通用配置 生成离线文档不可缺
* @return
*/
@Bean
public Docket configSpringfoxDocket_all() {
return new Docket(DocumentationType.SWAGGER_2)
.produces(Sets.newHashSet("application/json"))
.consumes(Sets.newHashSet("application/json"))
.protocols(Sets.newHashSet("http", "https"))
.apiInfo(apiInfo())
.forCodeGeneration(true)
.select()
.paths(regex("/api.*"))
.build();
}
/**
* 针对user的配置
* @return
*/
@Bean
public Docket createUserRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("user")
.produces(Sets.newHashSet("application/json"))
.consumes(Sets.newHashSet("application/json"))
.protocols(Sets.newHashSet("http", "https"))
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.jimzhang.web")) //扫描指定包下的Controller,并生成文档 (除了被@ApiIgnore指定的请求)
.paths(regex("/api/users.*"))
// .paths(PathSelectors.any())
.build();
}
/**
* 创建基本信息,会展示在文档首页
* @return
*/
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2构建RESTful APIs")
.description("欢迎关注我的博客:http://www.jianshu.com/u/450bfbaff4e3")
.termsOfServiceUrl("http://www.jianshu.com/u/450bfbaff4e3")
.contact(new Contact("Spring官网 ", "https://spring.io/projects", "1539745948@qq.com"))
.version("1.0").build();
}
}
@Api(tags = "用户操作")
@RestController
@RequestMapping(value="/users") // 通过这里配置使下面的映射都在/users下,可去除
public class UserController {
static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());
@ApiOperation(value="获取用户列表", notes="")
@RequestMapping(value={""}, method= RequestMethod.GET)
public List<User> getUserList() {
List<User> r = new ArrayList<User>(users.values());
return r;
}
@ApiOperation(value="创建用户", notes="根据User对象创建用户")
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
@RequestMapping(value="", method= RequestMethod.POST)
public String postUser(@RequestBody User user) {
users.put(user.getId(), user);
return "success";
}
@ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long")
@RequestMapping(value="/{id}", method= RequestMethod.GET)
public User getUser(@PathVariable Long id) {
return users.get(id);
}
@ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long"),
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
})
@RequestMapping(value="/{id}", method= RequestMethod.PUT)
public String putUser(@PathVariable Long id, @RequestBody User user) {
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return "success";
}
@ApiOperation(value="删除用户", notes="根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long")
@RequestMapping(value="/{id}", method= RequestMethod.DELETE)
public String deleteUser(@PathVariable Long id) {
users.remove(id);
return "success";
}
}
http://localhost:8080/swagger-ui.html
swagger2使用说明:
@Api:用在类上,说明该类的作用
@ApiOperation:用在方法上,说明方法的作用
@ApiIgnore:使用该注解忽略这个API
@ApiImplicitParams:用在方法上包含一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
paramType:参数放在哪个地方
header-->请求参数的获取:@RequestHeader
query-->请求参数的获取:@RequestParam
path(用于restful接口)-->请求参数的获取:@PathVariable
body(不常用)
form(不常用)
name:参数名
dataType:参数类型
required:参数是否必须传
value:参数的意思
defaultValue:参数的默认值
@ApiResponses:用于表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModelProperty:描述一个model的属性
<!-- 离线文档依赖 -->
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>1.1.2.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-staticdocs</artifactId>
<version>2.6.1</version>
</dependency>
asciidoctor-maven-plugin插件是用来把Asciidoc格式转成HTML5格式
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--Asciidoctor Maven 插件是一种官方支持的方式,它可以在 Apache Maven 构建过程中使用 Asciidoctor 转化你的 AsciiDoc 文档。-->
<!--https://github.com/asciidoctor/asciidoctor-maven-plugin/blob/master/README_zh-CN.adoc-->
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<configuration>
<!--配置index.adoc的获取路径-->
<!--<sourceDirectory>${asciidoctor.input.directory}</sourceDirectory>-->
<outputDirectory>${asciidoctor.html.output.directory}</outputDirectory>
<sourceDocumentName>index.adoc</sourceDocumentName>
<attributes>
<doctype>book</doctype>
<toc>left</toc>
<toclevels>3</toclevels>
<generated>${generated.asciidoc.directory}</generated>
</attributes>
</configuration>
<executions>
<execution>
<id>output-html</id>
<phase>test</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<attributes>
<snippets>${project.build.directory}/generated-snippets</snippets>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
在Swagger2Config类中新增入下配置:
/**
* 通用配置 生成离线文档不可缺
* @return
*/
@Bean
public Docket configSpringfoxDocket_all() {
return new Docket(DocumentationType.SWAGGER_2)
.produces(Sets.newHashSet("application/json"))
.consumes(Sets.newHashSet("application/json"))
.protocols(Sets.newHashSet("http", "https"))
.apiInfo(apiInfo())
.forCodeGeneration(true)
.select()
.paths(regex("/api.*"))
.build();
}
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
@RunWith(SpringRunner.class)
@SpringBootTest
public class DocumentationBuild {
private String snippetDir = "target/asciidoc/generated-snippets";
private String outputDir = "target/asciidoc";
@Autowired
private MockMvc mockMvc;
@After
public void Test() throws Exception {
// 得到swagger.json,写入outputDir目录中
mockMvc.perform(get("/v2/api-docs").accept(MediaType.APPLICATION_JSON))
.andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
.andExpect(status().isOk())
.andReturn();
// 读取上一步生成的swagger.json转成asciiDoc,写入到outputDir
// 这个outputDir必须和插件里面<generated></generated>标签配置一致
Swagger2MarkupConverter.from(outputDir + "/swagger.json")
.withPathsGroupedBy(GroupBy.TAGS)// 按tag排序
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)// 格式
.withExamples(snippetDir)
.build()
.intoFolder(outputDir);// 输出
}
@Test
public void TestApi() throws Exception {
mockMvc.perform(get("/api/users/1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("查询用户", preprocessResponse(prettyPrint()))); // '查询用户' 名字要与index.adoc 中的一致,否则 生成的文档有误
User userInfo = new User();
userInfo.setId(1L);
userInfo.setName("lisi");
userInfo.setAge(23);
mockMvc.perform(post("/api/users").contentType(MediaType.APPLICATION_JSON)
.content(JSON.toJSONString(userInfo))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful())
.andDo(MockMvcRestDocumentation.document("创建用户", preprocessResponse(prettyPrint())));
mockMvc.perform(get("/api/users")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("获取用户列表", preprocessResponse(prettyPrint())));
User user = new User();
user.setId(1L);
user.setName("张晋苗");
user.setAge(27);
mockMvc.perform(post("/api/users/1").contentType(MediaType.APPLICATION_JSON)
.content(JSON.toJSONString(userInfo))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful())
.andDo(MockMvcRestDocumentation.document("更新用户详细信息", preprocessResponse(prettyPrint())));
mockMvc.perform(post("/api/users/delete/1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("删除用户", preprocessResponse(prettyPrint())));
}
}
运行单元测试文件,会生成*.adoc和swagger.json文档,均不为空
然后进行打包,在target/asciidoc/html 会生成index.html 就是API文档
直接查看index.html即可。
github地址:https://github.com/YeDaxia/JApiDocs
参考:
didi
小柒
https://my.oschina.net/dlam/blog/808315
离线文档: