SpringFox 3.0.0内部使用swagger v2,但在localhost上swaggerUI openAPI v3文件可以下载

vptzau2j  于 2023-10-18  发布在  Spring
关注(0)|答案(1)|浏览(151)

我来解释这个问题。
我写了下面的代码来在我的SpringBoot项目中生成静态文件:

package com.kovospace.paster.base.swagger;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.models.Swagger;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.OpenAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.stream.Stream;

import io.swagger.v3.core.util.Yaml;

import static com.kovospace.paster.base.utils.Utils.exceptionHandler;

@Component
public class DocumentGenerator implements CommandLineRunner {

    @Value("${app.swagger.generated.files.path}")
    private String storagePath;

    private DocumentationCache documentationCache;
    private ServiceModelToSwagger2Mapper mapper;
    private ObjectMapper objectMapper;

    @Autowired
    public DocumentGenerator(
            final DocumentationCache documentationCache,
            final ServiceModelToSwagger2Mapper mapper,
            final ObjectMapper objectMapper
    ) {
        this.documentationCache = documentationCache;
        this.mapper = mapper;
        this.objectMapper = objectMapper;
    }

    @Override
    public void run(String... args) throws IOException {
    Optional.ofNullable(documentationCache.all())
                .map(docMap -> docMap.entrySet())
                .map(docEntries -> docEntries.stream())
                .orElseGet(Stream::empty)
                .forEach(docEntry -> generateAllexpectedDocumentTypes(docEntry));
    }

    private void generateAllexpectedDocumentTypes(final Map.Entry<String, Documentation> documentation) {
        Arrays.stream(ExpectedDocumentType.values())
                .forEach(documentType -> {
                    final String outputFilePath = getOutputFilePath(documentation, documentType.extension());
                    final String fileContent = converter.apply(documentation, documentType);
                    writeFile(fileContent, outputFilePath);
                });
    }

    private String getOutputFilePath(final Map.Entry<String, Documentation> documentation, final String extension) {
        return StringUtils.isEmpty(storagePath)
                ? String.format("%s.%s", documentation.getKey(), extension)
                : String.format("%s/%s.%s", storagePath, documentation.getKey(), extension);
    }

    private void writeFile(final String document, final String filePath) {
        final File outputFile = new File(filePath);
        if (!outputFile.exists()) {
            outputFile.getParentFile().mkdirs();
            try {
                outputFile.createNewFile();
            } catch (IOException e) {
                //TODO
                throw new RuntimeException(e);
            }
        }
        try (FileWriter fileWriter = new FileWriter(outputFile)) {
            fileWriter.write(document);
        } catch (Exception e) {
            //TODO
        }
    }

    private BiFunction<Map.Entry<String, Documentation>, ExpectedDocumentType, String> converter =
            (documentationEntry, expectedDocumentType) -> {
                final Swagger swagger = mapper.mapDocumentation(
                        documentationCache.documentationByGroup(documentationEntry.getKey()));
                switch (expectedDocumentType) {
                    case JSON:
                        return exceptionHandler(() -> Json.pretty(swagger));
                    case YAML:
                    default:
                        return exceptionHandler(() -> Yaml.pretty().writeValueAsString(swagger));
                }
            };
}

它正在生成swagger v2格式的文件:

swagger: "2.0"
info:
  description: Api Documentation
  version: "1.0"
  title: Api Documentation
  termsOfService: urn:tos
  contact:
    name: ""
    url: ""
    email: ""
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0
host: ""
basePath: /
tags:
- name: info-controller
  description: Info Controller
- name: item-controller
  description: Item Controller
- name: user-controller
  description: User Controller
schemes: []
consumes: []
produces:
- application/json
paths:
  /api/info/checkPlatform:
    post:
      tags:
      - info-controller
      summary: Check Platform
      description: Given platform is listed and supported

尽管我为openAPI v3设置了它:

package com.kovospace.paster.base.configurations;

import com.kovospace.paster.base.annotations.swagger.PublicEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.HashSet;

@Configuration
public class SwaggerConfig {

    //TODO do konstant alebo properties
    private static final String BASE_PACKAGE = "com.kovospace.paster";
    private static final String PUBLIC_API_GROUPNAME = "public-api";
    private static final String PRIVATE_API_GROUPNAME = "devel-api";
    private static final HashSet<String> RETURN_TYPES_POSSIBLE = new HashSet<String>() {{
        add(MediaType.APPLICATION_JSON_VALUE);
    }};

    @Bean
    public Docket publicApi() {
        return new Docket(DocumentationType.OAS_30)
                .groupName(PUBLIC_API_GROUPNAME)
                .produces(RETURN_TYPES_POSSIBLE)
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(PublicEndpoint.class))
                .paths(PathSelectors.any())
                .build();
    }

    @Bean
    public Docket developerApi() {
        return new Docket(DocumentationType.OAS_30)
                .groupName(PRIVATE_API_GROUPNAME)
                .produces(RETURN_TYPES_POSSIBLE)
                .select()
                .apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE))
                .paths(PathSelectors.any())
                .build();
    }

}

但你猜怎么着当我在localhost上的浏览器中打开swaggerUI时,我可以下载声称是V3的文件:

{
openapi: "3.0.3",
info: {
title: "Api Documentation",
description: "Api Documentation",
termsOfService: "urn:tos",
contact: { },
license: {
name: "Apache 2.0",
url: "http://www.apache.org/licenses/LICENSE-2.0"
},
version: "1.0"
},
servers: [
{
url: "https://0.0.0.0:4004",
description: "Inferred Url"
}
],
tags: [
{
name: "info-controller",
description: "Info Controller"
},
{
name: "item-controller",
description: "Item Controller"
},
{
name: "user-controller",
description: "User Controller"
}
],
paths: {
/api/info/checkPlatform: {
post: {
tags: [
"info-controller"
],
summary: "Check Platform",
description: "Given platform is listed and supported",

真相在哪里?为什么我的项目文件夹中不能生成漂亮的v3文件,或者我在swaggerUI前端上有假的v3.0文件?我已经在控制器端点上使用v3.0注解,会有什么问题?

g6baxovj

g6baxovj1#

抱歉打扰,但答案是:我瞎了:
private ServiceModelToSwagger2Mapper mapper;更改为private ServiceModelToOpenApiMapper mapper;
需要1MD

相关问题