N

Norlcayn的博客

A text-focused Halo theme

  • 首页
  • 文章
  • 默认分类
  • 关于
主页 Swagger在线接口文档
文章

Swagger在线接口文档

发表于 2026-01-15 更新于 昨天
作者 Administrator
36~46 分钟 阅读

在线接口文档

在开发中,如果遇到后端项目开发完毕,但是前端项目还未开发完成,但又需要对后端接口进行测试

先前的解决方式是通过第三方接口测试软件,如postman、apifox等进行测试

但这类测试工具需要清楚的知道接口的路径、请求方式、请求参数,且还需要手动填写对应内容

当与前端对接时,后端还需要提供详细的接口文档,当接口文档编写的不及时或者更新不及时,就会造成信息闭塞,造成不必要的效率降低

Swagger简介

Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务

官网:https://swagger.io

它的主要作用:

  • 使得前后端分离开发更加方便,有利于团队协作
  • 在线自动生成接口文档,降低后端开发人员编写接口文档的负担
  • 功能测试

Spring已经将Swagger纳入自身的标准,建立了Spring-Swagger项目,现在加Springfox。通过在项目中引入Springfox,就可以非常简单快捷的使用Swagger啦

项目中集成

目前若依框架已经集成了Swagger,核心配置有如下几个:

  1. 关键依赖:

f821521a-00a3-401b-8952-3d35ce933db8

  1. 核心配置类: - 位置:com.zzyl.web.core.config.SwaggerConfig - 请设计prompt提示词,来阅读以下代码
package com.zzyl.web.core.config;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.zzyl.common.config.RuoYiConfig;
import io.Swagger.annotations.ApiOperation;
import io.Swagger.models.auth.In;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * Swagger2的接口配置
 * 
 * @author ruoyi
 */
@Configuration
public class SwaggerConfig
{
    /** 系统基础配置 */
    @Autowired
    private RuoYiConfig ruoyiConfig;

    /** 是否开启Swagger */
    @Value("${Swagger.enabled}")
    private boolean enabled;

    /** 设置请求的统一前缀 */
    @Value("${Swagger.pathMapping}")
    private String pathMapping;

    /**
     * 创建API
     */
    @Bean
    public Docket createRestApi()
    {
        return new Docket(DocumentationType.OAS_30)
                // 是否启用Swagger
                .enable(enabled)
                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
                .apiInfo(apiInfo())
                // 设置哪些接口暴露给Swagger展示
                .select()
                // 扫描所有有注解的api,用这种方式更灵活
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // 扫描指定包中的Swagger注解
                // .apis(RequestHandlerSelectors.basePackage("com.zzyl.project.tool.Swagger"))
                // 扫描所有 .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                /* 设置安全模式,Swagger可以设置访问token */
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts())
                .pathMapping(pathMapping);
    }

    /**
     * 安全模式,这里指定token通过Authorization头请求头传递
     */
    private List<SecurityScheme> securitySchemes()
    {
        List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
        apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
        return apiKeyList;
    }

    /**
     * 安全上下文
     */
    private List<SecurityContext> securityContexts()
    {
        List<SecurityContext> securityContexts = new ArrayList<>();
        securityContexts.add(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
                        .build());
        return securityContexts;
    }

    /**
     * 默认的安全上引用
     */
    private List<SecurityReference> defaultAuth()
    {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences = new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }

    /**
     * 添加摘要信息
     */
    private ApiInfo apiInfo()
    {
        // 用ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                // 设置标题
                .title("标题:若依管理系统_接口文档")
                // 描述
                .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
                // 作者信息
                .contact(new Contact(ruoyiConfig.getName(), null, null))
                // 版本
                .version("版本号:" + ruoyiConfig.getVersion())
                .build();
    }
}
  1. 访问地址
  • 方式一:系统内部访问

955e7e76-5d79-4bdf-8bcd-f6386936f3e3

  • 方式二:服务地址+/Swagger-ui/index.html — > http://localhost:8080/swagger-ui/index.html

83962e69-c269-4b2c-a85a-5211c687accf

集成knife4j

如果不习惯使用swagger可以使用前端UI的增强解决方案knife4j,对比swagger相比有以下优势:

  1. 友好界面
  2. 离线文档
  3. 接口排序
  4. 安全控制
  5. 在线调试
  6. 文档清晰
  7. 注解增强
  8. 容易上手。

目前,企业项目中一般都使用knife4j框架

若依文档中有相关介绍:插件集成 | RuoYi

实现后的效果:

18161d6d-6f97-4ca6-801e-c8af0ce02e82

  • 可以下载离线文档:

7e774ea9-8c55-4bcb-b3b2-35534ddb724e

Swagger使用

常见注解

通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:

注解 说明
@Api 用在Controller类上,描述Controller类的作用
@ApiOperation 用在Controller类中的方法上,说明方法的用途、作用
@ApiParam 用在方法的参数上,描述单个形参的含义,适用于简单场景
@ApiImplicitParam 用在Controller类中的方法上方,描述单个形参的含义,适用于参数复杂或者需要详细描述参数的场景
@ApiModel 用在实体类上,描述用来接收参数或者响应结果的实体类的含义
@ApiModelProperty 用在实体类的属性上,用来描述实体类中属性的含义

请求体参数

一般的形参,如:id,status等这些,在controller的方法可以使用@ApiParam或者@ApiImplicitParam注解进行描述

如果接口是post、put请求,可能接收的是一个对象作为请求体参数,上面两个注解并不能很好的描述对象中的每一个属性,这个时候需要使用新的注解:@ApiModel和@ApiModelProperty

比如,在新增护理项目的时候,接收的参数为NursingProject实体类,咱们可以用上面两个注解在实体类中描述类和属性的含义

如下代码:

@ApiModel(value = "NursingProject" , description = "护理项目对象")
public class NursingProject extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 编号 */
    @ApiModelProperty("编号")
    private Long id;

    /** 名称 */
    @ApiModelProperty("名称")
    @Excel(name = "名称")
    private String name;

    /** 排序号 */
    @ApiModelProperty("排序号")
    @Excel(name = "排序号")
    private Integer orderNo;

    /** 单位 */
    @ApiModelProperty("单位")
    @Excel(name = "单位")
    private String unit;

    /** 价格 */
    @ApiModelProperty("价格")
    @Excel(name = "价格")
    private BigDecimal price;

    /** 图片 */
    @ApiModelProperty("图片")
    @Excel(name = "图片")
    private String image;

    /** 护理要求 */
    @ApiModelProperty("护理要求")
    @Excel(name = "护理要求")
    private String nursingRequirement;

    /** 状态(0:禁用,1:启用) */
    @ApiModelProperty("状态(0:禁用,1:启用)")
    @Excel(name = "状态", readConverterExp = "0=:禁用,1:启用")
    private Integer status;

    public void setId(Long id) 
    {
        this.id = id;
    }

    public Long getId() 
    {
        return id;
    }

    public void setName(String name) 
    {
        this.name = name;
    }

    public String getName() 
    {
        return name;
    }

    public void setOrderNo(Integer orderNo) 
    {
        this.orderNo = orderNo;
    }

    public Integer getOrderNo() 
    {
        return orderNo;
    }

    public void setUnit(String unit) 
    {
        this.unit = unit;
    }

    public String getUnit() 
    {
        return unit;
    }

    public void setPrice(BigDecimal price) 
    {
        this.price = price;
    }

    public BigDecimal getPrice() 
    {
        return price;
    }

    public void setImage(String image) 
    {
        this.image = image;
    }

    public String getImage() 
    {
        return image;
    }

    public void setNursingRequirement(String nursingRequirement) 
    {
        this.nursingRequirement = nursingRequirement;
    }

    public String getNursingRequirement() 
    {
        return nursingRequirement;
    }

    public void setStatus(Integer status) 
    {
        this.status = status;
    }

    public Integer getStatus() 
    {
        return status;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("id", getId())
            .append("name", getName())
            .append("orderNo", getOrderNo())
            .append("unit", getUnit())
            .append("price", getPrice())
            .append("image", getImage())
            .append("nursingRequirement", getNursingRequirement())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("updateBy", getUpdateBy())
            .append("remark", getRemark())
            .append("createTime", getCreateTime())
            .append("updateTime", getUpdateTime())
            .toString();
    }
}

由于这个类继承了BaseEntity,还需要使用上面两个注解对BaseEntity进行描述

@ApiModel(value = "BaseEntity",description = "Entity基类")
public class BaseEntity implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 搜索值 */
    @JsonIgnore
    private String searchValue;

    /** 创建者 */
    @ApiModelProperty(value = "创建者")
    private String createBy;

    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "创建时间")
    private Date createTime;

    /** 更新者 */
    @ApiModelProperty(value = "更新者")
    private String updateBy;

    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;

    /** 备注 */
    @ApiModelProperty(value = "备注")
    private String remark;

    /** 请求参数 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @ApiModelProperty(value = "请求参数")
    private Map<String, Object> params;

}

响应体数据

当查询护理项目的时候,并不能展示详细的返回结果,如下图

8eb88da6-842a-4b4a-9eee-69ddaf39f566

想要解决这个问题,有两步操作

  • 使用@ApiModel和@ApiModelProperty注解对返回值的类型进行说明(已完成)
  • 需要在controller类的方法上指定返回值类型
  • 返回一个对象
  • 返回数据列表(分页或不分页)

返回一个对象

  • 在目前的代码中,返回一个对象的接口代码,是根据id查询对应的对象,并返回
  • 详细代码如下:
@ApiOperation("获取护理项目详细信息")
@PreAuthorize("@ss.hasPermi('nursing:nursingProject:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@ApiParam("护理项目ID") @PathVariable("id") Long id)
{
    return success(nursingProjectService.selectNursingProjectById(id));
}

这个代码并不能在Swagger中展示详细的返回结果说明,因为目前的返回值是一个AjaxResult,并没有指定泛型

咱们需要使用若依框架中提供的另外一个返回值类型:

07b23398-4964-4196-bf85-445f9bfe580c

在R这个类中也提供了详细的返回值的方法,有成功的,有失败的等等

修改NursingProjectController类中的方法返回值:

/**
 * 获取护理项目详细信息
 */
@PreAuthorize("@ss.hasPermi('nursing:project:query')")
@GetMapping(value = "/{id}")
@ApiOperation(value = "获取护理项目详细信息", notes = "根据ID获取护理项目详细信息")
@ApiImplicitParam(name = "id", value = "护理项目ID", required = true, dataType = "Long", paramType = "path")
public R<NursingProject> getInfo(@PathVariable("id") Long id)
{
    NursingProject nursingProject = nursingProjectService.selectNursingProjectById(id);
    return R.ok(nursingProject);
}

最终的效果如下:

882c7ed8-a15f-42f7-b596-5616b9ac0e5d

返回分页对象

目前的分页列表查询的返回值是TableDataInfo这个类,咱们需要改造下这个类,让它具备接收泛型的能力

  • 定义类中的泛型T
  • 把类中的所有问号改为T
/**
 * 表格分页数据对象
 * 
 * @author alexis
 */
public class TableDataInfo<T> implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 总记录数 */
    private long total;

    /** 列表数据 */
    private List<T> rows;

    /** 消息状态码 */
    private int code;

    /** 消息内容 */
    private String msg;

    /**
     * 表格数据对象
     */
    public TableDataInfo()
    {
    }

    /**
     * 分页
     * 
     * @param list 列表数据
     * @param total 总记录数
     */
    public TableDataInfo(List<T> list, int total)
    {
        this.rows = list;
        this.total = total;
    }

    public List<T> getRows()
    {
        return rows;
    }

    public void setRows(List<T> rows)
    {
        this.rows = rows;
    }

    //其他代码略...

}

修改controller中分页查询的返回值

/**
 * 查询护理项目列表
 */
@PreAuthorize("@ss.hasPermi('nursing:project:list')")
@GetMapping("/list")
@ApiOperation(value = "查询护理项目列表", notes = "根据护理项目条件查询护理项目列表")
public TableDataInfo<List<NursingProject>> list(
    @ApiParam(value = "护理项目查询条件", required = false) NursingProject nursingProject)
{
    startPage();
    List<NursingProject> list = nursingProjectService.selectNursingProjectList(nursingProject);
    return getDataTable(list);
}

重启服务,查看分页接口的返回值效果:

be0e167f-b271-4ed5-b7b6-566e339b4f09

项目开发工具
后端 Java Web入门 SpringBoot
许可协议:  CC BY 4.0
分享

相关文章

1月 15, 2026

异步处理和AMQP协议

异步处理基础概念 在接收设备数据之前,需要先来熟悉一些基本的概念,方便理解接收设备数据的基本思路 同步和异步 同步和异步的概念: 同步(Background Synchronous)是指任务在后台进行处理,但其他任务需要等待任务完成后才能执行 异步(Asynchronous)是指任务的提交和执行是相

1月 15, 2026

Swagger在线接口文档

在线接口文档 在开发中,如果遇到后端项目开发完毕,但是前端项目还未开发完成,但又需要对后端接口进行测试 先前的解决方式是通过第三方接口测试软件,如postman、apifox等进行测试 但这类测试工具需要清楚的知道接口的路径、请求方式、请求参数,且还需要手动填写对应内容 当与前端对接时,后端还需要提

1月 15, 2026

日志管理技术-ELK

日志管理 查看日志信息对于运维和开发人员来说是非常必要的,常见的查看日志情况如下: 当应用程序或服务出现故障时,查看日志可帮助快速定位问题,了解故障前后的系统状态 通过分析日志,可以监控应用程序性能,识别性能瓶颈或资源消耗异常 在开发和测试过程中,查看日志有助于开发人员调试代码、定位并修复bug,同

下一篇

异步处理和AMQP协议

上一篇

性能优化-Redis数据库

最近更新

  • Hello Halo
  • 状态机
  • 数据表设计规范
  • 缓存优化
  • 事务失效

热门标签

Halo 异常处理 Redisson 并行 Vue 并发 递归 请求限流 SpringAMQP 类加载器

目录

©2026 Norlcayn的博客. 保留部分权利。

使用 Halo 主题 Chirpy