1. 概述
Swagger UI是一个强大的API可视化工具,能让我们以最小配置生成API结构文档。本文将聚焦于Spring Boot REST API与Swagger的集成,重点探讨在Swagger UI中隐藏请求字段的多种实现方式。
2. 场景引入
为便于演示,我们创建一个基础Spring Boot应用,通过Swagger UI观察API行为。首先定义ArticleApplication
和ArticlesController
:
@RestController
@RequestMapping("/articles")
public class ArticlesController {
@Autowired
private ArticleService articleService;
@GetMapping("")
public List<Article> getAllArticles() {
return articleService.getAllArticles();
}
@PostMapping("")
public void addArticle(@RequestBody Article article) {
articleService.addArticle(article);
}
}
DTO类Article
包含三个字段:
public class Article {
private int id;
private String title;
private int numOfWords;
// 标准getter/setter
}
启动应用后访问Swagger UI(默认地址:http://localhost:9090/springbootapp/swagger-ui/index.html#/articles-controller
),默认行为显示所有字段:
- GET接口返回所有字段
- POST接口接收所有字段输入
核心问题:当id
字段需要后端自动生成时,我们希望:
- 在POST接口中隐藏该字段(避免用户输入)
- 在GET接口中保留该字段(确保数据完整)
3. 使用@JsonIgnore
@JsonIgnore
是Jackson的标准注解,用于在序列化/反序列化时忽略指定字段。直接应用于字段即可同时隐藏getter和setter:
@JsonIgnore
private int id;
效果:
- ✅ 所有API中完全隐藏
id
字段 - ⚠️ 踩坑:GET接口也无法返回该字段
4. 使用@Schema
Swagger的@Schema
注解提供更精细的控制:
方案1:完全隐藏
@Schema(hidden = true)
private int id;
效果同@JsonIgnore
方案2:只读模式(推荐)
@Schema(accessMode = AccessMode.READ_ONLY)
private int id;
效果:
- ✅ GET接口:显示字段(只读)
- ✅ POST接口:隐藏字段(不可输入)
💡 技巧:
readOnly
属性已废弃,改用accessMode
更规范
5. 使用@JsonProperty
通过Jackson的@JsonProperty
实现字段访问控制:
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private int id;
效果:
- 等同于
@Schema(accessMode = AccessMode.READ_ONLY)
- 适合需要同时控制JSON序列化和Swagger的场景
6. 使用@JsonView
当需要动态控制字段可见性时,@JsonView
是更灵活的选择:
步骤1:定义视图类
public class Views {
public static class Public {}
public static class Private {}
}
步骤2:应用视图
public class Author {
@JsonView(Views.Private.class)
private Integer id;
@JsonView(Views.Public.class)
private String name;
@JsonView(Views.Public.class)
private String email;
// 标准getter/setter
}
步骤3:绑定到API
@JsonView(Views.Public.class)
@GetMapping
public List<Author> getAllAuthors() {
return authorService.getAllAuthors();
}
@PostMapping
public void addAuthor(@RequestBody @JsonView(Views.Public.class) Author author) {
authorService.addAuthor(author);
}
效果:
- ✅ GET/POST接口仅显示
name
和email
- ⚠️ 限制:仅支持
@RequestBody
,不兼容@ModelAttribute
7. 使用@Hidden
Swagger专用注解@Hidden
提供最直接的隐藏能力:
@Hidden
private int id;
效果:
- ✅ 所有API中完全隐藏字段
- ⚠️ 注意:这是Swagger层面的隐藏,不影响JSON序列化
8. 方案对比与选择
场景需求 | 推荐方案 | 备注 |
---|---|---|
完全隐藏(所有API) | @JsonIgnore /@Hidden |
简单粗暴,适合内部字段 |
只读模式(GET显示) | @Schema(accessMode=READ_ONLY) |
最常用,符合RESTful规范 |
动态视图控制 | @JsonView |
复杂场景必备,但配置稍多 |
实践建议:
- 优先使用
@Schema(accessMode=AccessMode.READ_ONLY)
满足90%场景 - 需要细粒度控制时考虑
@JsonView
- 避免滥用
@JsonIgnore
,可能影响数据完整性
源码示例:GitHub仓库(mock邮箱:dev@swaggerdemo.com)