翻译自https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X#apiimplicitparam-apiimplicitparams.
水平有限,不保证翻译准确,仅做自己学习记录之用。

Api资源声明

@Api

1
2
3
4
5
6
7
8
@Path("/pet")
@Api(value = "pet", authorizations = {
@Authorization(value="sampleoauth", scopes = {})
})
@Produces({"application/json", "application/xml"})
public class PetResource {
...
}

在这个例子中我们可以看出,@Api标签下的所有操作都属于pet类(所有这些操作可以放在一起)。Swagger会选用@Produces标签下的值,但是你也可以根据需要进行覆盖。@Api也可以用于声明资源级别的权限。这些声明可以作用于其下的所有操作,但是这些操作也可以根据需要被重写。
除了用value(),也可以使用tags()来为操作设置多个tags,例如:

1
@Api(tags = {"external_info","user_info"})

此时,如果存在value()属性,将会被忽略。
布尔属性hidden可以用来完全隐藏一个@Api。当使用子资源删除不必要的工件这尤其有用。
更多请参见:javadocs

操作声明

@ApiOperation

@ApiOperation用于声明单个操作。该操作应该是路径与HTTP方法的唯一结合。

1
2
3
4
5
6
7
@GET
@Path("/findByStatus")
@ApiOperation(value = "Finds Pets by status",
notes = "Multiple status values can be provided with comma seperated strings",
response = Pet.class,
responseContainer = "List")
public Response findPetsByStatus(...) { ... }
  • value属性是对这个API的简短描述,最后控制在120个字符以内。

  • notes属于可以对操作进行详细说明。

  • response是方法的返回类型,需要注意的是实际的方法声明返回的是一个通用的JAX-RS的类,而不是实际发送给用户的响应。如果返回的对象是实际的结果,它可以不用背声明直接被使用。

  • responseContainer用于返回一个list。记住Java具有类型擦除功能,因此在返回结果中使用泛型可能导致结果不能被正确解析,所以response应该被直接使用。

  • @Get和@Path标签分别用于操作HTTP方法和告诉我们方法的路径。

以上生成的API为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"/pet/findByStatus": {
"get": {
"tags": [
"pet"
],
"summary": "Finds Pets by status",
"description": "Multiple status values can be provided with comma seperated strings",
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
},
...

更多请参见:javadocs

@ApiResponses, @ApiResponse

众所周知可以使用HTTP状态码返回错误或成功信息。返回的类型已经在@ApiOperation定义了,其余的返回码可以在@ApiResponses, @ApiResponse标签中描述。

@ApiResponse用于描述一个操作的可能返回结果。它不能直接被方法,类或者接口使用而需要作为一列值被@ApiResponses包含。
如果响应伴随了一个body,那这个body模型也可以被描述。

1
2
3
4
5
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid ID supplied",
responseHeaders = @ResponseHeader(name = "X-Rack-Cache", description = "Explains whether or not a cache was used", response = Boolean.class)),
@ApiResponse(code = 404, message = "Pet not found") })
public Response getPetById(...) {...}

@Authorization, @AuthorizationScope

这两个标签仅仅作为@Api和@ApiOperation的输入使用,不能直接用于资源和操作。一旦在API里声明和配置了授权模式,你可以将该标签用于需要的资源或某个操作上。具体使用如下:

1
2
3
4
5
6
7
8
9
@ApiOperation(value = "Add a new pet to the store",
authorizations = {
@Authorization(
value="petoauth",
scopes = { @AuthorizationScope(scope = "add:pet") }
)
}
)
public Response addPet(...) {...}

在上述例子中,我们声明addPet操作使用了授权模式,然后使用@AuthorizationScope对add:pet进行范围的调整。正如上面提到的,我们可以发现@AuthorizationScope被用作了@Authorization的一个输入,进一步可以作为@ApiOperation的输入。
以上生成的API为:

1
2
3
4
5
6
7
"security": [
{
"petoauth": [
"add:pet"
]
}
]

@ApiParam

@ApiParam只能作为JAX-RS参数标签使用(@PathParam, @QueryParam, @HeaderParam, @FormParam, JAX-RS 2中 @BeanParam)。当swagger-core扫描这些标签时,@ApiParam可以被用于增加更多参数的细节或者改变从代码中读取的值。
Swagger采用注解的value()值作为参数名,并且会基于注解设置参数类型。
Swagger也会使用@DefaultValue的值作为默认值。

1
2
3
4
5
6
@Path("/{username}")
@ApiOperation(value = "Updated user",
notes = "This can only be done by the logged in user.")
public Response updateUser(
@ApiParam(value = "name that need to be updated", required = true) @PathParam("username") String username,
@ApiParam(value = "Updated user object", required = true) User user) {...}

如上面的例子所示,我们有两个参数。第一个username是路径的一部分,另一个是User对象,上例中作为body。两个参数都将quired属性设置为了true。@PathParam,尽管是多余的,但是因为它是默认强制毕业有点,且不能被覆盖。
以上生成的API为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"parameters": [
{
"name": "username",
"in": "path",
"description": "name that need to be deleted",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "Updated user object",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}
]

@ApiImplicitParam, @ApiImplicitParams

你可能希望手动对操作的参数进行描述,可能的理由有以下:

  • 使用了没有采用JAX-RS标签的Servlets。

  • 想隐藏一个参数,因为它已经被定义并且希望用完全不同的定义进行覆盖。

  • 描述一个被过滤器或者其他资源优先获取的JAX-RS的实现类。

@ApiImplicitParams可以有多个@ApiImplicitParams进行定义多个参数,注意这个注解@ApiImplicitParam必须被包含在注解@ApiImplicitParams之内。。

当隐式定义多个参数时,name,dataType和paramType的定义是最重要的。

1
2
3
4
5
6
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "User's name", required = true, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "email", value = "User's email", required = false, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "id", value = "User ID", required = true, dataType = "long", paramType = "query")
})
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {...}

在上例中,我们可以看到一个servlet定义和几个参数,dataType既可以是一个原语(primitive)也可以是一个类名。paramType可以是Swagger支持的任意类型的参数。

生成API为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"parameters": [
{
"name": "name",
"description": "User's name",
"required": true,
"type": "string",
"in": "query"
},
{
"name": "email",
"description": "User's email",
"required": false,
"type": "string",
"in": "query"
},
{
"name": "id",
"description": "User ID",
"required": true,
"type": "integer",
"format": "int64",
"in": "query"
}
]

ApiImplicitParam 与 ApiParam 的区别:

  • 对Servlets或者非 JAX-RS的环境,只能使用 ApiImplicitParam。

  • 在使用上,ApiImplicitParam比ApiParam具有更少的代码侵入性,只要写在方法上就可以了,但是需要提供具体的属性才能配合swagger ui解析使用。

  • ApiParam只需要较少的属性,与swagger ui配合更好。

@ResponseHeader

如果你需要描述一个响应头(response header),你可以提供的响应头的名称、描述和类型,简单地将它添加到@ApiOperation或@ApiResponse中。
例如在一个给出的响应中是这样的:

1
2
3
4
5
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid ID supplied",
responseHeaders = @ResponseHeader(name = "X-Rack-Cache", description = "Explains whether or not a cache was used", response = Boolean.class)),
@ApiResponse(code = 404, message = "Pet not found") })
public Response getPetById(...) {...}

Model声明

@ApiModel

Swagger-core基于引用API内省的方式构建模型定义。@ApiModel允许操作模型的元数据从一个简单的描述或名称变为一个多态的定义。
最基础的功能如下,使用@ApiModel改变一个模型的名称并为其添加描述:

1
2
@ApiModel(value="DifferentModel", description="Sample model for the documentation")
class OriginalModel {...}

上例我们改变模型的名称,输出结果为

1
2
3
4
"DifferentModel": {
"description": "Sample model for the documentation",
...
}

还可以使用@ApiModel通过指定子类型实现模型组成:

1
2
3
@ApiModel(value = "Pet", subTypes = {Cat.class})
public class Pet {
}

@ApiModelProperty

尽管swagger-core会内省字段和setters/getters,它也可以读取和处理JAXB注释。@ApiModelProperty允许通过控制Swagger-specific定义被允许的值和增加的注解。它还提供了额外的过滤性能,以防你在某些情况下想隐藏属性。

1
2
3
4
@ApiModelProperty(value = "pet status in the store", allowableValues = "available,pending,sold")
public String getStatus() {
return status;
}

上例为一个模型熟悉添加了描述,此外我们可以发现,虽然status是一个String类型,但是我们证明了他只有三个可能值。API输出为:

1
2
3
4
5
6
7
8
9
10
11
12
"properties": {
...,
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
}

Swagger Definition

@SwaggerDefinition

SwaggerDefinition注解提供了许多与Swagger对象的顶级属性相关的属性,可以在自动生成的定义里设置这些属性。SwaggerDefinition注解可以加在任意类上,会在Swagger自动配置过程中国被扫描。此外,它可以用于标记/配置接口上,而不必须用于JAX-RS API类,例如:

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
@SwaggerDefinition(
info = @Info(
description = "Gets the weather",
version = "V12.0.12",
title = "The Weather API",
termsOfService = "http://theweatherapi.io/terms.html",
contact = @Contact(
name = "Rain Moore",
email = "rain.moore@theweatherapi.io",
url = "http://theweatherapi.io"
),
license = @License(
name = "Apache 2.0",
url = "http://www.apache.org/licenses/LICENSE-2.0"
)
),
consumes = {"application/json", "application/xml"},
produces = {"application/json", "application/xml"},
schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
tags = {
@Tag(name = "Private", description = "Tag used to denote operations as private")
},
externalDocs = @ExternalDocs(value = "Meteorology", url = "http://theweatherapi.io/meteorology.html")
)
public interface TheWeatherApiConfig {
}

上例所示的所有属性都会使相关元数据被添加到生成的swagger.json/swagger.yaml文件中。
如果添加了多个@SwaggerDefinition注解,他们会被按照顺序聚合——当出现重复的属性,将会出现覆盖。

@Info

@Info注释添加通用的元数据属性定义——Info对象对应的规范。例如:

1
2
3
4
5
6
7
8
9
@SwaggerDefinition(
info = @Info(
description = "Gets the weather",
version = "V12.0.12",
title = "The Weather API",
termsOfService = "http://theweatherapi.io/terms.html",
...
),
...

@Contact

@Contact标签为@Info添加了contract属性——与Contract对象一样的规范。例如:

1
2
3
4
5
6
7
8
9
10
11
@SwaggerDefinition(
info = @Info(
...
contact = @Contact(
name = "Rain Moore",
email = "rain.moore@theweatherapi.io",
url = "http://theweatherapi.io"
),
...
),
...

@License

@License标签为@Info添加了license属性——与license对象一样的规范。例如:

1
2
3
4
5
6
7
8
9
@SwaggerDefinition(
info = @Info(
...
license = @License(
name = "Apache 2.0",
url = "http://www.apache.org/licenses/LICENSE-2.0"
)
),
...

@Extension

extension标签允许为Swagger定义添加扩展属性。目前支持在@ApiOperation @Info和@Tag注释。有两种方法可以使用它:

1
2
3
4
5
6
7
8
...
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "test1", value = "value1"),
@ExtensionProperty(name = "test2", value = "value2")
})
}
...

这种方法得到的是:

1
2
3
4
...
"x-test1" : "value1",
"x-test2" : "value2"
...

如果注释中没有明确说明,属性名会自动加上前缀“x-”。
另外一种方法可以命名扩展属性:

1
2
3
4
5
6
7
8
...
extensions = {
@Extension( name = "my-extension", properties = {
@ExtensionProperty(name = "test1", value = "value1"),
@ExtensionProperty(name = "test2", value = "value2")
})
}
...

会得到将扩展属性包裹在json对象中:

1
2
3
4
5
6
...
"x-my-extension" : {
"test1" : "value1",
"test2" : "value2"
}
...

@ExtensionProperty

这并不是一个独立的扩展属性,用法详见@Extension的例子。

定制Swagger定义

如果现有的标签都不适用,你需要自定义标签,你可以使用Swagger引擎,ReaderListener提供了相关回调函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface ReaderListener {
/**
* Called before the Swagger definition gets populated from scanned classes. Use this method to
* pre-process the Swagger definition before it gets populated.
*
* @param reader the reader used to read annotations and build the Swagger definition
* @param swagger the initial swagger definition
*/
void beforeScan(Reader reader, Swagger swagger);
/**
* Called after a Swagger definition has been populated from scanned classes. Use this method to
* post-process Swagger definitions.
*
* @param reader the reader used to read annotations and build the Swagger definition
* @param swagger the configured Swagger definition
*/
void afterScan(Reader reader, Swagger swagger);
}

当类在进行资源扫描中发现该注释,自定义的注释会被被实例化并进行相应的调用。例如:

1
2
3
4
5
6
7
public class BasePathModifier implements ReaderListener {
void beforeScan(Reader reader, Swagger swagger){}
void afterScan(Reader reader, Swagger swagger){
swagger.setBasePath( System.getProperty( "swagger.basepath", swagger.getBasePath() ));
}
}