springboot 2.7版本整合swagger2代码实现
作者:mmseoamin日期:2023-12-21

1.导入swagger2依赖

        
            io.springfox
            springfox-boot-starter
            3.0.0
        

2.添加swagger配置类

package com.xiyuan.cluster.middle.config;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
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 springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.*;
@EnableWebMvc
@EnableSwagger2
@Configuration
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(Collections.singletonList(apiKey()))
                .securityContexts(Collections.singletonList(securityContext()));
    }
    private static ApiKey apiKey() {
        return new ApiKey("token", "token", "header");
    }
    private SecurityContext securityContext() {
        return SecurityContext.builder()
                .securityReferences(Collections.singletonList(new SecurityReference("token", new AuthorizationScope[0])))
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .description("**项目管理平台")
                .title("**项目管理平台接口api").build();
    }
}

3.启动项目就这么easy 

4.easy个屁,报错了,抛出了异常信息: 

 Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()

   Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException:
    Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()

5.发现这是springboot版本过高然后在 SwaggerConfig配置类里加入以下代码(如果没报错则不需要加下面的代码):

   /**
     * 解决springboot版本过高与swagger2不兼容问题
     *  Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException:
     *  Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()
     *  " because "this.condition" is null
     * @param webEndpointsSupplier
     * @param servletEndpointsSupplier
     * @param controllerEndpointsSupplier
     * @param endpointMediaTypes
     * @param corsProperties
     * @param webEndpointProperties
     * @param environment
     * @return
     */
    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
        List> allEndpoints = new ArrayList();
        Collection webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    }
    private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
        return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
    }

并且在yml文件里添加:

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

这样便可以解决上面异常。

6.然后在controller层或者参数接受的实体类层添加注解,使得swagger界面中能显示出每个接口的用途及参数描述信息。

package com.xiyuan.cluster.middle.controller;
import com.xiyuan.cluster.middle.common.Result;
import com.xiyuan.cluster.middle.entity.SysUserRegister;
import com.xiyuan.cluster.middle.service.ISysUserRegisterService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * 

* 人员注册表 前端控制器 *

* * @author jerry * @since 2023-06-27 */ @RestController @RequestMapping("/dms/register") @Api(tags = "用户信息注册") public class SysUserRegisterController { @Autowired private ISysUserRegisterService registerService; /** * 信息注册接口 * * @param register * @return */ @PostMapping("/register") @ApiOperation("信息注册接口") public Result register(@RequestBody SysUserRegister register) throws Exception { registerService.register(register); return Result.success(); } /** * 获取审批列表接口 * * @param areaId * @return */ @GetMapping("/queryCheckList") @ApiOperation("获取审批列表接口") @ApiImplicitParams({ @ApiImplicitParam(name = "areaId", value = "区域ID", dataType = "String", required = true), }) public Result> queryCheckList(@RequestParam String areaId) throws Exception{ return Result.success(registerService.queryCheckList(areaId)); } /** * 用户信息审核接口 * * @param registers * @return */ @PostMapping("/check") @ApiOperation("用户信息审核接口") public Result check(@RequestBody SysUserRegister registers) throws Exception { registerService.check(registers); return Result.success(); } }
package com.xiyuan.cluster.middle.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * 

* 人员注册表 *

* * @author jerry * @since 2023-06-27 */ @Data @TableName("sys_user_register") @ApiModel(value = "用户注册实体类",description = "用于传输用户注册信息") public class SysUserRegister implements Serializable { private static final long serialVersionUID = 1L; /** * 姓名 */ @ApiModelProperty(value = "用户姓名",required = true) private String name; /** * 身份证 */ @ApiModelProperty(value = "身份证",required = true) private String sfz; /** * 电话号码 */ @ApiModelProperty(value = "电话号码",required = true) private String phone; /** * 角色 */ @ApiModelProperty(value = "用户角色",required = true) private String role; }

 7.最后浏览器输入http://127.0.0.1:8080/swagger-ui/index.html 浏览器上出现swagger可视化界面

可是页面是显示又出现了问题

Unable to render this definition

The provided definition does not specify a valid version field.

Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).

 8.排查了好长时间一直以为是版本冲突造成的,网上也查了好多相关的博客都没能解决,最后误打误撞把项目里的拦截器类注释了发现这个页面能正常显示了,估计是拦截里面把swagger相关的页面给拦截了,最后swagger页面能正常显示了:

9.然后狗日的甲方说提供的swagger页面不够美观,又被迫换了一个好看点的UI页面。

knife4介绍:

        knife4j 是基于 Swagger 构建的一个增强版工具,它在 Swagger 的基础上进行了扩展和优化。Swagger 是一个用于设计、构建和文档化 RESTful API 的开源框架,而 knife4j 则是在 Swagger 的基础上提供了更多的功能和便利性。它为开发人员提供了更友好的界面、更丰富的功能和更灵活的配置选项,使得 API 文档的管理和使用更加便捷。因此,可以说 knife4j 是 Swagger 的一种增强和扩展。

10.pom文件加入 knife4j 依赖包:

        
            com.github.xiaoymin
            knife4j-spring-boot-starter
            2.0.9
        

11.加入配置类

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("/static/**").addResourceLocations("classpath:/static/","classpath:/public/");
        // swagger访问配置
        registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/META-INF/resources/webjars/");
    }
}

然后浏览器输入地址:http://127.0.0.1:8080/doc.html 页面就换成了最新的:

最后如果在访问swagger页面的时候服务器抛出下面的异常:

java.lang.NumberFormatException: For input string: ""

则引入下面的两个依赖便能解决:

        
            io.swagger
            swagger-annotations
            1.5.21
        
        
            io.swagger
            swagger-models
            1.5.21