javascript
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模式的這種方法的步驟可以概括為:
使用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
這個簡單的命令生成與提供的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.JsonSchema類com.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
總結
以上是生活随笔為你收集整理的jaxb xsd生成xml_使用JAXB和Jackson从XSD生成JSON模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos工作原理(ddos 工作原理)
- 下一篇: 应对ddos(对ddos感知)