springboot整合Spring Security+Swagger3

一、springboot整合Spring Security请看:https://blog.csdn.net/sunxiaoju/article/details/109756993

二、Swagger是一个接口文档生成工具,同时提供接口测试调用的辅助功能。

Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因:

  • mSwagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API。
  • Swagger 可以生成客户端SDK代码用于各种不同的平台上的实现。
  • Swagger 文件可以在许多不同的平台上从代码注释中自动生成。
  • Swagger 有一个强大的社区,里面有许多强悍的贡献者。
  • Swagger 文档提供了一个方法,使我们可以用指定的 JSON 或者 YAML 摘要来描述你的 API,包括了比如 names、order 等 API 信息。

你可以通过一个文本编辑器来编辑 Swagger 文件,或者你也可以从你的代码注释中自动生成。各种工具都可以使用 Swagger 文件来生成互动的 API 文档。

注意:用 Swagger 文件生成互动的 API 文档是最精简的,它展示了资源、参数、请求、响应。但是它不会提供你的API如何工作的其他任何一个细节。

Swagger 分成一些不同的块。

  • Swagger spec:这一块对元素的嵌套、命令等采用官方模式。如果你想要对 Swagger 文件手动编码,你必须非常熟悉 Swagger spec。
    • Swagger editor:这是在线编辑器,用于验证你的 YML 格式的内容是否违反 Swagger spec 。YML 是一种句法,依赖于空格和嵌套。你需要对 YML 句法很熟悉才能很好的遵守 Swagger spec 规范。Swagger 编辑器会标出错误并且给你格式提醒(Swagger spec 文件可以使用 JSON 或者 YAML 中的任意一种格式)

    • Swagger-UI:这是一套 HTML/CSS/JS 框架用于解析遵守 Swagger spec 的 JSON 或 YML 文件,并且生成API文档的UI导航。它可以将你的规格文档转换成Swagger Petsotre-like UI。

    • Swagger-codegen:这个工具可以为不同的平台生成客户端 SDK(比如 Java、JavaScript、Python 等)。这些客户端代码帮助开发者在一个规范平台中整合 API ,并且提供了更多健壮的实现,可能包含了多尺度、线程,和其他重要的代码。SDK 是用于支持开发者使用 REST API 的工具。

我们在这里只使用Swagger-UI,下边介绍使用方法

1、在pom.xml中加入如下依赖:

        
            io.springfox
            springfox-boot-starter
            3.0.0
        
        
            org.apache.commons
            commons-lang3
            3.11
        

2、在application.yml中加入如下配置:

# ===== 自定义swagger配置 ===== #
swagger:
  enable: true
  application-name: ${spring.application.name}
  application-version: 1.0
  application-description: springfox swagger 3.0整合Demo
  try-host: http://localhost:${server.port}

如下图所示:

springboot整合Spring Security+Swagger3_第1张图片

2、添加获取属性的配置类SwaggerProperties,代码如下:

package com.best.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author:sunxj
 * @date:2020-12-05 22:05:29
 * @description:swagger配置类SwaggerProperties
 */
@Component
@ConfigurationProperties("swagger")//通过该属性可以获得application.yml中的swagger值
public class SwaggerProperties {
    /**
     * 是否开启swagger,生产环境一般关闭,所以这里定义一个变量
     */
    private Boolean enable;//对应application.yml中的swagger.enable

    /**
     * 项目应用名
     */
    private String applicationName;//对应application.yml中的swagger.application-name

    /**
     * 项目版本信息
     */
    private String applicationVersion;//对应application.yml中的swagger.application.version

    /**
     * 项目描述信息
     */
    private String applicationDescription;//对应application.yml中的swagger.application-description

    /**
     * 接口调试地址
     */
    private String tryHost;//对应application.yml中的swagger.try-host

    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;
    }
}

3、配置swagger3,使得springboot能够扫描到对应的类SwaggerConfiguration,如:

package com.best.config;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.boot.SpringBootVersion;
import org.springframework.context.annotation.Bean;
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.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.*;

/**
 * Swagger配置类
 * 在与Spring Boot集成时,放在与Application.java统计的目录下
 * 通过注解@Configuration让Spring来加载该类的配置
 * 在通过注解@EnableSwagger2来启用Swagger2
 * @author:sunxj
 * @date:2020-12-05 21:44:15
 * @description:Swagger配置类
 */
//@EnableOpenApi
//@Configuration
public class SwaggerConfiguration implements WebMvcConfigurer {
    private final SwaggerProperties swaggerProperties;
    public SwaggerConfiguration(SwaggerProperties swaggerProperties) {
        this.swaggerProperties = swaggerProperties;
    }
    /**
     * 创建API应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制那些借口暴露给Swagger来展现
     * 本例采用指定扫描的包路径来定义指定要建立API的目录
     * @return
     */
    @Bean
    public Docket createRestApi() {
        Set set = new HashSet<>();
        set.add("https");
        set.add("http");
        return new Docket(DocumentationType.OAS_30)
                .pathMapping("/")
                .enable(swaggerProperties.getEnable())//定义是否开启swagger,false为关闭,可以通过变量控制
                .apiInfo(apiInfo())//将api的元信息设置为包含在json ResourceListing响应中。
                .host(swaggerProperties.getTryHost())//接口调试地址
                .select()//选择哪些接口作为swagger的doc发布
                //.apis(RequestHandlerSelectors.basePackage("com.best.user"))//将那些包作为接口文档来显示
                .apis(RequestHandlerSelectors.any())//表示任何包
                .paths(PathSelectors.any())
                .build()
                .protocols(set)// 支持的通讯协议集合
                .securitySchemes(securitySchemes())// 授权信息设置,必要的header token等认证信息
                .securityContexts(securityContexts());// 授权信息全局应用
    }

    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://项目实际地址/swagger-ui.html
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getApplicationName() + "Restful APIs")//网页标题
                .description(swaggerProperties.getApplicationDescription())//网页描述
                .termsOfServiceUrl("http://localhost:8080/")//接口访问地址
                .contact(new Contact("user",null,"******@qq.com"))//名称,url,邮箱
                .version("Application Version: " + swaggerProperties.getApplicationVersion() + ", Spring Boot Version: " + SpringBootVersion.getVersion())//接口版本号
                .build();
    }
    /**
     * 设置授权信息
     */
    private List securitySchemes() {
        ApiKey apiKey = new ApiKey("BASE_TOKEN", "token", io.swagger.v3.oas.models.security.SecurityScheme.In.HEADER.toString());
        return Collections.singletonList(apiKey);
    }

    /**
     * 授权信息全局应用
     */
    private List securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        .securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
                        .build()
        );
    }

    @SafeVarargs
    private final  Set 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 registrations = (List) 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、然后在controller加入对应的信息,@ApiOperation  @ApiParam的使用、 @ApiImplicitParam   @ApiResponses  @ApiResponse的使用、@ApiIgnore的使用、@CrossOrigin @ApiImplicitParams @ApiImplicitParam的使用、@RequestParam @ApiParam的使用如:

package com.best.user.controller;

import com.best.common.entity.JsonResult;
import com.best.common.utils.ResultTool;
import com.best.entity.SysUser;
import com.best.user.service.SysUserService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 对象属性         @ApiModelProperty     用在参数对象的字段上
 * 协议集描述       @Api                  用在Conntroller类上
 * 协议描述         @ApiOperation         用在controller方法上
 * Response集      @ApiResponses         用在controller方法上
 * Response        @ApiResponse          用在@ApiResponses里面
 * 非对象参数集      @ApilmplicitParams    用在controller方法上
 * @author:sunxj
 * @date:2020-11-08 11:08:30
 * @description:用户验证控制器
 */
@RestController
@Api(value = "用户接口") //用在Conntroller类上
public class UserController {
    @Autowired
    private SysUserService sysUserService;


    @ApiOperation(value="getCode",notes="获得城市编号")
    @RequestMapping(value = "/getCode/{code}", method = RequestMethod.GET, produces = "application/json")
    public JsonResult getCode(@ApiParam(value = "城市编号", required = true) @PathVariable int code) {
        return ResultTool.success(code);
    }


    @ApiOperation(value="getUser",notes="获得用户信息")//用在controller方法上
    @ApiImplicitParam(name = "name", value = "用户姓名", required = true, paramType = "query", dataType = "string")//此处需要注意:如果在此处指定了name,name在@RequestMapping中指定了/getUser/{name}就会将name的值填写为{name},因此如果此处使用了@ApiImplicitParam,那么就不能再@RequestMapping使用
    @ApiResponses({
            @ApiResponse(code=400,message="请求参数没填好"),
            @ApiResponse(code=401,message="401"),
            @ApiResponse(code=402,message="402"),
            @ApiResponse(code=403,message="403"),
            @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
    })
    @RequestMapping(value = "/getUser", method = RequestMethod.GET, produces = "application/json")
    public JsonResult getUser(String name) {
        SysUser users = sysUserService.selectByName(name);
        return ResultTool.success(users);
    }


    @ApiIgnore //忽略该接口,就是在接口文档中不显示该接口
    @GetMapping("/getUser1")
    public JsonResult test1() {
        return ResultTool.success("hello word  2222222222222");
    }



    @ApiOperation(value="test",notes="ApiImplicitParam和ApiImplicitParams的使用")//用在controller方法上
    @CrossOrigin //支持跨域请求
    @ApiImplicitParams({
            @ApiImplicitParam(name="mobile",value="手机号",required=true,paramType="query"),
            @ApiImplicitParam(name="password",value="密码",required=true,paramType="query"),
            @ApiImplicitParam(name="age",value="年龄",required=true,paramType="query",dataType="Integer")//注意此处的paramType如果设置为form,那么在接口那里是显示不出参数列表的。
    })
    @RequestMapping(value = "/test", method = RequestMethod.GET, produces = "application/json")
    public JsonResult test( String mobile,  String password,  Integer age) {
        String msg = mobile + "     "+ password+"       "+age;
        return ResultTool.success(msg);
    }

    @ApiOperation(value="test",notes="RequestParam和ApiParam的使用")//用在controller方法上
    @CrossOrigin //支持跨域请求
    @GetMapping("/test1")
    public JsonResult test1(@RequestParam @ApiParam(name = "mobile", value = "手机号", required = true) String mobile, @RequestParam @ApiParam(name = "password", value = "密码", required = true) String password, @RequestParam @ApiParam(name = "age", value = "年龄", required = true)  Integer age) {
        String msg = mobile + "     "+ password+"       "+age;
        return ResultTool.success(msg);
    }
}

5、由于加入了Security,因此需要对swagger对应的路径放行,需要再WebSecurityConfig中加入如下代码:

    @Override
    public void configure(WebSecurity web) throws Exception {
        //所需要用到的静态资源,允许访问
        web.ignoring().antMatchers( "/swagger-ui.html",
                "/swagger-ui/*",
                "/swagger-resources/**",
                "/v2/api-docs",
                "/v3/api-docs",
                "/webjars/**");
    }

6、启动springboot,然后在浏览器中输入:http://localhost:8080/swagger-ui/index.html即可,如下图所示:

 

springboot整合Spring Security+Swagger3_第2张图片

7、打开user-controller就表示UserController对应的接口,如下图所示:

springboot整合Spring Security+Swagger3_第3张图片

8、打开各个接口测试,其中required表示必须加该参数,并且类型为integer,(@ApiOperation  @ApiParam的使用):

springboot整合Spring Security+Swagger3_第4张图片

 @ApiImplicitParam   @ApiResponses  @ApiResponse的使用

springboot整合Spring Security+Swagger3_第5张图片

@CrossOrigin @ApiImplicitParams @ApiImplicitParam的使用

springboot整合Spring Security+Swagger3_第6张图片

@RequestParam @ApiParam的使用

springboot整合Spring Security+Swagger3_第7张图片

 

 

 

你可能感兴趣的:(springboot整合Spring Security+Swagger3)