Swagger2API接口文档自动生成工具
1. SpringBoot集成Swagger2
1)、第一步,导入pom
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<!-- END Swagger -->
2)编写SwaggerConfig.java配置类
package com.alibaba.api2doc.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()).
select().
apis(RequestHandlerSelectors.basePackage("com.alibaba.api2doc.controller")).
paths(PathSelectors.any()).
build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("测试swagger2")
.description("XXX测试swagger2").
termsOfServiceUrl("http://www.java-mindmap.com")
.version("1.0")
.build();
}
}
3)访问API接口文档路径
访问路径:http://localhost:port/swagger-ui.html
4)页面显示效果:
2.swagger2常用注解
swagger通过注解表明该接口文档会生成文档,包括接口名,请求方法,参数,返回信息的等等。
@Api修饰整个类,描述controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:当接收参数为对象时
@ApiProperty:用对象接收参数时,描述对象的一个字段
@ApiRespose:HTTP响应其中1个描述
@ApiResponses:HTTP响应整体描述
@ApiIgnore:使用该注解忽略这个API
@ApiError:发生错误返回的信息
@ApiImplicitParam:一个参数请求
@ApiImplicitParams:多个请求
详细解释:
@Api:用在请求类上,表示对类的说明
tags=“说明该类的作用,可以在UI界面上看到的注解”
value=“该参数没什么意义,在UI界面上也看到,所以不需要配置”
@ApiOperation:用在请求的方法上,说明方法的用途,作用
value=“说明方法的用途,作用”
notes=“方法的备注说明”
@ApiImplicitParams:用在请求的方法上,表示一组参数的说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
name:参数名
value:参数的汉字说明
required:参数放在哪个地方
- header:请求参数的获取 @RequestHeader
- query:请求参数的获取 @RequestParam
- path:(用于Restful接口)
- body(不常用)
- form(不常用)
dataTye:当参数为对象类型时指定参数类型
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息(实际上任何相应信息都可以)
code:数字,例如400
message:信息,例如“请求参数没填写正确”
response:抛出的异常类
@ApiModel:用于响应类上,表示一个返回响应数据的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParams注解进行描述的时候)
@ApiModelProperty:用在属性上,描述响应类的属性
Swagger细节问题
- @ApiParam与@ApiImplicitParam的区别
查看源码的注释部分:
ApiParam.java:
/**
* Adds additional meta-data for operation paramters
* <p/>
*This annotations can be used only in combination of JAX-RS 1.x/2.x annotations
*/
ApiImplicitParam.java
/**
*Represents a single parameter in an API Operation
*<p/>
* While {@link ApiParam} is bound to a JAX-RS parameter,
* method or field, this allows you to manually define a parameter in a fine-tuned manner.
* This is the only way to define parameters when using Servlets or other non-JAX-RS
* environments.
* <p/>
* This annotation must be used as a value of {@link ApiImplicitParams}
* in order to be parsed.
*
* @see ApiImplicitParams
*/
就是说,@ApiParam和@ApiImplicitParam的功能时相同的,但是@ApiImplicitParam的适用范围更广。在非JAX-RS的场合(比如说使用servlet提供HTTP接口),只能使用@ApiImplicitParam进行说明。我认为,这是因为接口并不显式展示入参的名称,所以也没有地方去使用@ApiParam,只能在接口的方法声明下方写@ApiImplicitParam
- 当接收参数为基本数据类型时,在@ApiImplicitParam注解重的dataType不需要解释说明,否则导致Swagger找不到解释类型而出现错误提示信息
- 当自己的项目中使用到Gson转换器时(一般会用于去转换时间格式在HttpMessageConverters中),会导致http://localhost:port/v2/api-docs请求中返回的数据被自动转换为gson格式导致swagger的UI组件无法识别解析,出现No operations defined in spec 错误,需要进行json的适配
package com.alibaba.aop.config;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import springfox.documentation.spring.web.json.Json;
import java.lang.reflect.Type;
public class SpringfoxJsonToGsonAdpter implements JsonSerializer<Json> {
@Override
public JsonElement serialize(Json json,Type type,JsonSerializationContext context){
final JsonParser parser=new JsonParser();
return parser.parse(json.value());
}
}
@Bean
public HttpMessageConverters customConverters() {
Collection<HttpMessageConverter<?>> messageConverters = Lists.newArrayList();
GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
gsonHttpMessageConverter.setGson(new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").registerTypeAdapter(Json.class,new SpringfoxJsonToGsonAdpter()).create());
messageConverters.add(gsonHttpMessageConverter);
return new HttpMessageConverters(true, messageConverters);
}
-
同名问题
@Api同名问题,因为swagger会根据tags的名称查找对象,由同名对象的时候,swagger的文档就会出现问题。如果swagger的某个API下出现不属于该API的请求,这个就是API的同名的问题,查找相同的API名称替换即可
@ApiModelProperty相同name值问题,当使用@ApiModelProperty注解一个对象的属性和该对象中的对象属性的属性时,因为有相同类型字段,如果通过相同的name值说明时会导致name值冲突导致只会内部对象的属性会被显示出来 -
当http请求路径为非value=“/路径名”格式而是params=“name=value”时,Swagger2会无法识别出来该接口。
-
泛型问题:这个问题很无解的,我之前追过源码,在我追过的那一版中,发现的是因为当是Swagger2生成接口文档时,主要是通过切面和反射的原理来解析方法和参数上面的注解来获取接口的具体信息,但是好像只解析到了具体是哪一个类的层面,并没有解析到类中泛型具体是什么。