核心是 Swagger/OpenAPI 框架(常用的有 Swagger2 和 SpringDoc OpenAPI)用来生成可视化 API 文档的注解,主要作用是给接口、参数、响应等添加说明,让接口文档更清晰易读。我会以最常用的 Spring Boot + Swagger2 (knife4j 增强版) 为例,讲清楚核心注解的用法、场景和示例,新手也能直接套用。
一、先明确:注解的归属和前置条件
- 核心注解包:
io.swagger.annotations(Swagger2) /io.swagger.v3.oas.annotations(OpenAPI 3.0+) - 常用增强版:knife4j(基于 Swagger,UI 更友好),注解用法和原生 Swagger 一致。
- 前置:Spring Boot 项目中需引入 Swagger/knife4j 依赖(比如 knife4j-spring-boot-starter),并做基础配置。
二、核心 @Api 系列注解全解析(按使用场景分类)
1. 类级别注解:描述 Controller 整体
| 注解 | 作用 | 核心属性 & 示例 |
|---|---|---|
@Api |
标记 Controller,说明接口模块 | tags:模块名称(必填);description:模块描述(可选)java<br>@RestController<br>@Api(tags = "用户地址管理", description = "用户收货地址的增删改查接口")<br>@RequestMapping("/address")<br>public class AddressController { ... }<br> |
@ApiIgnore |
忽略整个 Controller / 方法 | 标记后,该 Controller 不会出现在 API 文档中java<br>@ApiIgnore<br>@RestController<br>@RequestMapping("/admin/internal")<br>public class InternalController { ... }<br> |
2. 方法级别注解:描述单个接口
| 注解 | 作用 | 核心属性 & 示例 |
|---|---|---|
@ApiOperation |
描述接口的功能 | value:接口简要说明;notes:详细说明;httpMethod:请求方式(GET/POST 等,可选)java<br>@GetMapping("/list")<br>@ApiOperation(value = "查询用户地址列表", notes = "根据用户ID查询该用户的所有收货地址,支持分页")<br>public Result<Page<Address>> list(@RequestParam Long userId) { ... }<br> |
@ApiResponses |
批量定义接口的响应状态 | 配合 @ApiResponse 使用,描述不同 HTTP 状态码的含义java<br>@PostMapping("/add")<br>@ApiOperation(value = "新增地址")<br>@ApiResponses({<br> @ApiResponse(code = 200, message = "新增成功"),<br> @ApiResponse(code = 400, message = "参数错误(比如用户ID为空)"),<br> @ApiResponse(code = 500, message = "服务器内部错误")<br>})<br>public Result<Void> add(@RequestBody AddressDTO addressDTO) { ... }<br> |
3. 参数级别注解:描述接口参数
| 注解 | 作用 | 核心属性 & 示例 |
|---|---|---|
@ApiParam |
描述单个参数(适用于 RequestParam/PathVariable 等) | name:参数名;value:说明;required:是否必填;example:示例值java<br>@GetMapping("/detail")<br>@ApiOperation(value = "查询地址详情")<br>public Result<Address> detail(<br> @ApiParam(name = "addressId", value = "地址ID", required = true, example = "1001")<br> @RequestParam Long addressId<br>) { ... }<br> |
@ApiModel |
描述复杂参数(DTO/VO 类) | 用于实体类,说明该类的作用;value:类名;description:描述java<br>@ApiModel(value = "AddressDTO", description = "新增/编辑地址的请求参数")<br>public class AddressDTO { ... }<br> |
@ApiModelProperty |
描述复杂参数的字段 | 用于实体类的字段;value:字段说明;required:是否必填;example:示例值;hidden:是否隐藏java<br>@ApiModel(value = "AddressDTO", description = "新增/编辑地址的请求参数")<br>public class AddressDTO {<br> @ApiModelProperty(value = "用户ID", required = true, example = "1")<br> private Long userId;<br> <br> @ApiModelProperty(value = "详细地址", required = true, example = "北京市朝阳区XX小区")<br> private String detail;<br> <br> @ApiModelProperty(value = "内部标识", hidden = true) // 隐藏不显示在文档<br> private String innerFlag;<br>}<br> |
4. 其他常用注解(补充)
| 注解 | 作用 | 示例 |
|---|---|---|
@ApiImplicitParam |
替代 @ApiParam,用于非实体类参数(单参数) |
java<br>@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "Long", paramType = "query")<br> |
@ApiImplicitParams |
批量定义 @ApiImplicitParam |
多参数时使用,比如同时传 userId 和 status:java<br>@ApiImplicitParams({<br> @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query"),<br> @ApiImplicitParam(name = "status", value = "地址状态(1=启用,0=禁用)", required = false, paramType = "query")<br>})<br> |
三、完整示例:把注解串起来用
java
// 1. Controller 类
@RestController
@Api(tags = "用户地址管理", description = "用户收货地址的CRUD接口")
@RequestMapping("/address")
public class AddressController {
@Autowired
private AddressService addressService;
// 2. 查询地址列表接口
@GetMapping("/list")
@ApiOperation(value = "查询用户地址列表", notes = "支持分页,默认每页10条")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", example = "1"),
@ApiImplicitParam(name = "pageNum", value = "页码", required = false, paramType = "query", example = "1"),
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = false, paramType = "query", example = "10")
})
@ApiResponses({
@ApiResponse(code = 200, message = "查询成功,返回分页数据"),
@ApiResponse(code = 400, message = "用户ID为空")
})
public Result<Page<AddressVO>> list(
@RequestParam Long userId,
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
@RequestParam(required = false, defaultValue = "10") Integer pageSize
) {
Page<AddressVO> page = addressService.listByUserId(userId, pageNum, pageSize);
return Result.success(page);
}
// 3. 新增地址接口(用DTO接收参数)
@PostMapping("/add")
@ApiOperation(value = "新增收货地址")
public Result<Void> add(@RequestBody AddressDTO addressDTO) {
addressService.add(addressDTO);
return Result.success();
}
}
// 4. DTO 实体类
@ApiModel(value = "AddressDTO", description = "新增地址的请求参数")
public class AddressDTO {
@ApiModelProperty(value = "用户ID", required = true, example = "1")
private Long userId;
@ApiModelProperty(value = "收货人姓名", required = true, example = "张三")
private String receiver;
@ApiModelProperty(value = "手机号", required = true, example = "13800138000")
private String phone;
@ApiModelProperty(value = "详细地址", required = true, example = "北京市海淀区中关村")
private String detail;
// getter/setter 省略
}
四、关键使用技巧(新手避坑)
- 必填项一定要标
required = true:文档中会明确标注,前端对接时能清楚知道哪些参数必须传。 - 示例值
example一定要填:前端调试时可以直接用示例值,不用猜格式。 - 复杂参数优先用
@ApiModel + @ApiModelProperty:比@ApiImplicitParam更清晰,尤其是参数字段多的时候。 - 隐藏敏感参数 :用
@ApiModelProperty(hidden = true)隐藏密码、token 等字段,避免泄露。 - 状态码说明要具体:不要只写 "成功 / 失败",要说明具体原因(比如 400 = "用户 ID 为空")。
总结
@Api系列注解是 Swagger/OpenAPI 生成可视化接口文档的核心,核心作用是给接口加 "注释",让前后端对接更高效。- 核心注解分工:
@Api描述模块、@ApiOperation描述接口、@ApiParam/@ApiModel描述参数、@ApiResponses描述响应。 - 最佳实践:复杂参数用 DTO +
@ApiModel,必填参数标required,补充示例值和状态码说明,隐藏敏感字段。
简单记:注解的核心是 "让接口文档说人话",你写的注解越详细,前端 / 测试看文档时就越少问问题。