Swagger
Swagger使用说明
功能简介
Swagger是一套治理API的工具,根据OAS(Open Api Specification)这个描述API的规则,实现API盘点、测试以及归档等功能。目前在wisteria功能中,可以在嵌入很少的侵入代码的情况下实现API的盘点功能——我们可以获取到一个最新的,随时和代码保持同步的API文档。
使用步骤
引入工程依赖
compile “io.springfox:springfox-swagger2:2.9.2”
添加API文档支持
在项目中,采用开开源的springfox支持API信息的采集。
(1)非Spring MVC项目(可以跳过该步骤)
(2)Spring MVC项目
需要在MvcConfig中增加@EnableSwagger2注解,同时注入BeanDocket即可。
@Configuration
@EnableSwagger2
@ComponentScan(basePackages = "com.xxx.frontend",
nameGenerator = FullBeanNameGenerator.class)
@EnableWebMvc
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class MvcConfig extends WebMvcConfigurerAdapter{
@Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(swaggerStatus)
.apiInfo(createDefaultApiInfo())
.groupName(appName + "frontend")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xxx"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo createDefaultApiInfo(){
return new ApiInfoBuilder()
.title(appName)
.description(appName + " frontend api 文档")
.termsOfServiceUrl("http://www.xxx.cn")
.build();
}
}
(3)添加API描述
Springfox定义了一系列的注解,用于更好的描述各个API的内容,包括输入输出以及字段类型和限制等。如果不添加这些内容,API的信息也是可以获取到的,只是不是很全面而已。
描述Controller的注解:
@Api describes the whole controller
@ApiOperation is used for description on a methods level
@ApiParam is used for method parameters
示例:
@RestController
@RequestMapping("/v2/persons/")
@Api(description = "Set of endpoints for Creating, Retrieving, Updating and Deleting of Persons.")
public class PersonController {
private PersonService personService;
@RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = "application/json")
@ApiOperation("Returns a specific person by their identifier. 404 if does not exist.")
public Person getPersonById(@ApiParam("Id of the person to be obtained. Cannot be empty.")
@PathVariable int id) {
return personService.getPersonById(id);
}
}
描述Model的注解:
示例:
{
@ApiModel(description = "Class representing a person tracked by the application.")
public class Person {
@ApiModelProperty(notes = "Unique identifier of the person. No two persons can have the same id.", example = "1", required = true, position = 0)
private int id;
@ApiModelProperty(notes = "First name of the person.", example = "John", required = true, position = 1)
private String firstName;
@ApiModelProperty(notes = "Last name of the person.", example = "Doe", required = true, position = 2)
private String lastName;
@ApiModelProperty(notes = "Age of the person. Non-negative integer", example = "42", position = 3)
private int age;
// … Constructor, getters, setters, ...
}
支持JSR-303
@NotNull 不为空
@NotBlank 不为空 不为空字符串
@Size(min = 1, max = 20) 字符串长度范围
@Min(0) 最小值最大值设置
@Max(100)
@Pattern(regexp = “[SOME REGULAR EXPRESSION]”) 正则表达式设置
做到上面几步就可以在api文档中看到效果了。类似如下:

或者采用不同的展示模板:

Springfox原理
Springfox生成Api文档的原理是,通过获取Spring上下文中@Controller以及@RequestMapping注解的Bean的信息,然后通过层层解析,最终按照Swagger的标准生成Api文档而得来的。
从RequestMappingHandlerMapping的一段源码上面看,就能够理解在@Controller和@ResquestMapping注解到一个Bean或其属性上之后,Spring做了什么,是如何用HandlerMapping将Http请求映射到响应的Bean的方法上的,以及是如何采用HandlerAdapter来处理Http请求的。
RequestMappingHandlerMapping中的两个关键方法:
/**
* {@inheritDoc}
* Expects a handler to have a type-level @{@link Controller} annotation.
*/
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = (element instanceof Class ?
getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
Springfox获取Controller Bean信息的类图:

参考:
https://www.vojtechruzicka.com/documenting-spring-boot-rest-api-swagger-springfox/
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!