Web菜鸟入门教程 - Swagger实现自动生成文档

news2024/10/5 16:22:17

如果是一个人把啥都开发了,那用不到Swagger-UI,但一般情况是前后端分离的,所以就需要告诉前端开发人员都有哪些接口,传入什么参数,怎么调用,返回什么。有了Swagger-UI就能把这部分文档编写的业务给省去了。

Swagger-UI是HTML, Javascript, CSS的一个集合,可以动态地根据注解生成在线API文档。

Swagger是通过扫描注册生成文档的,常用的注解有:

  • @Api:用于修饰Controller类,生成Controller相关文档信息
  • @ApiOperation:用于修饰Controller类中的方法,生成接口方法相关文档信息
  • @ApiParam:用于修饰接口中的参数,生成接口参数相关文档信息
  • @ApiModelProperty:用于修饰实体类的属性,当实体类是请求参数或返回结果时,直接生成相关文档信息

和上一篇文章介绍Mybatis-Gen一样,Swagger生成文档也是三要素:

  • 环境
  • 配置
  • 执行

GetStart

首先添加项目依赖,在pom.xml里面:

<!--Swagger-UI API文档生产工具-->
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger2</artifactId>
  <version>2.7.0</version>
</dependency>
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger-ui</artifactId>
  <version>2.7.0</version>
</dependency>

接下来要搞定配置文件,配置文件就简单啦,就是指定扫描方式以及文档属性:

Swagger2Config.java

package org.lange.study.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //Swagger对生成API文档的范围有三种不同的选择
                //1. 生成指定包下面的类的API文档
                //2. 生成有指定注解的类的API文档
                //3. 生成有指定注解的方法的API文档
                //这里指定为当前包下controller生成API文档
                .apis(RequestHandlerSelectors.basePackage("org.lange.study.controller"))
                //为有@Api注解的Controller生成API文档
//                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
                //为有@ApiOperation注解的方法生成API文档
//                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SwaggerUI演示")
                .description("mall")
                .contact("zhonglunshun")
                .version("1.0")
                .build();
    }
}

配置好了,接下来我们需要在controller里面加一些内容,不然会扫描不到看不出来效果(正好趁机把业务补充一下,添加增删查改)。

定义一个业务接口PmsBrandService.java

package org.lange.study.service;

import org.lange.study.mbg.model.PmsBrand;

import java.util.List;

public interface PmsBrandService {
    List<PmsBrand> listAllBrand();

    int createBrand(PmsBrand brand);

    int updateBrand(Long id, PmsBrand brand);

    int deleteBrand(Long id);

    List<PmsBrand> listBrand(int pageNum, int pageSize);

    PmsBrand getBrand(Long id);
}

然后实现之PmsBrandServiceImpl.java(这个时候实现真的超级简单了,就是用前面一篇文章用到的Mybatis-gen生成的代码去查询操作就好了),通常查询会用到分页查询,分页查询很简单,所以这里一起说下了:
Pom文件引入分页查询依赖:

		<!--MyBatis分页插件-->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper-spring-boot-starter</artifactId>
			<version>1.4.5</version>
		</dependency>

然后在list方法开始的时候执行startpage就ok了,关于Mabatis生成的基本Sql功能,这里不多介绍了,有兴趣的可以去看下Mybatis的详细使用扩展一下:

PmsBrandServiceImpl.java:

package org.lange.study.service.impl;

import com.github.pagehelper.PageHelper;
import org.lange.study.mbg.mapper.PmsBrandMapper;
import org.lange.study.mbg.model.PmsBrand;
import org.lange.study.mbg.model.PmsBrandExample;
import org.lange.study.service.PmsBrandService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class PmsBrandServiceImpl implements PmsBrandService {
    @Autowired
    private PmsBrandMapper brandMapper;

    @Override
    public List<PmsBrand> listAllBrand() {
        return brandMapper.selectByExample(new PmsBrandExample());
    }

    @Override
    public int createBrand(PmsBrand brand) {
        return brandMapper.insertSelective(brand);
    }

    @Override
    public int updateBrand(Long id, PmsBrand brand) {
        brand.setId(id);
        return brandMapper.updateByPrimaryKeySelective(brand);
    }

    @Override
    public int deleteBrand(Long id) {
        return brandMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<PmsBrand> listBrand(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return brandMapper.selectByExample(new PmsBrandExample());
    }

    @Override
    public PmsBrand getBrand(Long id) {
        return brandMapper.selectByPrimaryKey(id);
    }
}

其他地方都很好理解,list接口这里我们发现他返回的是一个用CommonPage封装的page对象,为什么要这么做呢?因为我们用分页查询后,希望客户端在接受后更方便地处理查询的数据列表,因此需要告诉他查询了什么,怎么查询的。

PageHelper维护了每次的查询结果,所以它能自动帮我们分页后封装,这个是引入分页查询的好处,看下CommonPage的封装就明白了:

package org.lange.study.common.api;

import com.github.pagehelper.PageInfo;

import java.util.List;

/**
 * 分页数据封装类
 */
public class CommonPage<T> {
    private Integer pageNum;
    private Integer pageSize;
    private Integer totalPage;
    private Long total;
    private List<T> list;

    /**
     * 将PageHelper分页后的list转为分页信息
     */
    public static <T> CommonPage<T> restPage(List<T> list) {
        CommonPage<T> result = new CommonPage<T>();
        PageInfo<T> pageInfo = new PageInfo<T>(list);
        result.setTotalPage(pageInfo.getPages());
        result.setPageNum(pageInfo.getPageNum());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotal(pageInfo.getTotal());
        result.setList(pageInfo.getList());
        return result;
    }

    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
    }
}

到这里其实就可以生成Api文档了,Swagger还提供了一种自定义Api注释的生成规则的方法。前面在介绍Bybatis生成器的时候有引入但是并没有介绍怎么用,这里顺带提一下。

CommentGenerator为MyBatis Generator的自定义注释生成器,简单理解就是Swagger在生成Api的时候同时能给代码生成注释(直接修改代码),这当然很好,但是有些时候我们觉得他添加的不美观想自己定制一下,那就需要配置这个

CommentGenerator.java:


/**
 * 自定义注释生成器
 */
public class CommentGenerator extends DefaultCommentGenerator {
    private boolean addRemarkComments = false;

    /**
     * 设置用户配置的参数,这个属性对应的就是项目中引入的properties文件
     * 这里表示读取名为addRemarkComments的属性
     */
    @Override
    public void addConfigurationProperties(Properties properties) {
        super.addConfigurationProperties(properties);
        this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
    }

    /**
     * 给字段添加注释,如果需要添加且注释不是空的,那就给他加一下
     */
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable,
                                IntrospectedColumn introspectedColumn) {
        String remarks = introspectedColumn.getRemarks();
        //根据参数和备注信息判断是否添加备注信息
        if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
            addFieldJavaDoc(field, remarks);
        }
    }

    /**
     * 给model的字段添加注释,以/** **/的方式,里面就一行一行的家。当然咯你也可以根据自己喜欢来定制
     */
    private void addFieldJavaDoc(Field field, String remarks) {
        //文档注释开始
        field.addJavaDocLine("/**");
        //获取数据库字段的备注信息
        String[] remarkLines = remarks.split(System.getProperty("line.separator"));
        for (String remarkLine : remarkLines) {
            field.addJavaDocLine(" * " + remarkLine);
        }
//        addJavadocTag(field, false);
        field.addJavaDocLine(" */");
    }

}

在这里插入图片描述

这个时候注释就出来了。然后我们看下接口文档是不是也生成了:
接口地址:http://localhost:8080/swagger-ui.html
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/894156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

抓洞指南- drupal1 代码执行 (CVE-2018-7600)

一个非常憨逼的事情&#xff0c;就是不知道flag在哪&#xff0c;然后突发奇想&#xff0c;既然把指令都能执行命令&#xff0c;如果直接ls /tmp,然后数据就拿到手了。这地方卡了我很久&#xff0c;看了很多教程感觉都不一样。 POST /user/register?element_parentsaccount/ma…

问道管理:沪指震荡微跌,保险、银行板块拉升,环保板块表现活跃

18日早盘&#xff0c;两市股指盘中震动回落&#xff0c;沪指翻绿&#xff0c;深成指、创业板指均走低&#xff1b;北向资金继续大幅流出&#xff0c;半日净卖出近50亿元。 截至午间收盘&#xff0c;沪指微跌0.06%报3161.97点&#xff0c;深成指跌0.69%&#xff0c;创业板指跌0.…

09 - 网络通信优化之序列化:避免使用Java序列化

当前大部分后端服务都是基于微服务架构实现的。服务按照业务划分被拆分&#xff0c;实现了服务的解偶&#xff0c;但同时也带来了新的问题&#xff0c;不同业务之间通信需要通过接口实现调用。两个服务之间要共享一个数据对象&#xff0c;就需要从对象转换成二进制流&#xff0…

216、仿真-基于51单片机温度烟雾人体感应布防报警Proteus仿真设计(程序+Proteus仿真+原理图+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、原理图 五、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选…

【MT32F006】MT32F006之CS1237采集秤传感器

本文最后修改时间&#xff1a;2023年06月07日 一、本节简介 本文介绍如何使用MT32F006连接CS1237芯片采集秤传感器。 二、实验平台 库版本&#xff1a;V1.0.0 编译软件&#xff1a;MDK5.37 硬件平台&#xff1a;MT32F006开发板&#xff08;主芯片MT32F006&#xff09; 仿真…

北斗时空子链重磅发布!移远通信与中国移动携手打造更加可靠的高精定位产品

8月16日&#xff0c;以“百川聚申城 数智创未来”为主题的2023年中国移动上海产业研究院百川生态大会在上海隆重召开。 本次大会聚焦时空信息、数智交通、工业能源、金融科技等领域&#xff0c;各级领导、产学研专家、企业家共聚一堂&#xff0c;共谋产业、共话行业、共促发展。…

innovus: IMPSP-190 利用率超标,place中断问题

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 这个问题在查看manual之后&#xff0c;工具给出两个解释。一个是setPlaceMode -place_global_max_density $value(0-1)设置的太小了&#xff0c;另一个是place之前加了过量的so…

飞凌嵌入式与您相约艾睿电子技术解决方案展

艾睿电子公司将在深圳主办年度“技术解决方案展”&#xff0c;2023 年展示会将以“启航未来&#xff0c;携手共进”为主题&#xff0c;汇聚百家电子/半导体大厂、制造商、供应商、方案公司及创科公司&#xff0c;展示最前沿的产品和领先技术解决方案&#xff0c;如何能驱动人、…

基于Spring Boot的餐厅订餐网站的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的餐厅订餐网站的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java springbo…

从零玩转系列之微信支付实战PC端装修我的订单页面 | 技术创作特训营第一期

一、前言 欢迎来到本期的博客&#xff01;本篇文章是 PC 端的结尾了,前面经历过九个章节到本章节刚刚好十章节感谢观看我的文章,那么接下来我们将要编写的是我的订单页面. GGBOM! 本篇完毕后将是 UniApp 的篇章感受移动端的诱惑 &#x1f497; 本次为前端知识点如果不懂前段可以…

基于OpenCV的人脸识别和模型训练系统(万字详解)

前言 我们身边的人脸识别有车站检票&#xff0c;监控人脸&#xff0c;无人超市&#xff0c;支付宝人脸支付&#xff0c;上班打卡&#xff0c;人脸解锁手机。 人脸检测是人脸识别系统组成的关键部分之一&#xff0c;其目的是检测出任意给定图片中的包含的一个或多个人脸&#…

Echarts升级7:环状图+标题设置+legend属性

效果 注意的点&#xff1a; title样式颜色设置legend颜色设置legend textStyle 样式设置&#xff1b;formatter样式设置&#xff0c;文字拆分 代码&#xff1a; <template><div style"width: 100%; height: 100%;"><div id"siteStatusStatis…

使用python3编写代码比对excle表格中的日期

表格类似如下&#xff1a; 需要提取H列和I列的日期&#xff0c;并且进行日期分割&#xff0c;提取出日期&#xff0c;将日期倒置&#xff0c;倒置后&#xff0c;拿 关闭时间减去创建时间&#xff0c;得出超过3天的数据&#xff0c;提取出相应的行&#xff1a; # #-* -编码&…

【.net】本地调试运行只能用localhost的问题

【.net】本地调试运行只能用localhost的问题 解决方案 找到到项目目录下 隐藏文件夹 .vs /项目名称/config/applicationhost.config <bindings><binding protocol"http" bindingInformation"*:1738:localhost" /></bindings> 再加一条你…

期待相聚|2023 Google 谷歌开发者大会现场见

直达科技前沿 点亮技术灵感 激发新思妙想 收获多元共进 长按下方图片&#xff0c;扫码报名参会 *仅出于确认身份&#xff0c;请填写与身份证件一致的姓名&#xff0c;并确认邮箱地址及联系电话准确无误。 2023 Google 开发者大会主旨演讲将会分享 Google 如何通过更智能、更…

Harvard transformer NLP 模型 openNMT 简介入门

项目网址&#xff1a; OpenNMT - Open-Source Neural Machine Translation logo&#xff1a; 一&#xff0c;从应用的层面先跑通 Harvard transformer GitHub - harvardnlp/annotated-transformer: An annotated implementation of the Transformer paper. ​git clone http…

跟左神刷算法02 基础

题目1 先根据难度拍个序&#xff0c;难度一样的按收入大的排序&#xff0c;因为他每份都有招无数份人。难度相同的就留一个最大的。难度增加了&#xff0c;而薪水变小了&#xff0c;直接丢掉。难度和薪水保持一个单调性就可以了。 用有序表取做。 key是排序的。 迅速查到小于…

用gdal库读取tif影像并填充边缘,并根据窗口大小滑动裁剪裁剪(包含gdal转PIL)

相关文章 PIL&#xff0c;OPENCV之间的转换关系_pil cvtcolor(image)_番茄就要炒鸡蛋的博客-CSDN博客 python GDAL和PIL图像转换_gdal.readasarray和pil_llc的足迹的博客-CSDN博客 一、原始数据 二、分别读取数据 1、gdal读取的array 2、pil读取的array 三、 gdal转pil image …

交换2个元素的值(3种方法)

1.创建临时变量 int main() {int a10;int b20;int tmp0;printf("before:a:%d,b:%d\n",a,b);tmpa;ab;btmp;printf("after :a:%d,b:%d\n",a,b);return 0; }2.加减法 int main() {int a10;int b20;printf("before:a:%d,b:%d\n",a,b);aab;ba-b;aa-…

470. 用 Rand7() 实现 Rand10()

470. 用 Rand7 实现 Rand10 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 470. 用 Rand7() 实现 Rand10() https://leetcode.cn/problems/implement-rand10-using-rand7/description/ 完成情况&#xff1a; 解…