Swagger 使用总结

发布时间:2023-07-02 11:00

文章目录

  • 一、初识Swagger
  • 二、实战演练
    • 2.1 添加依赖
    • 2.2 创建Swagger配置类
  • 三、 常用注解
    • 3.1 类
    • 3.2 方法上
    • 3.3 方法入参
    • 3.4 实体
    • 3.5 header参数
    • 3.6 file入参
  • 四、拦截器放行
  • 五、文档访问地址
  • 六、Swagger3 Demo
  • 七、Swagger2 Demo

一、初识Swagger

由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。

这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:

由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。

作用总结:

  1. 接口的文档在线自动生成。
  2. 功能测试。

二、实战演练

2.1 添加依赖

在pom.xml中加入Swagger3的依赖

<dependency>
    <groupId>io.springfoxgroupId>
    <artifactId>springfox-boot-starterartifactId>
    <version>3.0.0version>
dependency>

2.2 创建Swagger配置类

@Configuration
public class SwaggerConfig {

    @Bean
    public Docket initDocket(Environment env) {

        //设置要暴漏接口文档的配置环境
        Profiles profile = Profiles.of(\"dev\", \"test\");
        boolean flag = env.acceptsProfiles(profile);
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .enable(flag)
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(\"Swagger3-Demo接口文档\")
                .description(\"XXXX团队\")
                .contact(new Contact(\"XXXX技术团队\", \"http://www.XXXX.com\", \"XXXX@qq.com \"))
                .version(\"1.0\")
                .build();
    }
}

三、 常用注解

3.1 类

@Api():表示这个类是 swagger 资源

  • tags:表示说明内容,只写 tags 就可以省略属性名
  • value:同样是说明,不过会被 tags 替代,没卵用

3.2 方法上

@ApiOperation() :对方法的说明,注解位于方法上

  • value:方法的说明
  • notes:额外注释说明
  • response:返回的对象
  • tags:这个方法会被单独摘出来,重新分组,若没有,所有的方法会在一个Controller分组下

3.3 方法入参

@ApiParam():对方法参数的具体说明,用在方法入参括号里,该注解在post请求参数时,参数名不显示

  • name:参数名
  • value:参数说明
  • required:是否必填

@ApiImplicitParam对方法参数的具体说明,用在方法上@ApiImplicitParams之内,该注解在get,post请求参数时,参数名均正常显示

  • name 参数名称
  • value 参数的简短描述
  • required 是否为必传参数
  • dataType 参数类型,可以为类名,也可以为基本类型(String,int、boolean等)指定也不起作用,没卵用
  • paramType 参数的传入(请求)类型,可选的值有path, query, body, header or form。

3.4 实体

@ApiModel描述一个Model的信息(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候)

  • value : model的别名,默认为类名
  • description: model的详细描述

@ApiModelProperty描述一个model的属性

  • value 属性简短描述
  • example 属性的示例值
  • required 是否为必须值

3.5 header参数

@ApiImplicitParams({      
@ApiImplicitParam(
paramType=\"header\",
name=\"USERTOKEN\",
dataType=\"String\",
required=true,
value=\"用户token\")
    })

3.6 file入参

需要使用@RequestPart 注解

@ApiOperation(value = \"上传文件接口\",notes = \"上传文件接口\")
    @ApiImplicitParams({
            @ApiImplicitParam(name = \"name\", value = \"上传人\")
    })
    @PostMapping(value = \"/uploadFile\")
    public String uploadFile(
    @RequestParam(\"name\") String name,
    @RequestPart(\"file\") MultipartFile file){
        
    }

四、拦截器放行

若项目中有使用拦截器,放行以下路径

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    TokenInterceptor tokenInterceptor;

    /**
     * 拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册token拦截器
        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns(\"/**\")
                .excludePathPatterns(\"/**/swagger-ui/**\")
                .excludePathPatterns(\"/**/swagger-resources/**\")
                .excludePathPatterns(\"/**/v3/**\")
        ;
    }
}

五、文档访问地址

http://ip:port/context-path/swagger-ui/

http://ip:port/context-path/swagger-ui/index.html

六、Swagger3 Demo

/**
 * @Auther: lya
 * @Description: swagger3-演示
 * @Version: 1.0
 */
@RestController
@RequestMapping(\"/oss\")
@Api(value = \"swagger3-演示\",description = \"用来演示Swagger的一些注解\")
public class TestController {


    @ApiOperation(value=\"修改用户密码\", notes=\"根据用户id修改密码\")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType=\"query\", name = \"userId\", value = \"用户ID\", required = true, dataType = \"Integer\"),
        @ApiImplicitParam(paramType=\"query\", name = \"password\", value = \"旧密码\", required = true, dataType = \"String\"),
        @ApiImplicitParam(paramType=\"query\", name = \"newPassword\", value = \"新密码\", required = true, dataType = \"String\")
    })
    @RequestMapping(\"/updatePassword\")
    public String updatePassword(@RequestParam(value=\"userId\") Integer userId, @RequestParam(value=\"password\") String password, 
            @RequestParam(value=\"newPassword\") String newPassword){
         if(userId <= 0 || userId > 2){
             return \"未知的用户\";
         }
         if(StringUtils.isEmpty(password) || StringUtils.isEmpty(newPassword)){
             return \"密码不能为空\";
         }
         if(password.equals(newPassword)){
             return \"新旧密码不能相同\";
         }
         return \"密码修改成功!\";
     }
}

七、Swagger2 Demo

pom.xml

  
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger2artifactId>
            <version>2.9.2version>
            
            <exclusions>
                <exclusion>
                    <groupId>io.springfoxgroupId>
                    <artifactId>swagger-annotationsartifactId>
                exclusion>
                <exclusion>
                    <groupId>io.swaggergroupId>
                    <artifactId>swagger-modelsartifactId>
                exclusion>
            exclusions>
        dependency>
        
        <dependency>
            <groupId>io.swaggergroupId>
            <artifactId>swagger-annotationsartifactId>
            <version>1.5.21version>
        dependency>
        <dependency>
            <groupId>io.swaggergroupId>
            <artifactId>swagger-modelsartifactId>
            <version>1.5.21version>
        dependency>
        
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger-uiartifactId>
            <version>2.9.2version>
        dependency>

config.java


import io.swagger.annotations.ApiOperation;

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

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket initDocket(Environment env) {
        //设置要暴漏接口文档的配置环境
        Profiles profile = Profiles.of(\"dev\", \"test\");
        boolean flag = env.acceptsProfiles(profile);
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName(\"test1\")
                .apiInfo(apiInfo())
                .host(\"base url\")
                .enable(flag)
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    @Bean
    public Docket docket1() {
        return new Docket(DocumentationType.SWAGGER_2)
                //分组
                .groupName(\"test2\")
                //当前分组信息
                .apiInfo(apiInfoByLYA())
                //扫描范围select开始 build结束
                .select()
                //根据给定的包的位置进行扫描
                .apis(RequestHandlerSelectors.basePackage(\"com.yeyoo.support.swagger.controller2\"))
                //类上有对应注解会被扫描
//                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                //路径过滤
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                //标题
                .title(\"Swagger-Demo接口文档\")
                //简介
                .description(\"平台支撑小组\")
                //服务条款
//                .termsOfServiceUrl(\"www.fuwutiaokuan.com\")
                //作者个人信息
                .contact(new Contact(\"平台支撑小组\", \"http://www.baidu.com\", \"9945@qq.com \"))
                //版本
                .version(\"1.0\")
                .build();
    }

    private ApiInfo apiInfoByLYA() {
        return new ApiInfoBuilder()
                //标题
                .title(\"SwaggerByYEYOO接口文档\")
                //简介
                .description(\"lya\")
                //作者个人信息
                .contact(new Contact(\"lya\", \"http://www.baidu.com\", \"9945@qq.com \"))
                //版本
                .version(\"1.0\")
                .build();
    }
}

dao

@Data
@ApiModel(value=\" user \", description=\" 用户实体类 \")
public class User {
    @ApiModelProperty(value = \"用户名\")
    private String name;

    @ApiModelProperty(value = \"年龄\")
    private Integer age;

    @ApiModelProperty(value = \"性别\")
    private Integer sex;
}

controller


import com.yeyoo.support.swagger.pojo.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Api(value = \"用户\", tags = {\"用户测试\"})
@RestController
public class UserController {

    @ApiOperation(value = \"用户测试用例\")
    @RequestMapping(value = \"/user\",method = RequestMethod.POST)
    public void userTest(User user){
        user.setAge(1);
        user.setName(\"1\");
        System.out.println(user.toString());
    }

    @ApiOperation(value=\"修改用户密码\", notes=\"根据用户id修改密码\")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType=\"query\", name = \"userId\", value = \"用户ID\", required = true, dataType = \"Integer\"),
            @ApiImplicitParam(paramType=\"query\", name = \"password\", value = \"旧密码\", required = true, dataType = \"String\"),
            @ApiImplicitParam(paramType=\"query\", name = \"newPassword\", value = \"新密码\", required = true, dataType = \"String\")
    })
    @RequestMapping(\"/updatePassword\")
    public String updatePassword(@RequestParam(value=\"userId\") Integer userId,
                                 @RequestParam(value=\"password\") String password,
                                 @RequestParam(value=\"newPassword\") String newPassword){
        if(userId <= 0 || userId > 2){
            return \"未知的用户\";
        }
        if(StringUtils.isEmpty(password) || StringUtils.isEmpty(newPassword)){
            return \"密码不能为空\";
        }
        if(password.equals(newPassword)){
            return \"新旧密码不能相同\";
        }
        return \"密码修改成功!\";
    }

}

TestApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = {\"com.support.swagger\",\"com.support.redis\"})
@SpringBootApplication(scanBasePackages = \"com.yeyoo.support\")
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号