1. 概述

Swagger UI是一个强大的API可视化工具,能让我们以最小配置生成API结构文档。本文将聚焦于Spring Boot REST API与Swagger的集成,重点探讨在Swagger UI中隐藏请求字段的多种实现方式。

2. 场景引入

为便于演示,我们创建一个基础Spring Boot应用,通过Swagger UI观察API行为。首先定义ArticleApplicationArticlesController

@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字段需要后端自动生成时,我们希望:

  1. 在POST接口中隐藏该字段(避免用户输入)
  2. 在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接口仅显示nameemail
  • ⚠️ 限制:仅支持@RequestBody,不兼容@ModelAttribute

7. 使用@Hidden

Swagger专用注解@Hidden提供最直接的隐藏能力:

@Hidden
private int id;

效果

  • ✅ 所有API中完全隐藏字段
  • ⚠️ 注意:这是Swagger层面的隐藏,不影响JSON序列化

8. 方案对比与选择

场景需求 推荐方案 备注
完全隐藏(所有API) @JsonIgnore/@Hidden 简单粗暴,适合内部字段
只读模式(GET显示) @Schema(accessMode=READ_ONLY) 最常用,符合RESTful规范
动态视图控制 @JsonView 复杂场景必备,但配置稍多

实践建议

  1. 优先使用@Schema(accessMode=AccessMode.READ_ONLY)满足90%场景
  2. 需要细粒度控制时考虑@JsonView
  3. 避免滥用@JsonIgnore,可能影响数据完整性

源码示例:GitHub仓库(mock邮箱:dev@swaggerdemo.com


原始标题:Hide a Request Field in Swagger API