整合swagger,以及Knife4j优化界面

因为是前后端项目,需要前端的参与,所以一个好看的接口文档非常的重要

1、引入依赖

美化插件其中自带swagger的依赖了

XML 复制代码
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
            <version>4.3.0</version>
        </dependency>

2、添加配置类

java 复制代码
package com.study.question.config;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.OpenAPIService;
import org.springdoc.core.PropertyResolverUtils;
import org.springdoc.core.SecurityService;
import org.springdoc.core.SpringDocConfigProperties;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
import org.springdoc.core.providers.JavadocProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@ConditionalOnClass({OpenAPI.class})
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = false) // 设置为 false 时,禁用
public class SwaggerConfig implements Serializable {

    // ========== 全局 OpenAPI 配置 ==========

    @Bean
    public OpenAPI createApi(SwaggerProperties properties) {
        Map<String, SecurityScheme> securitySchemas = buildSecuritySchemes();
        OpenAPI openAPI = new OpenAPI()
                // 接口信息
                .info(buildInfo(properties))
                // 接口安全配置
                .components(new Components().securitySchemes(securitySchemas));
        securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key)));
        return openAPI;
    }

    /**
     * API 摘要信息
     */
    private Info buildInfo(SwaggerProperties properties) {
        return new Info()
                .termsOfService("有问题请及时联系申智核微服务架构组:HeliosLy")
                .title(properties.getTitle())
                .description(properties.getDescription())
                .version(properties.getVersion())
                .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail()))
                .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl()));
    }

    /**
     * 安全模式,这里配置通过请求头 Authorization 传递 token 参数
     */
    private Map<String, SecurityScheme> buildSecuritySchemes() {
        Map<String, SecurityScheme> securitySchemes = new HashMap<>();
        SecurityScheme securityScheme = new SecurityScheme()
                .type(SecurityScheme.Type.APIKEY) // 类型
                .name(HttpHeaders.AUTHORIZATION) // 请求头的 name
                .in(SecurityScheme.In.HEADER); // token 所在位置
        securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme);
        return securitySchemes;
    }

    /**
     * 自定义 OpenAPI 处理器
     */
    @Bean
    public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI,
                                         SecurityService securityParser,
                                         SpringDocConfigProperties springDocConfigProperties,
                                         PropertyResolverUtils propertyResolverUtils,
                                         Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers,
                                         Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers,
                                         Optional<JavadocProvider> javadocProvider) {

        return new OpenAPIService(openAPI, securityParser, springDocConfigProperties,
                propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
    }


}

属性类

java 复制代码
package com.study.question.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import javax.validation.constraints.NotEmpty;
import java.io.Serializable;

scription:
 */
@Data
@EnableConfigurationProperties
@ConfigurationProperties("study.api-docs")
public class SwaggerProperties implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 是否启用
     */
    @NotEmpty(message = "是否启用,不能为空")
    private boolean enable=false;

    /**
     * 标题
     */
    @NotEmpty(message = "标题不能为空")
    private String title="在线API文档";
    /**
     * 描述
     */
    @NotEmpty(message = "描述不能为空")
    private String description="申智核在线API文档 http://www.shenzhihe.com.cn";
    /**
     * 作者
     */
    @NotEmpty(message = "作者不能为空")
    private String author="HeliosLy";
    /**
     * 版本
     */
    @NotEmpty(message = "版本不能为空")
    private String version="v1.0";
    /**
     * url
     */
    @NotEmpty(message = "扫描的 package 不能为空")
    private String url;
    /**
     * email
     */
    @NotEmpty(message = "扫描的 email 不能为空")
    private String email;

    /**
     * license
     */
    private String license;

    /**
     * license-url
     */
    private String licenseUrl;

}

配置类中添加

XML 复制代码
study:
  api-docs:
    enable: true
    title: 在线API文档
    description: 在线API文档
    version: 1.0
    url: http://www.szh.com
    email: adminly@dingtalk.com
    license: MIT
    license-url: https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE
    author: SYD

3、展示效果

地址访问:http://localhost:8080/doc.html

4、swagger使用

java 复制代码
package com.study.question.model.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
* @author: SYD
* @since: 2024-12-08
* @description:
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_test_1")
@Schema(title="TTest1对象")
public class TTest1 implements Serializable {

    private static final long serialVersionUID=1L;

    @TableField("id")
    private Long id;

    @TableField("name")
    @Schema(description="名称")
    private String name;


}
java 复制代码
package com.study.question.controller;

import com.study.question.model.entity.TTest1;
import com.study.question.model.pojo.R;
import com.study.question.service.QueueService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;

@RequiredArgsConstructor
@Slf4j
@RestController
public class QueueController {

    private final QueueService queueService;
    @GetMapping("/testQueue")
    @Operation(summary = "查询")
    private void test(String name){
        queueService.test(name);
    }

    @GetMapping("/add")
    @Operation(summary = "添加/更新")
    private TTest1 test(TTest1 tTest1){
       return new TTest1();
    }

    @GetMapping("/get/{id}")
    @Operation(summary = "查询详情")
    public TTest1 getById(@NotNull(message = "id不能为null") @Schema(description = "唯一标志") @PathVariable("id") Integer id) {
        return new TTest1();
    }
}

5、bug解决

如果运行报错。Failed to start bean 'documentationPluginsBootstrapper

是因为springboot2.6.x后会有兼容问题,Springboot2.6以后将SpringMVC 默认路径匹配策略从AntPathMatcher 更改为PathPatternParser,导致出错。

所以要么降springboot的版本,要么yml文件加上一个配置。

XML 复制代码
spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER

配置类SwaggerConfig加上

java 复制代码
@Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
        Collection<ExposableWebEndpoint> 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));
    }

6.如果有鉴权请注意排除路径

XML 复制代码
      - /doc*/**
      - /v3*/*/**
      - /swagger-ui*/**
相关推荐
摸鱼仙人~5 分钟前
styled-components:现代React样式解决方案
前端·react.js·前端框架
kangkang-8 分钟前
PC端基于SpringBoot架构控制无人机(三):系统架构设计
java·架构·无人机
sasaraku.38 分钟前
serviceWorker缓存资源
前端
RadiumAg2 小时前
记一道有趣的面试题
前端·javascript
yangzhi_emo2 小时前
ES6笔记2
开发语言·前端·javascript
界面开发小八哥2 小时前
「Java EE开发指南」如何用MyEclipse创建一个WEB项目?(三)
java·ide·java-ee·myeclipse
yanlele2 小时前
我用爬虫抓取了 25 年 5 月掘金热门面试文章
前端·javascript·面试
idolyXyz2 小时前
[java: Cleaner]-一文述之
java
一碗谦谦粉2 小时前
Maven 依赖调解的两大原则
java·maven
netyeaxi3 小时前
Java:使用spring-boot + mybatis如何打印SQL日志?
java·spring·mybatis