JSON
适配器是一种将
ObjectScript
对象(registered, serial or persistent)映射到
JSON
文本或动态实体的方法。本章涵盖以下主题:
- 导出和导入-介绍启用
的对象并演示JSON
导入和导出方法%JSON.Adaptor
- 带参数映射-描述控制如何将对象属性转换为
字段的属性参数。JSON
- 使用扩展数据映射块-介绍将多个参数映射应用到单个类的方法。
- 格式化
-演示如何使用JSON
格式化%JSON.ForMatter
字符串。JSON
-
快速参考-提供本章中讨论的每个%JSON
类成员的简要说明。%JSON
Exporting and Importing
从JSON序列化或序列化到JSON的任何类都需要子类
%JSON.Adaptor
,它包括以下方法:
-
将启用JSON的类序列化为JSON文档,并将其写入当前设备。%JSONExport()
-
将启用JSON的类序列化为JSON文档并将其写入流。%JSONExportToStream()
-
将启用JSON的类序列化为JSON文档并将其作为字符串返回。%JSONExportToString()
-
将JSON作为字符串或流导入,或者作为%JSONImport()
Object的子类导入,并返回启用JSON的类的实例。%DynamicAbstract
为了演示这些方法,本节中的示例将使用这两个类:
启用JSON的类 Model.Event
和 Model.Location
Model.Event
Model.Location
Class Model.Event Extends (%Persistent, %JSON.Adaptor)
{
Property Name As %String;
Property Location As Model.Location;
}
复制
Class Model.Location Extends (%Persistent, %JSON.Adaptor)
{
Property City As %String;
Property Country As %String;
}
复制
如所见,我们有一个持久
Event
类,有一个
Location
属性类型为
Model.Location
。这两个类都继承自
%JSON.Adaptor
。这使能够填充对象图,并将其直接导出为JSON字符串。
将对象导出为JSON字符串
/// d ##class(PHA.TEST.Xml).SaveEvent()
ClassMethod SaveEvent()
{
set event = ##class(Model.Event).%New()
set event.Name = "Global Summit"
set location = ##class(Model.Location).%New()
set location.Country = "United States of America"
set event.Location = location
do event.%JSONExport()
}
复制
此代码显示以下JSON字符串:
DHC-APP>d ##class(PHA.TEST.Xml).SaveEvent()
{"Name":"Global Summit","Location":{"Country":"United States of America"}}
复制
可以使用
%JSONExportToString()
而不是
%JSONExport()
将
JSON
字符串赋给变量:
/// d ##class(PHA.TEST.Xml).SaveEventString()
ClassMethod SaveEventString()
{
set event = ##class(Model.Event).%New()
set event.Name = "Global Summit"
set location = ##class(Model.Location).%New()
set location.Country = "United States of America"
set event.Location = location
do event.%JSONExportToString(.jsonEvent)
w jsonEvent,!
}
复制
DHC-APP>d ##class(PHA.TEST.Xml).SaveEventString()
{"Name":"Global Summit","Location":{"Country":"United States of America"}}
复制
最后,可以通过
%JSONImport()
将JSON字符串转换回对象。此示例从上一个示例中获取字符串变量
jsonEvent
,并将其转换回
Model.Event
对象:
将JSON字符串导入到对象中
/// d ##class(PHA.TEST.Xml).SaveEventStringImport()
ClassMethod SaveEventStringImport()
{
set event = ##class(Model.Event).%New()
set event.Name = "yx"
set location = ##class(Model.Location).%New()
s location.City = "tianjin"
set location.Country = "United States of America"
set event.Location = location
do event.%JSONExportToString(.jsonEvent)
set eventTwo = ##class(Model.Event).%New()
do eventTwo.%JSONImport(jsonEvent)
write eventTwo.Name,!,eventTwo.Location.City
}
复制
DHC-APP>d ##class(PHA.TEST.Xml).SaveEventStringImport()
yx
tianjin
复制
导入和导出都适用于任意嵌套的结构。
使用参数映射
可以通过设置相应的参数为每个单独的属性指定映射逻辑。
可以通过指定属性参数来更改
Model.Event
类(在上一节中定义)的映射:
Class Model.Event Extends (%Persistent, %JSON.Adaptor)
{
Property Name As %String(%JSONFIELDNAME = "eventName");
Property Location As Model.Location(%JSONINCLUDE = "INPUTONLY");
}
复制
此映射引入了两个更改:
- 属性名称将映射到名为
的JSON字段。eventName
-
属性仍将由Location
用作输入,但将被%JSONImport()
和其他导出方法忽略。%JSONExport()
以前,在未修改的
Model.Event
类的实例上调用
%JSONExport()
,并返回以下
JSON
字符串:
{"Name":"Global Summit","Location":{"City":"Boston","Country":"United States of America"}}
复制
如果对重新映射的
Model.Event
实例调用
%JSONExport()
(使用相同的属性值),将返回以下字符串:
DHC-APP>d ##class(PHA.TEST.Xml).SaveEvent()
{"eventName":"Global Summit"}
复制
有各种参数可用于调整映射:
-
仅限属性)设置要用作JSON内容中的字段名称的字符串(默认情况下,值为属性名称)。%JSONFIELDNAME(
-
控制对JSON输入中意外字段的处理。%JSONIGNOREINVALIDFIELD
-
允许开发人员覆盖字符串属性的空字符串的默认处理。%JSONIGNORENULL
-
(仅限属性)指定该属性是否包含在JSON输出或输入中(有效值为%JSONINCLUDE
(默认),"inout"
,"outputonly"
,或"inputOnly"
)。"none"
-
指定了如何为字符串属性存储空字符串。%JSONNULL
-
%JSONREFERENCE
指定如何将对象引用投影到JSON字段。
选项包括
、OBJECT(默认值)
、ID
和OID
。GUID
使用XData映射块
可以在特殊的XData mapping块中指定映射,并在调用导入或导出方法时应用映射,而不是在属性级别上设置映射参数。
Class Model.Event Extends (%Persistent, %JSON.Adaptor)
{
Property Name As %String;
Property Location As Model.Location;
XData OnlyLowercaseTopLevel
{
<Mapping xmlns="http://www.intersystems.com/jsonmapping">
<Property Name="Name" FieldName="eventName"/>
<Property Name="Location" Include="INPUTONLY"/>
</Mapping>
}
Storage Default
{
<Data name="EventDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
<Value name="3">
<Value>Location</Value>
</Value>
</Data>
<DataLocation>^Model.EventD</DataLocation>
<DefaultData>EventDefaultData</DefaultData>
<IdLocation>^Model.EventD</IdLocation>
<IndexLocation>^Model.EventI</IndexLocation>
<StreamLocation>^Model.EventS</StreamLocation>
<Type>%Storage.Persistent</Type>
}
}
复制
这里有一个重要的区别:
XData
块中的
JSON
映射不会改变默认行为,但是可以通过在导入和导出方法的可选参数
%mappingName
中指定块名称来应用它们。
例如:
do event.%JSONExport("OnlyLowercaseTopLevel")
复制
/// d ##class(PHA.TEST.Xml).SaveEventXData()
ClassMethod SaveEventXData()
{
set event = ##class(Model.Event).%New()
set event.Name = "Global Summit"
set location = ##class(Model.Location).%New()
set location.Country = "United States of America"
set event.Location = location
do event.%JSONExport("OnlyLowercaseTopLevel")
}
复制
显示
{"eventName":"Global Summit"}
复制
就像在属性定义中指定了参数一样。
如果没有具有提供名称的扩展数据块,将使用默认映射。使用这种方法,可以配置多个映射并分别引用每个调用所需的映射,从而使可以更好地控制,同时使您的映射更加灵活和可重用。
定义到扩展数据映射块
支持JSON的类可以定义任意数量的附加映射。每个映射都在以下形式的单独扩展数据块中定义:
XData {MappingName}
{
<Mapping {ClassAttribute}="value" [...] xmlns="http://www.intersystems.com/jsonmapping".>
<{Property Name}="PropertyName" {PropertyAttribute}="value" [...] />
[... more Property elements]
</Mapping>
}
复制
其中,
{MappingName}
、
{ClassAttribute}
、
{Property Name}
和
{PropertyAttribute}
的定义如下:
-
MappingName
参数或%JSONREFERENCE
属性使用的映射的名称。Reference
-
指定映射的类参数。可以定义以下类属性:ClassAttribute
-
-要应用的扩展数据映射块的名称。Mapping
-
-指定类参数IgnoreInvalidField
。%JSONIGNOREINVALIDFIELD
-
-指定类参数NULL
。%JSONNULL
-
-指定类参数IgnoreNull
。%JSONIGNORENULL
-
-指定类参数Reference
。%JSONREFERENCE
-
-
要映射的属性的名称。PropertyName
-
指定映射的特性参数。可以定义以下特性属性:PropertyAttribute
-
-指定属性参数FieldName
(默认情况下与属性名称相同)。%JSONFIELDNAME
-
-指定属性参数Include
(有效值为%JSONINCLUDE
(默认值),"inout"
,"outputonly"
,或"inputOnly"
)。"none"
-
-要应用于对象属性的映射定义的名称。Mapping
-
-覆盖类参数NULL
。%JSONNULL
-
-覆盖类参数IgnoreNull
。%JSONIGNORENULL
-
-覆盖类参数Reference
。%JSONREFERENCE
-
格式化JSON
%JSON.ForMatter
是一个具有非常简单接口的类,允许将动态对象、数组和JSON字符串格式化为更易于阅读的表示形式。所有方法都是实例方法,因此始终从检索实例开始:
set formatter = ##class(%JSON.Formatter).%New()
复制
此选择背后的原因是,可以将格式化程序配置为只使用一次某些字符作为行终止符和缩进(例如,空格与制表符;请参阅本节末尾的属性列表),然后在需要的任何地方使用它。
Format()
方法接受动态实体或JSON字符串。下面是一个使用动态对象的简单示例:
/// d ##class(PHA.TEST.Xml).FormatterJson()
ClassMethod FormatterJson()
{
s formatter = ##class(%JSON.Formatter).%New()
s dynObj = {"type":"string"}
do formatter.Format(dynObj)
}
复制
DHC-APP>d ##class(PHA.TEST.Xml).FormatterJson()
{
"type":"string"
}
复制
Format
方法可以将输出定向到当前设备、字符串或流:
-
使用指定的缩进格式化JSON文档并将其写入当前设备。Format()
-
使用指定的缩进格式化JSON文档并将其写入流。FormatToStream()
-
使用指定的缩进格式化JSON文档并将其写入字符串,或者将启用JSON的类序列化为JSON文档并将其作为字符串返回。FormatToString()
此外,以下属性可用于控制缩进和换行符:
-
缩进指定是否应缩进JSON输出Indent
-
指定用于每个缩进级别的字符序列(默认为每个级别一个空格)。IndentChars
-
行终止符指定缩进时终止每行的字符序列。LineTerminator