SpringDoc注解解析与接口测试实战:UI界面高效使用指南

前言 上篇介绍了SpringBoot集成SpringDoc的基础配置,本文重点解析常用注解、UI测试操作,助你快速理解提升开发效率。 SpringDoc中的基础注解 @SecurityScheme 这个注解是做什么的呢?下...

                    前言

上篇介绍了SpringBoot集成SpringDoc的基础配置,本文重点解析常用注解、UI测试操作,助你快速理解提升开发效率。


SpringDoc中的基础注解

@SecurityScheme

这个注解是做什么的呢?下面我们来用一个例子简单的解释一下

想象我们的API接口就像一个个风格各异的房间:


 有些是开放的茶室,谁都可以进(不需要认证的接口)

 有些是机密档案室,只有授权才能进(需要认证的接口)

当我们想要保护这些机密房间时,需要两个关键步骤:


制作特殊的通行证​

 这就是@SecurityScheme干的事!它像是一个"安全通行证的制作说明书",告诉你:

通行证叫什么名字?(OAuth2、JWT等)

去哪里办理?(授权URL)

怎么办理?(提交什么信息)

有什么权限等级?(token能访问的范围)

给房间挂上"请出示通行证"的牌子​

 这是另一注解@SecurityRequirement做的事!它像在房间门口贴个告示:

“进入此房间需要’高级通行证’”(也就是指定这个接口需要哪种认证)

@SecurityScheme与@SecurityRequirement搭配完成获取通行证,给房间挂牌的整套流程,在这里我们先讲制作特殊通行证的流程,而给房间挂牌的流程放在后面


@SecurityScheme(

// 通行证名称 (后续在门禁系统识别时使用该名称)

name = "OAuth2",

/**

* 通行证类型 (选择哪种安防体系)

* 当前选择:OAUTH2协议认证体系

* 类似还有:API钥匙串(APIKEY)、基础密码锁(HTTP)等

*/

type = SecuritySchemeType.OAUTH2,

/**

* 发证流程说明

* 这里配置如何获取通行证的具体步骤

* 可以设置多种办证方式(当前选择最安全的授权码模式)

*/

flows = @OAuthFlows(

// 授权码模式 (最常用的安全认证流程)

authorizationCode = @OAuthFlow(

// 办证窗口:用户需要前往此地址提交申请

authorizationUrl = "https://auth.example.com/authorize",

// 领证窗口:凭申请码在此处兑换正式通行证(token)

tokenUrl = "https://auth.example.com/token",

/**

* 通行证权限范围说明

* 就像办公室门禁卡有不同权限级别:

*   - 普通员工卡只能进入公共区域

*   - 经理卡可进入敏感区域

* 这里定义该通行证能解锁哪些操作

*/

scopes = {

// 读取权限:可查看用户信息(普通权限)

@OAuthScope(name = "user:read", description = "读取用户信息"),


// 写入权限:可修改用户信息(高级权限)

@OAuthScope(name = "user:write", description = "修改用户信息")

}

)

)

)


不知道大家看上面这段代码加上注释能不能看懂,如果不懂的话,也没关系,我再给大家上一个效果图,大家就能看懂了


attachments-2025-08-MtL0BpDw689eb81d2495f,png


怎么说,大家看这个图能不能看懂呢?

其中有一个scopes属性,我觉得有必要跟大家解释一下:


scopes 就像给你的"钥匙"添加权限标签

每次申请钥匙时,系统会问:“这把钥匙想要哪些权限?”

界面上列出所有权限选项(如「只能看」「可以改」等 ​权限标签)

你勾选需要的权限 → 拿到带标签的钥匙

用这把钥匙开锁时:

锁上标着"钥匙需含「只能看」标签" → 开门

 锁上要求"钥匙需含「可以改」标签" → 开门失败!

@OpenAPIDefinition

该注解用在配置类上方:主要作用是用来展示以及配置Swagger的一些基础信息


@OpenAPIDefinition(

    // 基础信息

    info = @Info(

        title = "电商平台API",

        version = "1.2.0",

        description = "核心业务API",

        contact = @Contact(name = "技术支持", url = "https://support.example.com"),

        license = @License(name = "商业许可")

    ),

    

    // 多环境配置

    servers = {

        @Server(url = "/api/v1", description = "默认网关路由"),

        @Server(url = "http://dev.example.com", description = "开发环境")

    },

    

    // 全局标签

    tags = {

        @Tag(name = "会员中心", description = "用户账户相关接口"),

        @Tag(name = "支付服务", description = "付款和退款处理")

    },

    

    // 外部文档

    externalDocs = @ExternalDocumentation(

        description = "数据库设计文档",

        url = "https://docs.example.com/db-schema"

    ),

    

    // 扩展信息

    extensions = {

        @Extension(name = "x-sla", properties = {

            @ExtensionProperty(name = "response-time", value = "<500ms"),

            @ExtensionProperty(name = "availability", value = "99.9%")

        })

    },


// 安全要求

    security = @SecurityRequirement(name = "OAuth2")

)

@SecurityScheme(

name = "OAuth2",

type = SecuritySchemeType.OAUTH2,

flows = @OAuthFlows(

authorizationCode = @OAuthFlow(

authorizationUrl = "https://auth.example.com/authorize",

tokenUrl = "https://auth.example.com/token",

scopes = {

@OAuthScope(name = "user:read", description = "读取用户信息"),

@OAuthScope(name = "user:write", description = "修改用户信息")

}

)

)

)

@Configuration

public class SpringDocConfig {

}


大家先不要害怕哈,我这里由于是写教程,所以把大部分属性都写了上去,实际开发过程中根本用不到这么多属性,大部分属性大家了解下就好ლ(・ヮ・ლ)

info属性

info属性主要用于定义SwaggerUI界面的一些基础信息,这里不多讲,只需要放张图,大家就明白了

attachments-2025-08-ki10LkvW689eb93a673a7,png

怎么样,是不是一目了然

servers属性

servers属性呢,其使用过PostMan或者ApiFox或者ApiPost的小伙伴,一眼就能认出来这个是做什么的,无非就是多环境配置嘛,选择不同的环境,请求不同的基础路径对吧ヽ( ̄~ ̄ )ノ

attachments-2025-08-6faOZMt4689eb94ad312b,png

tags属性

这个属性其实是用来定义全局所有接口可以公用的tag标签的,这里不多讲,因为下面会讲到一个@Tag标签和一个方法上的tags属性,会详细展开讲,这里就不浪费篇幅了,只简单的提一嘴,也就是在这里定义的标签,无论在每个分组中是否有属于这个标签的方法,都会展现在每个组中,如下图:

attachments-2025-08-VDPCq8cy689eb969c2813,png

attachments-2025-08-rCBZJTSe689eb98bb5bc6,png

externalDocs 属性

这个属性呢是用来链接外部文档的,可以将一些与这里有关联的外部文档放在这里,用户可以点击这里跳转到相应的文档,大家看下面的图,是不是很方便

attachments-2025-08-JfBl1rHC689eb9a8e579d,png

extensions属性

这个属性就稍微复杂一点,他其实是用来定义一些自定义属性的,什么意思呢?

首先,我们使用SpringDoc的目的是什么呢?其中一个是不是可以生成接口文档?那么我现在有一个需求,就是我需要在生成的接口文档中添加一些自定义的信息,比如开发者姓名、开发小组、联系人、背锅侠之类的,我们该咋写,我们发现如果仅仅使用官方提供的标准属性,没地方写,那么自定义属性在这个时候就派上用场了,不多说废话,直接上代码,大家一看就明白


@OpenAPIDefinition(

    extensions = {

        @Extension(properties = {

            @ExtensionProperty(name = "x-team", value = "billing-team"),

            @ExtensionProperty(name = "x-sla", value = "99.9%")

        })

    }

)


{

  "openapi": "3.0.1",

  "info": {

    "title": "API文档",

    "version": "1.0.0"

  },

  "paths": { ... },

  "components": { ... },

  "x-team": "billing-team",

  "x-sla": "99.9%"

}


大家明白了吗,当然,我这里展示的仅仅是最简单的一种,还有很多复杂场景,我这里了就不展开了,毕竟用的也不多,如果展开的话太多废话,文章会拉得很长,大家如果有兴趣,可以私聊我,我会对有需要的小伙伴单独解释

security
security 是做什么的呢,简单来说他是用来做权限控制的,security 属性指定访问该接口所需的安全认证方案。当客户端调用此接口时,必须提供符合声明的认证凭证(如 OAuth2 令牌、API Key 等),否则请求会被拒绝。

什么意思呢?其实上面我们在讲@SecurityScheme的时候已经讲过了一个制作钥匙,加锁的流程,上面说过了@SecurityScheme是用来制作钥匙的,那么谁是用来加锁的呢?诶,就是这里了,嘿嘿

下面我仅仅简单介绍下代码的书写方式以及基础概念,因为如果完全没有接触过权限认证的小伙伴,这里是不太好理解的,所以可以先跳过,等大家明白了权限认证,在回过头来看这里就很容易了,而接触过权限认证的小伙伴,相信大家看一下下面的代码,应该可以明白个七七八八

@Configuration  // 标识为 Spring 配置类
@OpenAPIDefinition(  // 定义 OpenAPI 全局规范
    security = @SecurityRequirement(name = "OAuth2")  // ⭐️全局安全要求:所有接口默认需 OAuth2 认证
)
@SecurityScheme(
name = "OAuth2",
type = SecuritySchemeType.OAUTH2,
flows = @OAuthFlows(
authorizationCode = @OAuthFlow(
authorizationUrl = "https://auth.example.com/authorize",
tokenUrl = "https://auth.example.com/token",
scopes = {
@OAuthScope(name = "user:read", description = "读取用户信息"),
@OAuthScope(name = "user:write", description = "修改用户信息")
}
)
)
)
public class SpringDocConfig {
}

大家看上面这个例子,我告诉程序我需要OAuth2这个类型的钥匙,并且已经使用@SecurityScheme定义了获取OAuth2这种钥匙的方式,大家看看效果
attachments-2025-08-kDDL66US689eba26c4096,png
看,当我们配置了这个之后,页面上出现了一把锁,点击这把锁,就会弹出这个页面让用户提供认证信息,页面中还会有我们配置的认证流程之类的,只有用户按照要求提供了认证信息,通过认证之后,访问我们的接口,才可以正常访问,所以,大家懂了吗

另外这里有几个注意点

页面上展示的锁的状态:
锁打开表示:未认证​:未提供有效凭证或未完成OAuth2流程,无法正常访问接口
​锁关闭表示:已认证​:已获得有效访问令牌,可以正常访问接口
在配置类上加了security = @SecurityRequirement(name =“OAuth2”)之后表示整个环境中所有接口默认都需要认证才可以访问,这明显不合理,针对这种结果,我们有三种处理方式
第一种是我们在这里开启全局认证后,在后面不需要的方法上面添加@SecurityRequirements()注解即可取消掉该接口的权限认证(后面会讲到)
第二种是在Controller类的上方添加@SecurityRequirements()注解即可取消掉该类所有接口的权限认证(后面会讲到)
第三种方式是这里不要添加这个属性(不开启全局认证),只使用@SecurityScheme注解定义认证方式,等到后面需要认证的接口上面单独开启认证(一样后面会讲)
第二个需要注意的点是这里可以添加多个security 属性,让用户选择使用哪种方式进行认证
@Tag
该注解用在Controller类上方:主要作用是标志当前Controller在UI界面的显示名称,以及当前Controller的描述
对应SpringFox的@Api注解
同时SpringDoc中也支持使用@Api这个注解,只是相对来说更推荐SpringDoc专属的注解

@RestController
@RequestMapping("/api/member")
@Tag(
// 当前Controller在UI界面所显示的名称
name = "会员controller",
// 当前Controller在UI界面的描述
description = "会员controller",
// extensions 用于添加自定义属性,而 @Extension 就是定义这些扩展属性的关键注解。
// OpenAPI 规范提供了标准字段(如 name, description),但实际项目中可能需要额外的元数据(如排序、权限、业务分类等)。
// 扩展属性以 x- 前缀开头(如 x-order),是 OpenAPI 允许的自定义字段,不影响规范核心功能。
// 以x-order举例,x-order属性用于定义当前Controller在当前分组显示的顺序,值越小显示越靠前。
extensions = {
@Extension(name = "x-order", properties = @ExtensionProperty(name = "priority", value = "0"))
}
)
public class MemberController {

@GetMapping("/list")
@Operation(summary = "会员列表", description = "会员列表")
public String list(@Parameter(description = "memberName", required = true) String memberName) {
return "请求成功";
}

}

举个栗子
基础属性很简单,所以不多啰嗦,这里主要举例说明自定义属性,以x-order举例,如果当前分组下我有两个Controller,一个MemberController,一个MemberAccountController,并且两个Controller都不设置显示顺序,那么他就按照默认顺序进行显示,如下:
attachments-2025-08-1YHvjtAw689eba79c9edb,png
但是如果我给MemberController设置一个显示顺序属性,设置为0,会怎样呢?大家看:
attachments-2025-08-31QwdKbD689eba8d22dd9,png

发现了吗,MemberController跑到前面去了,所以大家明白了吗( ̄▽ ̄)ノ

@Operation

@RestController

@RequestMapping("/api/member")

@Tag(

// 当前Controller在UI界面所显示的名称

name = "会员controller",

// 当前Controller在UI界面的描述

description = "会员controller"

}

)

public class MemberController {

@GetMapping("/list")

@Operation(

// 接口摘要说明(简洁描述接口功能)

summary = "会员列表",

// 详细接口描述(可包含具体行为说明)

description = "会员列表",

// 接口所属标签

tags = {"测试会员标签"},  // 支持多标签,如{"认证","公共接口"}

// 标记接口是否已废弃(true时UI会有删除线提示,并且接口颜色会变为灰色)

deprecated = false,  // 默认false

// 是否在文档中隐藏该接口(true时不在UI显示)

hidden = false,  // 默认false

// 接口安全需求(声明此接口需要何种认证方式)

security = @SecurityRequirement(name = "OAuth2")  // 对应securitySchemes定义的方案名

)

public String list(@Parameter(description = "memberName", required = true) String memberName) {

return "请求成功";

}

}


上面这个注解中,像summary、description、deprecated 、hidden等属性,配合注释,应该不用解释,相信以大家的聪明才智很容易就理解了,这里着重说一下tags与security

tags属性
先说tags,相信大家发现了,tags与Controller上面的@Tag很像,那么他们有什么关系,有什么区别呢?先上图,大家对照着看会更容易理解
attachments-2025-08-xtBvhqpn689ebb15cb475,png
attachments-2025-08-nCZBjeWV689ebb2b13d89,png

大家看,由于我同时使用了@Tag注解和tags属性,于是发生了一个相同的接口出现在了两个不同的标签组中的情况,于是我们得到一个结论,当类的上方与方法上方同时存在tag相关的内容时,涉及到的方法会同时出现在两个位置

那么如果我们没有在类的层面使用@Tag,仅仅在方法层面使用了tags这个属性会怎样呢?

attachments-2025-08-tyLXvWqE689ebbc5efc11,pngattachments-2025-08-qbtyt1i7689ebbdc1c047,png

看,会员Controller消失了ヽ(°〇°)ノ,于是我们又得到一个结论,当类的上方没有@Tag注解,只有方法上方的注解存在tags属性时,该方法只会出现在方法指定的tags中,同时类的模块会隐藏

那我,我们再想想,上方这个类中只有一个方法,并且类上方没有添加@Tag注解,而方法上方添加了tags属性,所以类的模块被隐藏了,只出现了我们自定义的标签,那我们如果在上方的基础上稍微改一下,就是在类里面如果有两个或两个以上的方法,那么没有自定义tags属性的方法会出现在哪里呢?我们来看效果

attachments-2025-08-AQiOblME689ebc4ce9538,png
attachments-2025-08-A4xyx8qJ689ebc5749f02,png


大家猜到了吗?如果这个类上方没有添加@Tag注解,但是这个类中存在没有自定义标签属性的方法,那么就会出现一个以Controller名字为命名的标签来展示这些其他方法

可能有点绕,但是我相信大家看图应该很容易理解,同时注意tags可以写多个标签哦

我的习惯是,如果在类的层面定义了@Tag,就不在方法层面使用tags属性,当然具体如何使用还是看大家的习惯(‘-’*ゞ

security属性
大家看到这个,是不是很熟悉呢,是的,这个跟上面配置类@OpenAPIDefinition注解上的security属性以及@SecurityScheme注解都是配套使用的,大家只要搞懂了上面,这里几句话就能解释的明白

简单的说,放在配置类上的@OpenAPIDefinition注解的security属性是用来全局开启认证的,而放在这里的@Operation注解的security属性是针对某个方法开启认证的,当你没有开启全局认证的时候,只要你使用@SecurityScheme注解配置了具体的获取认证的方式,这里就可以使用这个属性来对这个方法单独开启权限认证了

//全局未开启认证,但是配置了认证方式,该方法需要开启认证
@Operation(
// 接口摘要说明(简洁描述接口功能)
summary = "会员列表",
// 详细接口描述(可包含具体行为说明)
description = "会员列表",
// 接口所属标签
tags = {"测试会员标签"},  // 支持多标签,如{"认证","公共接口"}
// 接口安全需求(声明此接口需要何种认证方式)
// 这里支持多种认证方式(注意这里要用到的所有认证方式一定要现在配置类中定义才可以)
security = {
        @SecurityRequirement(name = "OAuth2"),
        @SecurityRequirement(name = "ApiKey")
    }
)
public String list(@Parameter(description = "memberName", required = true) String memberName) {
return "请求成功";
}

attachments-2025-08-1TmGMUHM689ebca21a20f,png
@SecurityRequirements
这个注解呢,其实和@OpenAPIDefinition注解的security属性和@Operation注解的security属性功能差不多,大家理解了上面的两个内容,这里很容易理解,只不过他是一个单独的注解,并且功能更全面一些

第一种使用方式:不包含属性(表示清空权限认证)

@RestController
@RequestMapping("/api/member")
@SecurityRequirements()
public class MemberController {
@GetMapping("/list")
@Operation(
// 接口摘要说明(简洁描述接口功能)
summary = "会员列表",
// 详细接口描述(可包含具体行为说明)
description = "会员列表"
)
//注意这个注解可以单独放在类上或者单独放在方法上,但是如果类上面已经覆盖了,这里就没必要在加了
//@SecurityRequirements()
public String list(@Parameter(description = "memberName", required = true) String memberName) {
return "请求成功";
}
}

这个注解的这种使用方式是用来覆盖全局认证的,什么意思呢?
上面讲过,配置类中可以使用@OpenAPIDefinition的security属性来配置全局接口都需要进行安全认证,但是不太合理,如果我某个接口或者某个Controller不需要进行安全认证,要怎么做?
这个时候就可以用这个注解进行清除安全认证了,当这个注解加载类上,那么这个类的所有接口都不需要进行安全认证了,当这个接口加在方法上,那么单独这个方法不需要进行安全认证

第二种使用方式:包含属性(表示当前接口可以使用哪些权限认证,覆盖全局配置)
@GetMapping("/list")
@Operation(
// 接口摘要说明(简洁描述接口功能)
summary = "会员列表",
// 详细接口描述(可包含具体行为说明)
description = "会员列表"
)
@SecurityRequirements({
@SecurityRequirement(name = "API-Key"),       // 要求1:API-Key
@SecurityRequirement(name = "OAuth2", scopes = {"user:write"})   // 要求2:OAuth2且具有user:write权限
})
public String list(@Parameter(description = "memberName", required = true) String memberName) {
return "请求成功";
}



大家看上面这种使用方式,它其实和@OpenAPIDefinition注解的security属性和@Operation注解的security属性用法基本一样了,表示访问这个接口,可以使用两种认证方式(任选其一即可),但是当使用OAuth2认证方式时需要具有user:write权限

@Parameter

@GetMapping("/list")
@Operation(
// 接口摘要说明(简洁描述接口功能)
summary = "会员列表",
// 详细接口描述(可包含具体行为说明)
description = "会员列表"
)
@SecurityRequirements({
@SecurityRequirement(name = "API-Key"),       // 要求1:API-Key
@SecurityRequirement(name = "OAuth2", scopes = {"user:write"})   // 要求2:OAuth2且具有payment:write权限
})
public String list(
@Parameter(description = "memberName", required = true) String memberName,
@Parameter(
// 定义参数的名称
name = "memberType",
// 参数的详细描述
description = "会员类型:0-普通,1-VIP,2-管理员",
// 提供参数示例值
example = "1",
// 参数是否必填
required = true,
// 定义参数的数据类型和约束
schema = @Schema(type = "integer", allowableValues = {"0", "1", "2"}),
// 指定参数传递的位置
in = ParameterIn.QUERY
) String memberType) {
return "请求成功";
}


@Parameter注解呢主要是针对接口参数使用的,如果不加这个注解,那么首先这个参数没有一个解释,调用接口的时候,会很迷茫(这什么鬼玩意),于是就需要这个注解

这个注解中的name、description、example、required等属性不用多说,配合注释,大家一看就能理解

这里主要说一说schema和in属性

schema
这个属性主要是用来对参数进行一系列限制的

type = “integer”,表示当前参数只可以使用integer类型
allowableValues = {“0”, “1”, “2”},表示取值范围,限定参数只允许取值为 0, 1, 2(对应普通用户、VIP、管理员)
in
这个属性主要是指定参数传递的位置

QUERY:参数需通过 ​URL 查询字符串传递(如 /api/list?userType=1)。
PATH:参数须通过URL 路径中的变量传递(如/api/user/profile/456)。
HEADER:参数须通过 HTTP 头传递(如X-Auth-Token: abcde12345)。
COOKIE:参数须通过浏览器 Cookie 传递(如:Cookie: sessionId=9a8b7c6d5e)

@Schema

@Schema(description = "会员基础信息模型")
public class Member {

/** 会员ID */
@Schema(
description = "会员唯一ID",             // 字段描述:说明字段含义
example = "1",                     // 示例值:文档中显示的示例数据
accessMode = Schema.AccessMode.READ_ONLY, // 访问模式:表示该字段仅用于响应(不可修改)
minimum = "10000",                     // 最小值:限定ID最小值为10000
maximum = "99999",                     // 最大值:限定ID最大值为99999
type = "integer"                      // 数据类型:限定为整数类型
)
private Integer memberId;
/** 会员姓名 */
@Schema(
description = "用户名",                // 字段描述
minLength = 4,                         // 最小长度:用户名至少4个字符
maxLength = 20,                        // 最大长度:用户名最多20个字符
pattern = "^[a-zA-Z0-9_]+$",          // 正则规则:只允许字母/数字/下划线
defaultValue = "guest",                 // 默认值:未传值时使用默认值"guest"
type = "string"
)
private String memberName;
/** 会员手机号 */
@Schema(description = "会员手机号",type = "string")
private String memberPhone;
/** 会员邮箱 */
@Schema(description = "会员邮箱",type = "string")
private String memberEmail;
/** 会员地址 */
@Schema(description = "会员地址",type = "string")
private String memberAddress;
/** 会员类型 */
@Schema(
description = "会员类型",             // 字段描述:说明字段含义
type = "short",// 字段类型限制
allowableValues = {"0", "1", "2"}// 限定范围
)
private Short memberType;
@Schema(
description = "角色列表",               // 字段描述
implementation = Role.class,           // 关联模型:说明数组元素对应的数据模型
type = "array"                         // 数据类型:明确声明为数组类型(可省略)
)
private List<Role> roles;
}

这个注解很简单,相信大家看上面的代码示例,加上注释应该能够一目了然
下面给大家列出几个使用场景吧:

场景一:当标注了@Schema的实体类作为参数使用时

//添加会员

@GetMapping("/add")

@Operation(

// 接口摘要说明(简洁描述接口功能)

summary = "添加会员",

// 详细接口描述(可包含具体行为说明)

description = "添加会员"

)

public String add(Member member) {

return "请求成功";

}


页面显示效果如下:
attachments-2025-08-dLTiR4G0689ebd72a2cbe,png

场景二:当标注了@Schema的实体类作为返回值使用时

@GetMapping("/detail")

@Operation(

// 接口摘要说明(简洁描述接口功能)

summary = "会员详情",

// 详细接口描述(可包含具体行为说明)

description = "会员详情"

)

public Member detail(@Parameter(description = "memberId", required = true) Integer memberId) {

return new Member();

}


效果如下:
attachments-2025-08-pCIJhTkH689ebdacaa483,png

嘿嘿,一样的效果
怎么样,是不是很简单?一看就懂

@ParameterObject

这个注解相当简单,他配合上面的@Schema进行使用,我只需要上几张图,加几句话解释,大家瞬间就明白了
我们来看两段代码

//第一段代码,不加@ParameterObject注解

@GetMapping("/add")

@Operation(

// 接口摘要说明(简洁描述接口功能)

summary = "添加会员",

// 详细接口描述(可包含具体行为说明)

description = "添加会员"

)

public String add(Member member) {

return "请求成功";

}

看看效果:

attachments-2025-08-ONOkgCmA689ebe007e8f8,png
//第二段代码,加了@ParameterObject注解
@GetMapping("/add")
@Operation(
// 接口摘要说明(简洁描述接口功能)
summary = "添加会员",
// 详细接口描述(可包含具体行为说明)
description = "添加会员"
)
public String add(@ParameterObject Member member) {
return "请求成功";
}

看看效果:

attachments-2025-08-bxSDqLic689ebe2c1df19,png
欧吼,大家发现了什么?没错,当一个参数类型是一个实体类,并且这个实体类内部使用@Schema对字段进行了标注时,如果不加@ParameterObject,那么这个参数就还是以一个实体类的形式进行传递,但是如果加了@ParameterObject,那么参数会自动按照实体类中的配置进行解构,然后进行传递
怎么样,是不是超简单(・ε・`)

@ApiResponse

@PostMapping("/create")
@Operation(summary = "创建新用户")
@ApiResponse(  // 描述接口的返回状态响应
    responseCode = "201",  // HTTP响应状态码(如201表示创建成功)
    description = "用户创建成功",  // 响应描述信息
    content = @Content(  // 定义响应体内容
        mediaType = "application/json",  // 响应内容类型(JSON格式)
        schema = @Schema(implementation = UserResult.class)  // 关联的数据模型
    )
)
@ApiResponse(  // 第二个响应声明
    responseCode = "400",  // 400表示客户端请求错误
    description = "无效的用户数据",  // 描述问题原因
    content = @Content(  // 错误响应内容
        mediaType = "application/json", 
        schema = @Schema(implementation = ErrorResponse.class)  // 错误模型
    )
)
public ResponseEntity<?> createUser(...) { ... }

Emmm…
这个注解,怎么说呢,是不是一看就大概能猜出来他是干啥的?是的,他是用来定义json文档的返回结果的,如下:

/create-user:
  post:
    responses:
      '201':
        description: 用户创建成功
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserResult'  # 指向UserResult模型
      '400':
        description: 无效的用户数据
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ErrorResponse'  # 指向错误模型

这个没什么难的,但是有一点要注意,大家千万不要把这个注解当成这个方法的真正返回结果,OpenAPI的注解,它的影响力只到文档层面,不会对业务层面的返回有任何实际的效果,这个接口最终要返回什么,还是要看大家方法中的实际返回

@Hidden

@Hidden // 隐藏整个控制器

@RestController

public class InternalController {

    @GetMapping("/secret")

    @Hidden // 隐藏单个方法

    public String secretMethod() {

        return "秘密数据";

    }

}


这个注解一看就懂他是干啥的,无非就是在UI界面隐藏这个方法或者Controller类的显示嘛,其实就是用在SpringDoc在配置扫描时,扫描到了这个类或者方法,但是这个类或者方法不想展示,这个时候@Hidden就派上用场了

总结
本文把 SpringDoc 的核心注解和在 Swagger UI 里的效果都给大伙儿掰扯清楚了。
本来想一口气把 Swagger UI 的操作也手把手教了,​结果光注解就唠了这么老长!键盘都让我敲出火星子了
下期咱专门肝操作指南!​点个关注不迷路,更新时第一时间踹你来看~
如果觉得有用,​赶紧点赞收藏​ !给我码字加个氮气加速,我们下期见!(ง •_•)ง



下一篇: 解锁Swagger UI:界面功能详解与实战操作技巧
  • 发表于 2025-08-15 12:27
  • 阅读 ( 69 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
石天
石天

437 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章