Swagger2Swagger3

news2024/11/17 10:53:04

一、什么是Swagger

        swagger是当下比较流行的实时接口文文档生成工具。接口文档是当前前后端分离项目中必不可少的工具,在前后端开发之前,后端要先出接口文档,前端根据接口文档来进行项目的开发,双方开发结束后在进行联调测试。

        所以接口文档其实就是开发之前双方之间的一种约定。通常接口文档分为离线的和实时的。离线的接口文档工具有: word(相当于没说), YAPI, 小幺鸡等,这种文档需要程序员在上面编写,也一般具备接口测试功能。通常是由开发人员先在离线接口文档上编写信息,然后交给前端人员参照开发。最大的弊端是当我们的接口程序发生变动时,需要回过头来维护上面的内容,很麻烦,是真的麻烦。

        实时接口文档就是可以根据我们的代码来自动生成相应的接口文档,优点就是我们的代码发生变化时,生成的接口文档也会自动更新,无需我们关注修改,主需要按时发布即可。但是由于是根据代码自动生成的,所以最大的弊端就是代码侵入性强,需要我们在项目代码中集成生成接口文档的相关代码。实时接口文档现在的方案有很多,但是swagger还是其中比较有影响力的一个。

二、SpringBoot集成swagger2

        官网地址: swagger.io 当然,官网都是英文的,看起来还是比较麻烦的。建议大家直接按照我的步骤来,还是很简单的。

        同时在说一点: swagger分为swagger2 和swagger3两个常用版本。二者区别不是很大,主要对于依赖和注解进行了优化。swagger2需要引入2个jar包,swagger3只需要一个,用起来没有什么大的区别。下面以swagger2为例。

第1步:pom.xml中添加Swagger2的坐标

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

第2步:添加Swagger的配置文件

        首先需要添加一个注解 : @EnableSwagger2。 这个注解我们可以添加到SpringBoot的启动类上,也可以自定义一个配置类,放到上面。添加了这个注解以后,就代表我们已经在项目中开启了Swagger的功能。

        我们采用第二种方式,自己定义一个配置类,正好还可以添加一个Docket配置(Swagger API 摘要对象)。 所谓Docket配置,就是一组(一个项目或一个版本)接口文档的配置,比如设置名称, 联系人等等。

        我们在config文件夹下,添加一个SwaggerConfig类。

        在 SwaggerConfig 中添加两个方法:(其中一个方法是为另一个方法作辅助的准备工作)
api()方法使用 @Bean,在启动时初始化,返回实例 Docket(Swagger API 摘要对象),这里需要注意的是 .apis(RequestHandlerSelectors.basePackage("xxx.yyy.zzz")) 指定需要扫描的包路路径,只有此路径下的 Controller 类才会自动生成 Swagger API 文档。

package demo.config;

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

import java.util.ArrayList;
import java.util.List;

/**
 * Swagger配置类
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
                // 此处自行修改为自己的 Controller 包路径。
                .apis(RequestHandlerSelectors.basePackage("demo.controller")).paths(PathSelectors.any())
                .build().globalOperationParameters(setHeaderToken());

    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("XXX 项目接口文挡")
                .description("swagger实战")  //说明信息
                .termsOfServiceUrl("") //文档生成的主页地址
                .version("1.0").build(); //文档版本
    }

    private List<Parameter> setHeaderToken() {
        List<Parameter> pars = new ArrayList<>();
        ParameterBuilder userId = new ParameterBuilder();
        userId.name("token").description("用户TOKEN").modelRef(new ModelRef("string")).parameterType("header")
                .required(true).build();
        pars.add(userId.build());
        return pars;
    }
}

上面就是一个配置案例, 还设置了一个setToken方法,代表生成文档的所有接口中,都要包含一个header类型的token参数。

第3步:给Controller添加Swagger注解

        我们接口文档的直接描述主要就是在Controller这一层,比如这个接口的功能,参数的名称,返回值的名称等。这些值我们都需要在Controller上通过给方法上,请求参数和返回参数上添加对应的注解,swagger才能帮我们生成相应的接口文档。这也就是我前面提到的对现有代码的侵入性。

2.1、案例

        首先先创建一个vo的包,里边写我们的请求和相应参数,使用JavaBean定义出请求和响应的数据结构。注意这里要添加相应的注解

请求参数类UserVO实体

package demo.entity;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("创建User请求参数")
public class UserVO {

    @ApiModelProperty("id")
    private Integer id;

    @ApiModelProperty("姓名")
    private String name;

    @ApiModelProperty("性别")
    private Integer gender;
}

请求响应类User实体 

package demo.entity;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("创建User响应结果")
public class User {

    @ApiModelProperty("id")
    private Integer id;

    @ApiModelProperty("姓名")
    private String name;

    @ApiModelProperty("性别")
    private Integer gender;

    @ApiModelProperty("住址")
    private String addr;
}

TestController 

 

package demo.controller;

import demo.entity.UserVO;
import demo.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/swagger")
@Api(value = "用户接口", tags = {"用户接口"}) //定义接口的组名
public class TestController {

    @ApiOperation("新增用户") //定义接口的名称
    @PostMapping("save")
    public String save(@RequestBody UserVO req) {
        return "success";
    }

    @ApiOperation("根据条件查询用户") //定义接口的名称
    @GetMapping("getById")
    public User getById(@RequestBody User req) {
        return new User();
    }
}

启动项目

        当启动项目的时候,我们发现会出现错误,异常原因是:SpringBoot2.6版本和Swagger2.9.2不兼容导致的。,也有人说是由于guava这个包的版本过低导致的,所以最简单的解决办法是将SpringBoot的版本改到2.6以下。当然,如果项目中的SpringBoot版本不能修改的话,我们还可以在application.yml配置文件中进行修改。

修改application.yml配置文件
PathPatternMatcher匹配路径,Swagger引用的Springfox使用的路径匹配是基于AntPathMatcher的。
所以要想解决,添加配置,将springBoot MVC的路劲匹配模式修改一下即可。

application.yml

spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER

 

再次重启项目,问题解决。

测试访问

访问地址: ip:端口号/swagger-ui.html

正常情况就可以看到我们的界面了。一会再说非正常情况。由于我们只给用户接口添加了注解,所有用户接口是可以直接观察中文文档的。而剩下的两个接口,由于没添加注解,所以都是以默认的形式展示的。

点开接口,我们可以看到接口中的想详细信息

 点击model,可以看到字段的中文描述。点击 Try it out,就可以直接调试接口。同时注意接口中都让填一个token,这就是我们之前的设置成效了。

截止到目前其实swagger的集成就已经完毕了,主要就是根据我们的注解生成文档,并且可以在线调用调试。开发的时候,我们只需要把Controller这一层的请求和响应,以及方法描述等内容先开发完毕,就可以提供给前端让他们参照开发了。

2.2、 [404]问题解决

正常情况我们按照上面的步骤就可以出现页面,但是有些时候可能是由于springBoot的版本过高导致的,我们输入之前的地址,出现404的情况,这个主要是由于项目中无法读取到swagger依赖包下的页面导致的。如果出现了这个问题,我们可以添加一个配置类,让他实现WebMvcConfigurer 接口,在添加一个方法

package demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

 

这个时候在启动就可以了!

2.3、替换UI

上面的整个过程已经完成了,但是生成的接口文档的页面,其实很多人不太喜欢,觉得不太符合国人的使用习惯,所有又有一些大神,提供了其他的UI测试页面。这个页面的使用还是比较广泛的。

修改方式:只需引入一个依赖包:

<dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>

 然后把刚才实现的那个的那个方法再添加一条:

registry.addResourceHandler("doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");

 重新启动项目: 访问路径发生了变化:** ip:端口号/doc.html**

 页面出现了。我们在看看我们的用户接口:

这个风格确实更加的直观,同时也是可以直接进行调试的。大部分的swagger都用的这个风格的文档。

2.4、源代码

swagger2-demo.zip

三、SpringBoot集成swagger3

上面已经很详细的讲解了swagger2的集成方式,而swagger3的集成方式更加的简洁一些。

第1步:pom.xml中添加Swagger3的坐标

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-boot-starter</artifactId>
  <version>3.0.0</version>
</dependency>

第2步:Swagger配置类

然后是替换注解: swagger2使用的开启注解是: @EnableSwagger2
而在swagger3中,这个注解要换成: @EnableOpenApi

 

package demo.config;

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

import java.util.ArrayList;
import java.util.List;

/**
 * Swagger配置类
 */
@Configuration
@EnableOpenApi // v2 不同
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.OAS_30) // v2 不同
                .apiInfo(apiInfo()).select()
                // 此处自行修改为自己的 Controller 包路径。
                .apis(RequestHandlerSelectors.basePackage("demo.controller")).paths(PathSelectors.any())
                .build().globalOperationParameters(setHeaderToken());

    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("XXX 项目接口文挡")
                .description("swagger实战")  //说明信息
                .termsOfServiceUrl("") //文档生成的主页地址
                .version("1.0").build(); //文档版本
    }

    private List<Parameter> setHeaderToken() {
        List<Parameter> pars = new ArrayList<>();
        ParameterBuilder userId = new ParameterBuilder();
        userId.name("token").description("用户TOKEN").modelRef(new ModelRef("string")).parameterType("header")
                .required(true).build();
        pars.add(userId.build());
        return pars;
    }
}

要注意,里边的版本类型换成了 OAS_30, 就是swagger3的意思。 

Tips:OAS 是 OpenAPI Specification 的简称,翻译成中文就是 OpenAPI 说明书。

 同时访问地址:原始地址,也就是没换UI的地址: localhost:8080/swagger-ui/index.html这个要和swagger2区分开。
swagger3的原始UI风格也发生了一些变化:

同时swagger3也是可以更换UI的。方法和swagger2一样。 

源代码

swagger3-demo.zip

扩展:swaggerUI 拦截器和跨域冲突处理

         如果我们的项目中有关于跨域的处理,同时还有拦截器,然后还要使用swagger,这种情况大家要注意了,有可能我们的拦截器会将swagger中的页面路径拦截掉导致swagger页面出不来,当我们在拦截器中把swagger的页面排除掉的时候,也有可能会导致跨域配置的失效。

         详细的解决方案可以看我之前写过的一篇博客: springboot跨域过滤器与swagger拦截器冲突的解决方案
具体解决方案简单提一下:

第1步:定义拦截器

 

/**
 * 拦截器配置
 *
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
 
    @Bean
    public TokenInterceptor tokenInterceptor() {
        return new TokenInterceptor();
    }
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                .addInterceptor(tokenInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login")
                .excludePathPatterns("/user/downloadExcel")
                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
    }
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

第2步:跨域配置 

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
 
@Configuration
public class CorsConfig {
 
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.setAllowCredentials(true);
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }
}

用这两种方式去配置,就可以让他们和平共处了。 

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

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

相关文章

Python程序设计之 —— 简易学生信息管理系统

大家好&#xff0c;我是 Enovo飞鱼&#xff0c;今天分享一个 Python程序设计之 —— 简易学生信息管理系统 &#xff0c;小白或者正在学习Python的小伙伴推荐阅读&#xff0c;加油&#x1f4aa;。 目录 前言 Python 简介 Python 特点 一、项目来源及背景 二、功能设计 …

PTA L1-023 输出GPLT(详解)

前言&#xff1a;本期是关于输出GPLT的详解&#xff0c;内容包括四大模块&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读&#xff0c;今天你c了吗&#xff1f; 题目&#xff1a; 给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字…

概论_第7章_参数估计__区间估计

先看知识结构图 一 置信区间 定义 定义&#xff1a; 设σ\sigmaσ 为总体的未知参数&#xff0c; θ^1θ^1(x1,x2,...,xn),θ^2θ^2(x1,x2,...,xn)\hat \theta_1 \hat\theta_1(x_1,x_2, ..., x_n), \hat \theta_2 \hat\theta_2(x_1,x_2, ..., x_n)θ^1​θ^1​(x1​,x2​,...,x…

YB菜菜的机器学习自学之路(七)——简单了解keras框架

YB菜菜的机器学习自学之路&#xff08;七&#xff09;——简单了解keras框架前提说明1. 机器学习框架-keras1.1 keras框架的特点1.2 keras框架实现一个神经元的建立的过程2. 举例说明2.1 一个神经元 和输入特征为1的案例2.2 多神经元 和单输入特征为1的案例2.3 多输入&#xff…

第11-15章

第11章 枚举和注解 11.1举例 要求创建季节(Season) 对象&#xff0c;请设计并完成。 但是&#xff0c;季节的值是有限的几个值&#xff08;4个季节&#xff09;&#xff0c;不可以再多。 就可以用枚举来解决 枚举&#xff08;enumeration,简写enum&#xff09;,是一组常量的集…

【自学Python】Python字符串对齐教程

Python字符串左对齐 大纲 Python字符串左对齐教程 Python 字符串的左对齐&#xff0c;即在我们需要设定 字符串 为固定的长度时&#xff0c;如果字符串的长度不够&#xff0c;则我们可以指定使用特定的字符在字符串的右边进行填充&#xff0c;从而达到左对齐的目的。 在 Pyt…

请求域名requests.(url = 地址)报错

报错&#xff1a;raise MissingSchema(requests.exceptions.MissingSchema: Invalid URL titles: No scheme supplied. Perhaps you meant http://titles?报错分析&#xff1a;response requests.get(urlurl,headersheaders) # print(response) response.encoding"utf-…

Docker逃逸二三事

Docker逃逸在渗透测试中面向的场景大概是这样&#xff0c;渗透拿到shell后&#xff0c;发现主机是docker环境&#xff0c;要进一步渗透&#xff0c;就必须逃逸到“直接宿主机”。甚至还有物理机运行虚拟机&#xff0c;虚拟机运行Docker容器的情况。那就还要虚拟机逃逸了。所以本…

【LeetCode】2325. 解密消息

给你字符串 key 和 message &#xff0c;分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下&#xff1a; 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。将替换表与普通英文字母表对齐&#xff0c;形成对照表。按照对照表 替换 messag…

C语言课设作业《通讯录》全程记录 ps:动态版本

写在前面&#xff1a; 通讯录算是前面对学过知识的一个综合运用&#xff0c;涉及到的知识点有 &#xff1a;枚举类型&#xff0c;结构体、结构体指针、动态内存分配(malloc,calloc,realloc,free)、typedef关键字、多文件编程等以上内容&#xff0c;设计思想不是太难&#xff0c…

Java多线程环境下使用的集合类

Java标准库中大部分集合类都是线程不安全的, 多线程环境下使用同一个集合类对象, 很可能会出问题; 只有少部分是线程安全的, 比如: Vector, Stack, HashTable这些, 关键方法都会带有synchronized, 但一般是不推荐使用这几个类的. 一. 多线程环境下使用ArrayList ArrayList在多…

浅析设计模式4——模板方法模式

我们在进行软件开发时要想实现可维护、可扩展&#xff0c;就需要尽量复用代码&#xff0c;并且降低代码的耦合度。设计模式就是一种可以提高代码可复用性、可维护性、可扩展性以及可读性的解决方案。大家熟知的23种设计模式&#xff0c;可以分为创建型模式、结构型模式和行为型…

OAuth2简介

目录一、 什么是OAuth2二、OAuth2中的角色三、认证流程四、生活中的Oauth2思维五、令牌的特点六、OAuth2授权方式1、授权码2、隐藏方式3、密码方式4、凭证方式一、 什么是OAuth2 OAuth2.0是目前使用非常广泛的授权机制&#xff0c;用于授权第三方应用获取用户的数据。 举例说明…

使用Vuex的个人理解

一、逻辑原理 要使用 Vuex 进行集中管理数据&#xff08;状态&#xff09;&#xff0c;按照 Vuex 分模块的设 计思想&#xff0c;先在 src 下创建 store 文件夹&#xff0c;然后创建一个根级别的 index.js&#xff0c;作为组装模块并导出 store 地方&#xff08;store 对象是 …

xss.haozi.me通关教程

10.xss.haozi.me通关教程 0x00 首先整体浏览网站 分别是xss注入点&#xff0c;注入后的HTML代码以及网页源码 构造常规payload&#xff1a; <script>alert(1)</script> 成功通关 0x01 看到注入点是在标签中, 所以用上一题的方法是不会被解析的, 故需要去构造…

MySQL_索引

索引概述 简介 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff…

OKR之剑·实战篇04:OKR执行过程优化的那些关键事

作者&#xff1a;vivo 互联网平台产品研发团队 本文是《OKR 之剑》系列之实战第 4 篇——OKR执行过程不是一成不变的&#xff0c;团队和个人在执行中不断优化执行的具体行动&#xff0c;保障OKR的高效执行。 前言 “言治骨角者&#xff0c;既切之而复磋之&#xff1b;治玉石者…

vue axios post 请求415、400、500、404报错时

vue axios post 请求415 415错误的解释&#xff0c;服务器无法处理请求附带的媒体格式。 解决方式&#xff1a; 后端参数使用了RequestBody注解进行绑定&#xff0c;用了这个注解进行数据绑定&#xff0c;只能接受数据类型为 Content-Type类型为application/json 1.后台修改&am…

notepad++ 中安装NppExec插件

一、何为NppExec简单的说&#xff0c;这个插件可以让用户在NPP中直接运行一些命令和程序&#xff0c;而不用启动这些命令和程序对应的实际工具或编译器。1. NppExec是...NppExec是介于Notepad和外部工具/编译器之间的一个中间件。它允许用户在NPP中直接运行这些工具/编译器。Np…

智能管理PoE交换机

随着网络化信息化的快速发展&#xff0c;以太网供电&#xff08;PoE&#xff09;的优势逐渐被大家所熟知。只需要一根网线&#xff0c;PoE在给网络设备供电的同时还能传输数据&#xff0c;免布线&#xff0c;节省成本和空间&#xff0c;设备可随意移动&#xff0c;系统部署灵活…