• Swagger学习笔记


    查看swagger教学视频,请点击 《狂神说java》: https://www.bilibili.com/video/BV1Y441197Lw?p=1 记得投币三连呀~~

    Swagger

    学习目标:

    • 了解Swagger的作用和概念
    • 了解前后端分离
    • 在SpringBoot中继承Swagger

    Swagger简介

    前后端分离

    Vue + SpringBoot

    后端时代:

    ​ 前端只用管理静态页面(html),再交给后端。后端通过模板引擎(如jsp)将页面重构,后端是主力!

    前后端分离时代:

    • 后端:后端控制层,服务层,数据访问层 【后端团队】

    • 前端:前端控制层,视图层 【前端团队】

      • 伪造后端数据,json。数据已经存在了,不需要后端,前端工程依旧可以跑起来。
    • 前后端如何交互?===> API

    • 前后端相对独立,松耦合;

    • 前后端甚至可以部署在不同服务器上。

    产生一个问题:

    • 前后端集成联调,前端人员和后端人员无法做到“及时协商,尽早解决”,最终导致问题集中爆发;

    • 首先指定schema,实时更新API,降低集成风险;

    • 早些年:指定word计划文档;

    • 前后端分离:

      • 前端测试后端接口使用:postman
      • 后端提供接口,需要实时更新最新的消息及改动!

    Swagger

    • 号称世界上最流行的API框架

    • Restful API文档在线自动生成工具=> API文档与API定义同步更新

    • 直接运行,可以在线测试API接口;

    • 支持多种语言:(java、php...)

    官网:https://swagger.io/

    在项目中使用Swagger需要springfox:

    • swagger2
    • ui

    SpringBoot集成Swagger

    目录结构:

    1、新建springboot项目

    2、导入依赖

    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.9.2</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.9.2</version>
            </dependency>
    

    3、编写helloworld

    4、配置Swagger===>Config

    @Configuration
    @EnableSwagger2      //开启swagger2
    public class SwaggerConfig {
    
    }
    

    5、测试运行:http://localhost:8080/swagger-ui.html

    配置Swagger

    配置了Swagger的docket的bean实例

    @Configuration
    @EnableSwagger2      //开启swagger2
    public class SwaggerConfig {
    
        //配置了swagger的docket的bean实例
        @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo());
        }
    
        
    

    配置swagger的信息

        //配置swagger信息ApiInfo
        private ApiInfo apiInfo(){
            
            //作者信息
            Contact CONTACT = new Contact("ztx", "https://www.cnblogs.com/", "123445@qq.com");
            
    		//要返回的swagger信息=apiInfo
            return new ApiInfo("小帅哥的swaggerAPI文档",
                    "这个帅哥确实帅",
                    "1.0",
                    "https://www.bilibili.com/video/BV1Y441197Lw?p=2",
                    CONTACT,
                    "Apache 2.0",
                    "http://www.apache.org/licenses/LICENSE-2.0",
                    new ArrayList());
        }
    }
    

    之前的swagger信息是默认的,以上代码是我们对swagger信息的重新定义!

    自定义后的swagger信息,如下:

    Swagger配置扫描接口

    Docket.select

    用法: .select() + ( .apis(xxx) / .path(xxx) ) + .build() 必须要和 .build() 方法搭配使用!!!

        //配置了swagger的docket的bean实例
        @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    //RequestHandlerSelectors,配置要扫描接口的方式
                    //basePackage():指定要扫描的包
                            //.basePackage("com.ztx.swagger.controller")
                    //withClassAnnotation():扫描类上的注解,参数是一个注解的反射对象
                            //.withClassAnnotation(RestController.class)
                    //withMethodAnnotation():扫描方法上的注解
                            //.withMethodAnnotation(RequestMapping.class)
                    //any():扫描全部,无参数
                    //none():不扫描,无参数              
                    .apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
                    //path():过滤什么路径
                    //.paths(PathSelectors.ant("/ztx/**"))
                    .build();
        }
    

    因为在配置扫描接口方式时,我们定义的是只扫描"com.ztx.swagger.controller"包下面的,所以页面中接口信息部分如下:

    配置是否开启Swagger

        @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    //enable:是否开启swagger,如果为false,则swagger不开启,不能在浏览器中访问到swagger页面
                    .enable(false)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
                    .build();
        }
    

    浏览器中访问不到swagger页面

    问题:如何做到我只希望我的swagger在生产环境中使用,在发布时不使用?

    • 判断是不是生产环境 flag = false or flag = true
    • 注入enable(flag)

    当前项目环境设为: 开发环境 !

    设置开发环境和生产环境服务器端口号!

    判断当前环境是否开发环境,从而决定是否开启swagger!

        @Bean  //获取当前环境需要用到environment对象
        public Docket docket(Environment environment){
    
            //设置要显示的Swagger环境,是否处于dev或test环境
            Profiles profiles = Profiles.of("dev","test");
            //通过environment.acceptsProfiles判断是否处在自己设定的环境当中
            boolean flag = environment.acceptsProfiles(profiles);
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    //是否开启swagger
                    .enable(flag)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
                    .build();
        }
    

    可以发现swagger页面只有在开发环境下的8081端口才可以显示,在生产环境的8082端口无效:


    配置swaggerAPI文档分组

    当多人协作开发时,每个人负责各自不同的业务区,这时为了便于显示每个人的业务是否合规,就需要用到分组功能,一个docket对应一个人:

        @Bean   
        public Docket docket1(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .groupName("李华")
                	。。。。。
                    .enable(false);
        }
    
        @Bean
        public Docket docket2(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .groupName("旺仔")
               		。。。。。
                    .enable(true);
        }
        
        //配置了swagger的docket的bean实例
        @Bean
        public Docket docket(Environment environment){
    
            //设置要显示的Swagger环境
            Profiles profiles = Profiles.of("dev","test");
            //通过environment.acceptsProfiles判断是否处在自己设定的环境当中
            boolean flag = environment.acceptsProfiles(profiles);
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .groupName("狂神")
                    .enable(flag)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
                    .build();
        }
    

    前端页面展示:(可以看到有三个定义的组,且每个组对应的swagger页面内容也是不同的)

    配置文档注释

    创建一个实体类User:

    public class User {
    
        public String username;
        public String password;
    
    }
    

    在controller中添加如下方法:

        //只要我们的接口中,返回值中存在实体类,它就会被扫描到swagger中
        @PostMapping("/user")
        public User user(){
            return new User();
    

    在User实体类添加Api相关注解:

    @ApiModel("用户实体类")
    public class User {
    
        @ApiModelProperty("用户名")
        public String username;
        @ApiModelProperty("密码")
        public String password;
    
    }
    

    加与没加Api注解的对比,如下图:


    发现@Api注解 主要起到注释的作用!

    在HelloController下使用Api注解:

    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        public String hello(){
            return "hello";
        }
    
        //只要我们的接口中,返回值中存在实体类,它就会被扫描到swagger中
        @PostMapping("/user")
        public User user(){
            return new User();
        }
    
        //Operation接口,不是放在类上,是方法上
        @ApiOperation("这是一个hello2方法")
        @GetMapping("/hello2")
        public String hello2(@ApiParam("用户名") String username){
            return "hello2"+username;
        }
    }
    

    前端页面显示:发现使用api注解的地方都出现了注释!!!

    补充一点:

    @Api(tags = "hello控制器")  //添加在类上,该控制器注释同样会出现在页面文档中,由于该处是后加的,故上面截图就没体现出来
    @RestController
    public class HelloController {....}
    

    常用注解

    Swagger的所有注解定义在io.swagger.annotations包下

    下面列一些经常用到的,未列举出来的可以另行查阅说明:

    Swagger注解 简单说明
    @Api(tags = "xxx模块说明") 作用在模块类上
    @ApiOperation("xxx接口说明") 作用在接口方法上
    @ApiModel("xxxPOJO说明") 作用在模型类上:如VO、BO
    @ApiModelProperty(value = "xxx属性说明",hidden = true) 作用在类方法和属性上,hidden设置为true可以隐藏该属性
    @ApiParam("xxx参数说明") 作用在参数、方法和字段上,类似@ApiModelProperty

    总结

    1. 我们可以通过swagger给一些比较难理解的属性或者接口,增加注释信息
    2. 接口文档实时更新
    3. 可以在线测试
  • 相关阅读:
    程序员这生必须掌握的两种图形
    用一张组织架构图说清楚类和对象
    简单工厂、工厂方法、抽象工厂的比较与分析
    rabbitmq系列(一)初识rabbitmq
    【最新】经典面试100问,附答案
    使用wordPress搭建个人博客
    调试接口你还在用postman吗
    Token ,Cookie、Session傻傻分不清楚?
    你不可不知的自定义注解
    使用aop加解密http接口
  • 原文地址:https://www.cnblogs.com/churujianghudezai/p/13152283.html
Copyright © 2020-2023  润新知