首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将XSD导入OpenAPI

将XSD导入OpenAPI
EN

Stack Overflow用户
提问于 2019-05-07 16:18:55
回答 2查看 5.9K关注 0票数 9

我在XSD文件中有一些模型定义,需要从OpenApi定义引用这些模型。手动重塑是不可行的,因为文件太大了,我需要把它放到一个构建系统中,这样如果XSD发生了变化,我就可以为OpenApi重新生成模型/模式。

我尝试过并且几乎成功的方法是使用xsd2json,然后使用节点模块json-schema-to-openapi对其进行转换。然而,xsd2json正在放弃一些complexElement型号。例如,在一个模型中使用"$ref": "#/definitions/tns:ContentNode"作为子类型,但是在模式中没有ContentNode的定义,而当我查看XSD时,有一个用于ContentNodecomplexElement定义。

我还没有尝试过的另一种方法是使用xjb从XSD生成Java模型,然后使用JacksonSchema生成json模式。

在OpenApi中使用XSD有没有现成的库或方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-07 20:51:56

我最终实现了第二种方法,使用jaxb将XSD转换为java模型,然后使用Jackson将模式写入文件。

Gradle:

代码语言:javascript
复制
plugins {
    id 'java'
    id 'application'
}

group 'foo'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-jsonSchema', version: '2.9.8'
}

configurations {
    jaxb
}

dependencies {
    jaxb (
            'com.sun.xml.bind:jaxb-xjc:2.2.7',
            'com.sun.xml.bind:jaxb-impl:2.2.7'
    )
}

application {
    mainClassName = 'foo.bar.Main'
}

task runConverter(type: JavaExec, group: 'application') {
    classpath = sourceSets.main.runtimeClasspath

    main = 'foo.bar.Main'
}

task jaxb {
    System.setProperty('javax.xml.accessExternalSchema', 'all')
    def jaxbTargetDir = file("src/main/java")

    doLast {
        jaxbTargetDir.mkdirs()

        ant.taskdef(
                name: 'xjc',
                classname: 'com.sun.tools.xjc.XJCTask',
                classpath: configurations.jaxb.asPath
        )
        ant.jaxbTargetDir = jaxbTargetDir

        ant.xjc(
                destdir: '${jaxbTargetDir}',
                package: 'foo.bar.model',
                schema: 'src/main/resources/crs.xsd'
        )
    }
}

compileJava.dependsOn jaxb

对于转换程序主类,它的作用大致如下:

代码语言:javascript
复制
package foo.bar;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
import foo.bar.model.Documents;

public class Main {

    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();
        JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
        try {
            JsonSchema schema = schemaGen.generateSchema(Documents.class);
            System.out.print(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

}

然而,它仍然不是完美的。这将需要迭代所有的模型类,并使用模式生成一个文件。此外,它不使用引用,如果一个类有另一个类的成员,模式将以内联方式打印,而不是引用。这需要对SchemaFactoryWrapper进行更多的定制,但是可以做到。

票数 4
EN

Stack Overflow用户

发布于 2019-05-07 17:03:45

您遇到的问题是,您正在对多步转换应用推理工具。正如您已经发现的,推理工具本质上是繁琐的,并不是在所有情况下都能工作。这有点像玩Chinese whispers --链中的每一步都有潜在的损失,所以你从另一端得到的可能是乱码。

基于您建议的替代方法,我将建议一个类似的解决方案:

很明显,OpenAPI是一个应用编程接口定义标准。您应该可以采用代码优先的方法,在代码中组合API操作并公开从XJB生成的类型。然后,您可以使用Apiee及其注释来生成OpenAPI定义。这假设您的应用编程接口使用的是JAX-RS

这仍然是一个两步走的过程,但成功的机会更高。这里的好处是您的第一步,将您的XSD类型推断为java类型,希望对定义您的API操作的代码影响很小(如果有的话)。尽管仍然会有一个手动的步骤(更新模型),但是一旦代码被重新构建,OpenAPI定义就会自动更新。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56018335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档