jaxb xsd生成xml_使用JAXB和Jackson从XSD生成JSON模式

jaxb xsd生成xml

在本文中,我演示了一种从XML Schema (XSD)生成JSON Schema的 方法 。 在概述从XML Schema创建JSON Schema的方法的同时,本文还演示了JAXB实现的使用(与JDK 9捆绑在一起的xjc版本2.2.12-b150331.1824 [build 1.9.0-ea-b68])和JSON / Java绑定实现的说明( 杰克逊 2.5.4)。

从XSD生成JSON模式的这种方法的步骤可以概括为:

  1. 应用JAXB的xjc编译器从XML Schema(XSD)生成Java类。
  2. 应用Jackson来从JAXB生成的Java类生成JSON模式。

使用JAXB的xjc从XSD生成Java类

为了便于讨论,我将使用我先前的博客文章A JAXB Nuance:字符串与枚举受限XSD字符串中的枚举使用的简单Food.xsd 。 为了方便起见,我在此处重现了该简单模式,但没有特定于先前博客文章的XML注释:

Food.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:dustin="http://marxsoftware.blogspot.com/foodxml"targetNamespace="http://marxsoftware.blogspot.com/foodxml"elementFormDefault="qualified"attributeFormDefault="unqualified"><xs:element name="Food"><xs:complexType><xs:sequence><xs:element name="Vegetable" type="dustin:Vegetable" /><xs:element ref="dustin:Fruit" /><xs:element name="Dessert" type="dustin:Dessert" /></xs:sequence></xs:complexType></xs:element><xs:simpleType name="Vegetable"><xs:restriction base="xs:string"><xs:enumeration value="Carrot"/><xs:enumeration value="Squash"/><xs:enumeration value="Spinach"/><xs:enumeration value="Celery"/></xs:restriction></xs:simpleType><xs:element name="Fruit"><xs:simpleType><xs:restriction base="xs:string"><xs:enumeration value="Watermelon"/><xs:enumeration value="Apple"/><xs:enumeration value="Orange"/><xs:enumeration value="Grape"/></xs:restriction></xs:simpleType></xs:element><xs:simpleType name="Dessert"><xs:restriction base="xs:string"><xs:enumeration value="Pie"/><xs:enumeration value="Cake"/><xs:enumeration value="Ice Cream"/></xs:restriction></xs:simpleType></xs:schema>

使用由JDK提供的JAXB实现提供的xjc命令行工具来生成与此XSD相对应的Java类很容易。 下一个屏幕快照使用以下命令显示了此过程:

xjc -d jaxb。\ Food.xsd

生成JavaObjectsFromFoodXsdWithXjc

这个简单的命令生成与提供的Food.xsd相对应的Java类,并将这些类放置在指定的“ jaxb”子目录中。

用Jackson从JAXB生成的类生成JSON

使用现在可用的JAXB生成的类,可以将Jackson应用于这些类以从Java类生成JSON。 Jackson的主门户网站页面上将其描述为“一个用于处理的多功能Java库”,“其灵感来自可用于Java平台的XML工具的质量和种类。” Jackson的存在以及类似的框架和库似乎是Oracle从Java SE 9中 删除 JEP 198 (“轻型JSON API”)的原因之一。 [值得注意的是, Java EE 7已经通过其JSR 353 (“与JSON处理有关的Java API”)的实现实现了内置的JSON支持 ,而该JSR 353与JEP 198无关。)

将Jackson应用于从我们的JAXB生成的Java类生成JSON的第一步之一就是获取并配置Jackson的ObjectMapper类的实例。 下一个代码清单显示了实现此目的的一种方法。

获取和配置用于JAXB序列化/反序列化的Jackson ObjectMapper

/*** Create instance of ObjectMapper with JAXB introspector* and default type factory.** @return Instance of ObjectMapper with JAXB introspector*    and default type factory.*/
private ObjectMapper createJaxbObjectMapper()
{final ObjectMapper mapper = new ObjectMapper();final TypeFactory typeFactory = TypeFactory.defaultInstance();final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(typeFactory);// make deserializer use JAXB annotations (only)mapper.getDeserializationConfig().with(introspector);// make serializer use JAXB annotations (only)mapper.getSerializationConfig().with(introspector);return mapper;
}

上面的代码清单演示了如何获取Jackson的ObjectMapper实例并将其配置为使用默认类型的工厂和面向JAXB的注释自检器。

实例化并适当配置了Jackson的ObjectMapper ,就很容易使用该ObjectMapper实例从生成的JAXB类生成JSON。 下一个代码清单中演示了使用不推荐使用的Jackson类JsonSchema实现此目的的一种方法。

使用不推荐使用的com.fasterxml.jackson.databind.jsonschema.JsonSchema类从Java类生成JSON

/*** Write JSON Schema to standard output based upon Java source* code in class whose fully qualified package and class name* have been provided.** @param mapper Instance of ObjectMapper from which to*     invoke JSON schema generation.* @param fullyQualifiedClassName Name of Java class upon*    which JSON Schema will be extracted.*/
private void writeToStandardOutputWithDeprecatedJsonSchema(final ObjectMapper mapper, final String fullyQualifiedClassName)
{try{final JsonSchema jsonSchema = mapper.generateJsonSchema(Class.forName(fullyQualifiedClassName));out.println(jsonSchema);}catch (ClassNotFoundException cnfEx){err.println("Unable to find class " + fullyQualifiedClassName);}catch (JsonMappingException jsonEx){err.println("Unable to map JSON: " + jsonEx);}
}

上面清单中的代码实例化获取提供的Java类的类定义(在我的示例中由JAXB xjc编译器生成的最高级别的Food类),并将对该JAXB生成的类的引用传递给ObjectMapper的generateJsonSchema(Class < ?>)方法。 不推荐使用的JsonSchema类的toString()实现非常有用,并且可以轻松写出从JAXB生成的类生成的JSON。

为了进行演示,我将演示驱动程序作为main(String [])函数提供。 在下一个代码清单中提供了该函数和到目前为止的整个类(包括上面显示的方法)。

JsonGenerationFromJaxbClasses.java,版本1

package dustin.examples.jackson;import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;import com.fasterxml.jackson.databind.jsonschema.JsonSchema;import static java.lang.System.out;
import static java.lang.System.err;/*** Generates JavaScript Object Notation (JSON) from Java classes* with Java API for XML Binding (JAXB) annotations.*/
public class JsonGenerationFromJaxbClasses
{/*** Create instance of ObjectMapper with JAXB introspector* and default type factory.** @return Instance of ObjectMapper with JAXB introspector*    and default type factory.*/private ObjectMapper createJaxbObjectMapper(){final ObjectMapper mapper = new ObjectMapper();final TypeFactory typeFactory = TypeFactory.defaultInstance();final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(typeFactory);// make deserializer use JAXB annotations (only)mapper.getDeserializationConfig().with(introspector);// make serializer use JAXB annotations (only)mapper.getSerializationConfig().with(introspector);return mapper;}/*** Write out JSON Schema based upon Java source code in* class whose fully qualified package and class name have* been provided.** @param mapper Instance of ObjectMapper from which to*     invoke JSON schema generation.* @param fullyQualifiedClassName Name of Java class upon*    which JSON Schema will be extracted.*/private void writeToStandardOutputWithDeprecatedJsonSchema(final ObjectMapper mapper, final String fullyQualifiedClassName){try{final JsonSchema jsonSchema = mapper.generateJsonSchema(Class.forName(fullyQualifiedClassName));out.println(jsonSchema);}catch (ClassNotFoundException cnfEx){err.println("Unable to find class " + fullyQualifiedClassName);}catch (JsonMappingException jsonEx){err.println("Unable to map JSON: " + jsonEx);}}/*** Accepts the fully qualified (full package) name of a* Java class with JAXB annotations that will be used to* generate a JSON schema.** @param arguments One argument expected: fully qualified*     package and class name of Java class with JAXB*     annotations.*/public static void main(final String[] arguments){if (arguments.length < 1){err.println("Need to provide the fully qualified name of the highest-level Java class with JAXB annotations.");System.exit(-1);}final JsonGenerationFromJaxbClasses instance = new JsonGenerationFromJaxbClasses();final String fullyQualifiedClassName = arguments[0];final ObjectMapper objectMapper = instance.createJaxbObjectMapper();instance.writeToStandardOutputWithDeprecatedJsonSchema(objectMapper, fullyQualifiedClassName);}
}

要针对基于Food.xsd的JAXB xjc生成的Java类运行此相对通用的代码,我需要提供最高级别生成的类的标准包名称和类名称。 在这种情况下,这就是com.blogspot.marxsoftware.foodxml.Food (程序包名称基于XSD的名称空间,因为我在运行xjc时未明确覆盖该名称空间)。 当我使用完全限定的类名以及类路径上的JAXB类和Jackson库运行上述代码时,我看到以下JSON写入标准输出。

生成的JSON

{"type":"object","properties":{"vegetable":{"type":"string","enum":["CARROT","SQUASH","SPINACH","CELERY"]},"fruit":{"type":"string"},"dessert":{"type":"string","enum":["PIE","CAKE","ICE_CREAM"]}}}

人类(包括许多开发人员)比打印的JSON更喜欢漂亮的打印 。 我们可以调整演示类的方法writeToStandardOutputWithDeprecatedJsonSchema(ObjectMapper, String) ,如下所示,以写出缩进的JSON ,以更好地反映其层次结构性质。 接下来显示此修改的方法。

修改了writeToStandardOutputWithDeprecatedJsonSchema(ObjectMapper,String)以写入缩进的JSON

/*** Write out indented JSON Schema based upon Java source* code in class whose fully qualified package and class* name have been provided.** @param mapper Instance of ObjectMapper from which to*     invoke JSON schema generation.* @param fullyQualifiedClassName Name of Java class upon*    which JSON Schema will be extracted.*/
private void writeToStandardOutputWithDeprecatedJsonSchema(final ObjectMapper mapper, final String fullyQualifiedClassName)
{try{final JsonSchema jsonSchema = mapper.generateJsonSchema(Class.forName(fullyQualifiedClassName));out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));}catch (ClassNotFoundException cnfEx){err.println("Unable to find class " + fullyQualifiedClassName);}catch (JsonMappingException jsonEx){err.println("Unable to map JSON: " + jsonEx);}catch (JsonProcessingException jsonEx){err.println("Unable to process JSON: " + jsonEx);}
}

当我使用此修改后的方法再次运行演示类时,JSON输出在美学上更加令人愉悦:

生成带有缩进通信层次结构的JSON

{"type" : "object","properties" : {"vegetable" : {"type" : "string","enum" : [ "CARROT", "SQUASH", "SPINACH", "CELERY" ]},"fruit" : {"type" : "string"},"dessert" : {"type" : "string","enum" : [ "PIE", "CAKE", "ICE_CREAM" ]}}
}

我在这篇文章中一直在使用Jackson 2.5.4。 com.fasterxml.jackson. databind .jsonschema.JsonSchemacom.fasterxml.jackson. databind .jsonschema.JsonSchema 该版本不推荐使用com.fasterxml.jackson. databind .jsonschema.JsonSchema ,并带有以下注释:“从2.2开始,我们建议使用外部JSON Schema生成器模块 。” 鉴于此,我现在看一下使用新的首选方法( Jackson JSON Schema Module方法)。

最显著的变化是使用JsonSchema在类com.fasterxml.jackson.module.jsonSchema包,而不是使用JsonSchema在类com.fasterxml.jackson.databind.jsonschema包。 获取这些不同版本的JsonSchema类的实例的方法也不同。 下一个代码清单演示了如何使用更新的首选方法从Java类生成JSON。

使用Jackson的更新和首选com.fasterxml.jackson.module.jsonSchema.JsonSchema

/*** Write out JSON Schema based upon Java source code in* class whose fully qualified package and class name have* been provided. This method uses the newer module JsonSchema* class that replaces the deprecated databind JsonSchema.** @param fullyQualifiedClassName Name of Java class upon*    which JSON Schema will be extracted.*/
private void writeToStandardOutputWithModuleJsonSchema(final String fullyQualifiedClassName)
{final SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();final ObjectMapper mapper = new ObjectMapper();try{mapper.acceptJsonFormatVisitor(mapper.constructType(Class.forName(fullyQualifiedClassName)), visitor);final com.fasterxml.jackson.module.jsonSchema.JsonSchema jsonSchema = visitor.finalSchema();out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));}catch (ClassNotFoundException cnfEx){err.println("Unable to find class " + fullyQualifiedClassName);}catch (JsonMappingException jsonEx){err.println("Unable to map JSON: " + jsonEx);}catch (JsonProcessingException jsonEx){err.println("Unable to process JSON: " + jsonEx);}
}

下表将两个Jackson JsonSchema类的用法与左侧较早显示的已弃用方法(为进行比较而进行了一些调整)并在右侧推荐了较新的方法进行了比较。 两者针对要从其编写JSON的相同给定Java类生成相同的输出。

/*** Write out JSON Schema based upon Java source code in* class whose fully qualified package and class name have* been provided. This method uses the deprecated JsonSchema* class in the "databind.jsonschema" package* {@see com.fasterxml.jackson.databind.jsonschema}.** @param fullyQualifiedClassName Name of Java class upon*    which JSON Schema will be extracted.*/
private void writeToStandardOutputWithDeprecatedDatabindJsonSchema(final String fullyQualifiedClassName)
{final ObjectMapper mapper = new ObjectMapper();try{final com.fasterxml.jackson.databind.jsonschema.JsonSchema jsonSchema =mapper.generateJsonSchema(Class.forName(fullyQualifiedClassName));out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));}catch (ClassNotFoundException cnfEx){err.println("Unable to find class " + fullyQualifiedClassName);}catch (JsonMappingException jsonEx){err.println("Unable to map JSON: " + jsonEx);}catch (JsonProcessingException jsonEx){err.println("Unable to process JSON: " + jsonEx);}
}
/*** Write out JSON Schema based upon Java source code in* class whose fully qualified package and class name have* been provided. This method uses the newer module JsonSchema* class that replaces the deprecated databind JsonSchema.** @param fullyQualifiedClassName Name of Java class upon*    which JSON Schema will be extracted.*/
private void writeToStandardOutputWithModuleJsonSchema(final String fullyQualifiedClassName)
{final SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();final ObjectMapper mapper = new ObjectMapper();try{mapper.acceptJsonFormatVisitor(mapper.constructType(Class.forName(fullyQualifiedClassName)), visitor);final com.fasterxml.jackson.module.jsonSchema.JsonSchema jsonSchema = visitor.finalSchema();out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));}catch (ClassNotFoundException cnfEx){err.println("Unable to find class " + fullyQualifiedClassName);}catch (JsonMappingException jsonEx){err.println("Unable to map JSON: " + jsonEx);}catch (JsonProcessingException jsonEx){err.println("Unable to process JSON: " + jsonEx);}
}

这篇博客文章展示了两种方法,这些方法使用由Jackson提供的名称为JsonSchema的类的不同版本来基于从具有JAXB的xjc的XSD生成的Java类编写JSON。 本文中演示的整个过程是一种从XML Schema生成JSON Schema的方法。

翻译自: https://www.javacodegeeks.com/2015/06/generating-json-schema-from-xsd-with-jaxb-and-jackson.html

jaxb xsd生成xml

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中结构体struct的用法

点击蓝字关注我们定义结构体变量下面举一个例子来说明怎样定义结构体变量。struct string { char name[8]; int age; char sex[2]; char depart[20]; float wage1, wage2, wage3, wage4, wage5; }person;这个例子定义了一个结构名为string的结构体变量person。还可以省略变量名…

html全屏漂浮,jquery全屏漂浮广告插件,可点击关闭(原创)

jquery全屏漂浮广告插件 兼容主流浏览器 实现简单 调用简单 在线预览 源码下载jquery全屏漂浮广告插件 兼容主流浏览器 实现非常简单说明&#xff1a;jquery在1.9开始不支持.live()方法的写法而改用.on()&#xff0c;见http://jquery.com/upgrade-guide/1.9/#live-removed.该插…

C++ 面试考点(二)

点击蓝字关注我们11、extern 用法&#xff1f;extern 修饰变量的声明如果文件a.c 需要引用b.c 中变量int v&#xff0c;就可以在a.c 中声明extern int v&#xff0c;然后就可以引用变量v。extern 修饰函数的声明如果文件a.c 需要引用b.c 中的函数&#xff0c;比如在b.c 中原型是…

内存不能为read进不去桌面_四级报名进不去怎么办

英语四级报名进不去怎么办?这里提供有两种方法&#xff0c;一种是重复刷新&#xff0c;直到页面出现;另外一种就是错峰报名&#xff0c;叉开登录高峰期。很多考生在报名的时候遇到困难&#xff0c;最多的就是报名页面进不去&#xff0c;这个时候有一些考生就会产生疑惑&#x…

C语言线程库的使用,这篇值得收藏!

点击蓝字关注我们1. 线程概述线程是轻量级的进程&#xff08;LWP&#xff1a;light weight process&#xff09;&#xff0c;在 Linux 环境下线程的本质仍是进程。在计算机上运行的程序是一组指令及指令参数的组合&#xff0c;指令按照既定的逻辑控制计算机运行。操作系统会以进…

alexeyab darknet 编译_【目标检测实战】Darknet—yolov3模型训练(VOC数据集)

原文发表在&#xff1a;语雀文档0.前言本文为Darknet框架下&#xff0c;利用官方VOC数据集的yolov3模型训练&#xff0c;训练环境为&#xff1a;Ubuntu18.04下的GPU训练&#xff0c;cuda版本10.0&#xff1b;cudnn版本7.6.5。经过一晚上的训练&#xff0c;模型20个类别的mAP达到…

html字符串转svg,【SVG】如何操作SVG Text

上周我们学习了如何使用元素创建SVG文本。在实例中我们设置了x和y坐标来定位文本&#xff0c;也尝试了给SVG文本中的每个字符定位。关于元素还有很多内容。在处理SVG文本时&#xff0c;不要局限于x和y属性。元素还有几个可以添加的属性&#xff0c;现在我们开始讨论吧。dx和dy属…

C++ 面试考点(三)

点击蓝字关注我们21、构造函数和析构函数可以调用虚函数吗&#xff0c;为什么在C中&#xff0c;提倡不在构造函数和析构函数中调用虚函数&#xff1b;在构造函数和析构函数调用的所有函数(包括虚函数)都是编译时确定的, 虚函数将运行该类中的版本.因为父类对象会在子类之前进行…

用终端访问路由器设置端口开发_serial for mac(终端管理软件)v2.0.3

原标题&#xff1a;serial for mac(终端管理软件)v2.0.3serial for mac是应用在Mac上的一款终端管理软件&#xff0c;可以帮助您连接和控制串行设备&#xff0c;如服务器&#xff0c;路由器或调制解调器等网络设备&#xff0c;PBX系统等。好消息是Serial为大多数串行设备提供了…

大神级的C++性能优化,你能看懂吗?

点击蓝字关注我们一、前言性能优化不管是从方法论还是从实践上都有很多东西&#xff0c;文章会从C语言本身入手&#xff0c;介绍一些性能优化的方法&#xff0c;希望能做到简洁实用。二、实例1在开始本文的内容之前&#xff0c;让我们看段小程序&#xff1a;// 获取一个整数对应…

钢笔墨水能否代替打印机墨水_LAMY钢笔应该如何选择墨水?

其实墨水世面上基本是有两种&#xff1a;碳素墨水和非碳素。碳素墨水相对比较堵笔&#xff0c;碳素墨水对钢笔本身腐蚀性不大&#xff0c;腐蚀性大的那是染料/颜料墨水。碳素墨水写字非常容易有笔锋&#xff0c;而非碳素墨水就显得略微柔和了。有人说&#xff0c;字写得好的人用…

html ctf查找,Web CTF 解题思路总结—南京邮电大学攻防平台writeup

1、直接查看源代码例&#xff1a;签到题(50)2、PHP的特性(1)MD5 碰撞例&#xff1a;md5 collision(50)md5碰撞&#xff1a;MD5摘要算法可以从多个字节组成的串中计算出由32个字节构成的“特征串”&#xff0c;对于超过32字节的串来说&#xff0c;MD5计算得出的值必然是其一个子…

java 1.8新增功能_睡觉时:新增的Java 8新增功能

java 1.8新增功能自Java 8推出以来&#xff0c;最有趣的功能是什么&#xff1f; Java 8最近庆祝了它的第一个生日&#xff0c;其主要版本已经在一年多以前了。 这当然值得庆祝。 自从最初的Java 8版本问世以来&#xff0c;已经发布了六个更新。 这些更新中的某些元素是次要的…

C++ 为什么不加入垃圾回收机制

点击蓝字关注我们Java的爱好者们经常批评C中没有提供与Java类似的垃圾回收(Gabage Collector)机制(这很正常&#xff0c;正如C的爱好者有时也攻击Java没有这个没有那个&#xff0c;或者这个不行那个不够好)&#xff0c;导致C中对动态存储的官吏称为程序员的噩梦&#xff0c;不是…

c++ 共享内存_Python3.8多进程之共享内存

最近发了个宏愿想写一个做企业金融研究的Python框架。拖出Python一看已经更新到了3.8&#xff0c;于是就发现了Python 3.8里新出现的模块&#xff1a;multiprocessing.shared_memory。随手写了个测试。生成一个240MB大小的pandas.DataFrame&#xff0c;然后转换成numpy.recarra…

计算机主机箱外部介绍图,电脑的主机结构是怎样的 电脑主机结构图【图文】...

在电脑已经普及的今天&#xff0c;基本上每家每户都有电脑了&#xff0c;大家用它来看电影&#xff0c;搜索资料啊&#xff0c;上网啊等等。在我们日常的娱乐方式中&#xff0c;电脑也是我们的娱乐项目之一&#xff0c;至少还是好多人用它看电影和追剧的。但是机器会有故障的时…

C 语言各数据类型的内存映像

点击蓝字关注我们C语言各种数据类型的内存映像&#xff08;32位平台&#xff09;&#xff1a;0 signed char#include <stdio.h> int main() {char min 1<<7;char max (1<<7)-1;for(int imin;i<max;i)if(i<0)printf("%.2X ",(unsigned char…

用java编写一个图书管理系统_手把手教你编写第一个java程序

安装完jdk后我们就可以试着编写第一个java程序了&#xff0c;让我们一起来试试吧&#xff01;第一步点击开始——所有程序——附件——记事本&#xff0c;新建记事本&#xff0c;输入以下代码&#xff1a;class HelloWorld { public static void main(String args[]) { System.…

go micro java_Java Micro Framework:您无法忽略的新趋势

go micro java什么是Java微框架&#xff0c;为什么要使用它们&#xff1f; 每种语言都有权衡。 对于Java&#xff0c;要成为一种安全&#xff0c;经过严格测试&#xff0c;向后兼容的语言&#xff0c;就要在敏捷性和简化方面做出一些牺牲。 无可否认&#xff0c;有些冗长和冗长…

C语言调用C++类成员函数讲解和实例

点击蓝字关注我们1、问题成因C语言与C调用问题原因主要在于C编译器和C编译器的不同。C是过程式语言&#xff0c;C编译器编译后&#xff0c;函数在符号库中就是函数名&#xff0c;没有其他任何附加信息。而C是对象式语言&#xff0c;支持函数重载&#xff0c;C编译器编译后&…