Springboot整合swagger

swagger介绍

相信无论是前端还是后端开发,都被接口文档所折磨过,如今大多项目采用前后的分离,前端与后端的交互变成了接口文档,而维护接口文档也需要很多的时间,接口文档随着版本的更新迭代不能实时更新往往就跟不上代码了,发现了问题即而就要去解决,我们的swagger就能很好的解决这个问题。

swagger 是一个 api 文档维护组织,后来成为了 Open API 标准的主要定义者,现在最新的版本为17年发布的 Swagger3(Open Api3)。国内绝大部分人还在用过时的swagger2(17年停止维护并更名为swagger3)swagger2的包名为 io.swagger,而swagger3的包名为 io.swagger.core.v3。

使用 swagger3 注解代替 swagger2 的(可选)

这一步是可选的,因为改动太大,故 springfox对旧版的 swagger做了兼容处理。 但不知道未来会不会不兼容,这里列出如何用 swagger 3 的注解(已经在上面引入)代替 swagger 2 的 (注意修改 swagger 3 注解的包路径为io.swagger.v3.oas.annotations.)

对应关系为:

常用注解

Swagger注解 简单说明

@Api(tags = “xxx模块说明”) 作用在模块类上

@ApiOperation(“xxx接口说明”) 作用在接口方法上

@ApiModel(“xxxPOJO说明”) 作用在模型类上:如VO、BO @ApiModelProperty(value = “xxx属性说明”,hidden = true) 作用在类方法和属性上,hidden设置为true可以隐藏该属性

@ApiParam(“xxx参数说明”) 作用在参数、方法和字段上,类似@ApiModelProperty

使用上的区别

新版本和老版本的区别主要体现在以下 4 个方面:

1:依赖项的添加不同:新版本只需要添加一项,而老版本需要添加两项;

2:启动 Swagger 的注解不同:新版本使用的是 @EnableOpenApi,而老版本是 @EnableSwagger2;

3:Docket(文档摘要信息)的文件类型配置不同:新版本配置的是 OAS_3,而老版本是 SWAGGER_2;

4:Swagger UI 访问地址不同:启动项目,

访问地址:http://localhost:8080/swagger-ui/index.html,(注意swagger2.x版本中访问的地址的为: http://localhost:8080/swagger-ui.html)

Ps:在使用swagger的时候,通常需要使用【@ApiParam】注解指定接口中参数的名字,特别是接口是post请求且参数使用了@RequestParam注解时

踩坑指南

使用springboot2.6.x版本与swagger使用时可能会有冲突会报一个错误documentationPluginsBootstrapper‘; java.lang.NullPointerException 

解决思路:

1.降低springboot的版本可以避开这个错误

2.网上引用这个博主的解决方案可以成功解决02.Spring Boot 2.6.x整合Swagger启动失败报错问题解决(治标还治_这是王乃醒的博客-CSDN博客

话不多说上代码看效果:

一 .springboot2.52+swagger3.0使用

1.应用主类增加注解@EnableOpenApi

2.Maven项目中引入springfox-boot-starter依赖

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

3.创建配置文件
  1. 创建SwaggerConfiguration类配置文件 , 使用@EnableOpenApi注解,启用swagger配置,可以设置配置相关参数

    package com.swaggerdemo.demo.config;
    ​
    import org.springframework.boot.SpringBootVersion;
    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.oas.annotations.EnableOpenApi;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    ​
    import java.util.Arrays;
    import java.util.LinkedHashSet;
    import java.util.Set;
    @EnableOpenApi
    @Configuration
    public class SwaggerConfiguration {
        private final SwaggerProperties swaggerProperties;
        public SwaggerConfiguration(SwaggerProperties swaggerProperties) {
            this.swaggerProperties = swaggerProperties;
        }
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.OAS_30).pathMapping("/")
    ​
                    // 定义是否开启swagger,false为关闭,可以通过变量控制
                    .enable(swaggerProperties.getEnable())
    ​
                    // 将api的元信息设置为包含在json ResourceListing响应中。
                    .apiInfo(apiInfo())
    ​
                    // 接口调试地址
                    .host(swaggerProperties.getTryHost())
    ​
                    // 选择哪些接口作为swagger的doc发布
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(PathSelectors.any())
                    .build()
    ​
                    // 支持的通讯协议集合
                    .protocols(newHashSet("https", "http"));
        }
        /**
         * API 页面上半部分展示信息
         */
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder().title(swaggerProperties.getApplicationName() + " Api Doc")
                    .description(swaggerProperties.getApplicationDescription())
                    .contact(new Contact("lighter", null, "123456@gmail.com"))
                    .version("Application Version: " + swaggerProperties.getApplicationVersion() + ", Spring Boot Version: " + SpringBootVersion.getVersion())
                    .build();
        }
        
        @SafeVarargs
        private final <T> Set<T> newHashSet(T... ts) {
            if (ts.length > 0) {
                return new LinkedHashSet<>(Arrays.asList(ts));
            }
            return null;
        }
    }

如需要详细配置文件配置请参考:

一个完整详细的springfox swagger配置示例:

import io.swagger.models.auth.In;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.boot.SpringBootVersion;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
​
import java.lang.reflect.Field;
import java.util.*;
​
@EnableOpenApi
@Configuration
public class SwaggerConfiguration implements WebMvcConfigurer {
    private final SwaggerProperties swaggerProperties;
​
    public SwaggerConfiguration(SwaggerProperties swaggerProperties) {
        this.swaggerProperties = swaggerProperties;
    }
​
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.OAS_30).pathMapping("/")
​
                // 定义是否开启swagger,false为关闭,可以通过变量控制
                .enable(swaggerProperties.getEnable())
​
                // 将api的元信息设置为包含在json ResourceListing响应中。 
                .apiInfo(apiInfo())
​
                // 接口调试地址
                .host(swaggerProperties.getTryHost())
​
                // 选择哪些接口作为swagger的doc发布
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
​
                // 支持的通讯协议集合
                .protocols(newHashSet("https", "http"))
​
                // 授权信息设置,必要的header token等认证信息
                .securitySchemes(securitySchemes())
​
                // 授权信息全局应用
                .securityContexts(securityContexts());
    }
​
    /**
     * API 页面上半部分展示信息
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title(swaggerProperties.getApplicationName() + " Api Doc")
                .description(swaggerProperties.getApplicationDescription())
                .contact(new Contact("lighter", null, "123456@gmail.com"))
                .version("Application Version: " + swaggerProperties.getApplicationVersion() + ", Spring Boot Version: " + SpringBootVersion.getVersion())
                .build();
    }
​
    /**
     * 设置授权信息
     */
    private List<SecurityScheme> securitySchemes() {
        ApiKey apiKey = new ApiKey("BASE_TOKEN", "token", In.HEADER.toValue());
        return Collections.singletonList(apiKey);
    }
​
    /**
     * 授权信息全局应用
     */
    private List<SecurityContext> securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        .securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
                        .build()
        );
    }
​
    @SafeVarargs
    private final <T> Set<T> newHashSet(T... ts) {
        if (ts.length > 0) {
            return new LinkedHashSet<>(Arrays.asList(ts));
        }
        return null;
    }
​
    /**
     * 通用拦截器排除swagger设置,所有拦截器都会自动加swagger相关的资源排除信息
     */
    @SuppressWarnings("unchecked")
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        try {
            Field registrationsField = FieldUtils.getField(InterceptorRegistry.class, "registrations", true);
            List<InterceptorRegistration> registrations = (List<InterceptorRegistration>) ReflectionUtils.getField(registrationsField, registry);
            if (registrations != null) {
                for (InterceptorRegistration interceptorRegistration : registrations) {
                    interceptorRegistration
                            .excludePathPatterns("/swagger**/**")
                            .excludePathPatterns("/webjars/**")
                            .excludePathPatterns("/v3/**")
                            .excludePathPatterns("/doc.html");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
}

4.自定义swagger配置类SwaggerProperties

package com.swaggerdemo.demo.config;
​
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties {
    /**
     * 是否开启swagger,生产环境一般关闭,所以这里定义一个变量
     */
    private Boolean enable;
    /**
     * 项目应用名
     */
    private String applicationName;
    /**
     * 项目版本信息
     */
    private String applicationVersion;
    /**
     * 项目描述信息
     */
    private String applicationDescription;
    /**
     * 接口调试地址
     */
    private String tryHost;
​
    public Boolean getEnable() {
        return enable;
    }
​
    public void setEnable(Boolean enable) {
        this.enable = enable;
    }
​
    public String getApplicationName() {
        return applicationName;
    }
​
    public void setApplicationName(String applicationName) {
        this.applicationName = applicationName;
    }
​
    public String getApplicationVersion() {
        return applicationVersion;
    }
​
    public void setApplicationVersion(String applicationVersion) {
        this.applicationVersion = applicationVersion;
    }
​
    public String getApplicationDescription() {
        return applicationDescription;
    }
​
    public void setApplicationDescription(String applicationDescription) {
        this.applicationDescription = applicationDescription;
    }
​
    public String getTryHost() {
        return tryHost;
    }
​
    public void setTryHost(String tryHost) {
        this.tryHost = tryHost;
    }
}

6.编写测试接口(采用的lombok插件):

实体类编写:

package com.swaggerdemo.demo.entity;
​
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
@Schema(name = "demo实体类")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Demo {
    @Schema(name = "id")
    private Integer id;
    @Schema(name = "name")
    private String name;
​
}

Controller类:

package com.swaggerdemo.demo.Controller;
import com.swaggerdemo.demo.config.JsonResult;
import com.swaggerdemo.demo.entity.Demo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
@Tag(name = "test接口类")
@RestController
public class TestController {
​
    @Operation(summary = "test接口描述")
    @RequestMapping("/test")
    public String test(){
        return "success";
    }
​
    @GetMapping("/get/{id}")
    @Operation(summary = "根据用户唯一标识获取用户信息")
    public JsonResult<Demo> getUserInfo(  @Parameter(description = "用户唯一标识") Integer id) {
        // 模拟数据库中根据id获取User信息
        Demo user = new Demo( id,"123456");
        return new JsonResult(user);
    }
​
}

实现效果:

 

 

资料

swagger 官网:swagger.io(https://swagger.io/) springfox 官网:springfox(http://springfox.github.io/springfox/) springfox Github 仓库:springfox / springfox(https://github.com/springfox/springfox) springfox-demos Github 仓库:springfox / springfox-demos(https://github.com/springfox/springfox-demos) springfox Maven 仓库:Home » io.springfox(https://mvnrepository.com/artifact/io.springfox)

Swagger2.0使用

采用springboot2.52+swagger2.9.2

1.导入maven依赖:

       
<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.编写swagger2.0的配置文件

package com.wq.springbootdemo.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 SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                // 指定构建api文档的详细信息的方法:apiInfo()
                .apiInfo(apiInfo())
                .select()
                // 指定要生成api接口的包路径,这里把controller作为包路径,生成controller中的所有接口
                .apis(RequestHandlerSelectors.basePackage("com.wq.springbootdemo.Controller"))
                .paths(PathSelectors.any())
                .build();
    }
    /**
     * 构建api文档的详细信息
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                // 设置页面标题
                .title("Spring Boot集成Swagger2接口总览")
                // 设置接口描述
                .description("Spring Boot集成Swagger2测试")
                // 设置联系方式
                .contact("wq," + "qq: 2964906495")
                // 设置版本
                .version("1.0")
                // 构建
                .build();
    }
}

3.编写实体类

package com.wq.springbootdemo.entity;
​
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
@ApiModel(value = "demo实体类")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Demo {
    @ApiModelProperty(value = "id")
    private Integer id;
    @ApiModelProperty(name = "name")
    private String name;
​
}
​
}

4.编写controller

package com.wq.springbootdemo.Controller;
​
import com.wq.springbootdemo.config.JsonResult;
import com.wq.springbootdemo.entity.Demo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
​
@Api(value = "测试Controller")
@RestController
public class TestController {
​
    @GetMapping("/get/{id}")
    @ApiOperation(value = "根据用户唯一标识获取用户信息")
    public JsonResult<Demo> getUserInfo(@PathVariable @ApiParam(value = "用户唯一标识") Integer id) {
        // 模拟数据库中根据id获取User信息
        Demo user = new Demo(id, "123456");
        return new JsonResult(user);
    }
    
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值