Salesforce JSON解析

来源:互联网 发布:淘宝店哪家大衣好看 编辑:程序博客网 时间:2024/06/11 16:37

前言


JSON(JavaScript Object Notation)格式是目前比较流行的一种数据传输方式。JSON是一种轻量级的数据传输方式(尤其相对于XML方式),而且采用JSON传输数据结构清晰,易于理解和解析。在Salesforce中大部分的数据传输都可以采用JSON(SOAP/Metadata部分强制需要XML),所以有必要去了解Salesforce对于JSON的支持力度。

相关类

  1. JSONParser:需要实例,以调用相应的方法。主要功能是将JSON字符串转化为对象,并提供可读取为Apex基本类型/Apex Object方法,例如:getDateValue();
  2. JSONGenerator:需要实例,以调用相应的方法。主要功能是将Apex对象等转化为JSON字符串,提供Step By Step写入,例如:writeTimeField();
  3. JSON:静态方法,不需要实例。一个强大的Super(效果相当于,并不是技术实现),提供了JSONParser/JSONGenerator实例方法。并提供将Apex对象转为JSON字符串/JSON字符串转为Apex Object/Collection(List/Map等);
  4. JSONToken:枚举类型。主要服务于JSONParser
下面是一段JSON数据,我们尝试用不同的方式解析/组装:
{    "messages": [        {            "type": "Availability",            "message": {                "results": [                    {                        "id": "5732800000005GQ",                        "isAvailable": true                    }                ]            }        }    ]}

解析


以获得results中isAvailable值为例:

  1. JSONParser
    String jsonS = '{"messages":[{"type":"Availability","message":{"results":[{"id":"5732800000005GQ","isAvailable":true}]}}]}';JSONParser parser = JSON.createParser(jsonS);while (parser.nextToken() != null) {if(parser.getCurrentToken() == JSONToken.FIELD_NAME && parser.getText() == 'isAvailable') {parser.nextValue();System.debug('-- isAvailable: ' + parser.getBooleanValue());}}
  2. JSON
    String jsonS = '{"messages":[{"type":"Availability","message":{"results":[{"id":"5732800000005GQ","isAvailable":true}]}}]}';Map<String, Object> obj = (Map<String, Object>)JSON.deserializeUntyped(jsonS);List<Object> messages = (List<Object>)obj.get('messages');for(Object o : messages) {Map<String, Object> messageO = (Map<String, Object>)o;Map<String, Object> message = (Map<String, Object>)messageO.get('message');List<Object> results = (List<Object>)message.get('results');for(Object r : results) {Map<String, Object> result = (Map<String, Object>)r;System.debug('-- isAvailable: ' + result.get('isAvailable'));}}

以上代码是一种简单的解析,不涉及直接解析为Class。直观的比较而言似乎JSONParser解析要比JSON更简单、方便一些,JSON的解析方式涉及到的类型转化很多、很繁琐,一不小心就得不到想要的结果。实际上JSONParser的解析方式如果我们想要直接得到某个属性而不考虑其他,确实很快很便捷。但是却受到两个重要的限制:

  1. Key是否有重复(在JSON对象中我们很容易在不同的层级中设置相同的Key),若是这样我们可能得到错误的值;
  2. 没有层级结构:解析的结果我们无法完全的获悉层次结构。
它的优势也很明显,可以直接获取到属性值并且获得相应的类型(除String,获取String要使用getBlobValue())。JSON的解析方式看起来确实复杂而且实际执行也较为复杂,但却有个优势就是可以获得层级结构,并轻松的转为相应的Map(前提是解析过程已有)。

序列化


我们同样以构造出上述的结构为例:
  1. JSONGenerator
    JSONGenerator generator = JSON.createGenerator(true);generator.writeStartObject();generator.writeFieldName('messages');generator.writeStartArray();generator.writeStartObject();generator.writeObjectField('type', 'Availability');generator.writeFieldName('message');generator.writeStartObject();generator.writeFieldName('results');generator.writeStartArray();generator.writeStartObject();generator.writeObjectField('id', '5732800000005GQ');generator.writeObjectField('isAvailable', true);generator.writeEndObject();generator.writeEndArray();generator.writeEndObject();generator.writeEndObject();generator.writeEndArray();generator.writeEndObject();System.debug(generator.getAsString());

  2. JSON
    Map<String, Object> result = new Map<String, Object>();result.put('id', '5732800000005GQ');result.put('isAvailable', true);List<Map<String, Object>> results = new List<Map<String, Object>>();results.add(result);Map<String, Object> message = new Map<String, Object>();message.put('type', 'Availability');message.put('message', results);List<Object> messagesL = new List<Object>();messagesL.add(message);Map<String, Object> messages = new Map<String, Object>();messages.put('messages', messagesL);System.debug(JSON.serializePretty(messages));

以上代码简单的构建了一个JSON字符串。通过代码可以看到JSONGenerator构建方式是由上之下,一级一级搭建层级结构,整个过程可控但稍显臃肿;JSON的方式是先构建相应的对象(这里由Map/List实现),在转化为JSON字符串,层级结构由对象结构决定(由于Map无序,不保证同级顺序),转化方式较为简洁。以上方式不涉及直接转化Object,只涉及基本字段和Array。


心得


  1. JSON的解析和转化在Salesforce内相对而言较为简单,根据需求不同提供不同的解决方式(过程时候可控);
  2. 在涉及到解析较为严谨的地方(例如接口数据等)建议转化为对应的Object,而不是Map;
  3. JSON中带有Pretty的方法是输出是否缩进;
  4. 在实际过程中,笔者较多的使用JOSN Class的解析和转化方式,解析直接,转化方便;
  5. JSON解析为Object的情况下:两种解析方式均提供了带有Strict方法(是否严格匹配)。

附录


各自的方法和属性:
  • JSON
    • createGenerator(prettyPrint): Returns a new JSON generator;
    • createParser(jsonString): Returns a new JSON parser;
    • deserialize(jsonString, apexType): Deserializes the specified JSON string into an Apex object of the specified type;
    • deserializeStrict(jsonString, apexType): Deserializes the specified JSON string into an Apex object of the specified type;
    • deserializeUntyped(jsonString): Deserializes the specified JSON string into collections of primitive data types;
    • serialize(objectToSerialize): Serializes Apex objects into JSON content;
    • serializePretty(objectToSerialize): Serializes Apex objects into JSON content and generates indented content using the pretty-print format.
  • JSONGenerator
    • close(): Closes the JSON generator;
    • getAsString()Returns the generated JSON content.
    • isClosed()Returns true if the JSON generator is closed; otherwise, returns false.
    • writeBlob(blobValue)Writes the specified Blob value as a base64-encoded string.
    • writeBlobField(fieldName, blobValue)Writes a field name and value pair using the specified field name and BLOB value.
    • writeBoolean(blobValue)Writes the specified Boolean value.
    • writeBooleanField(fieldName, booleanValue)Writes a field name and value pair using the specified field name and Boolean value.
    • writeDate(dateValue)Writes the specified date value in the ISO-8601 format.
    • writeDateField(fieldName, dateValue)Writes a field name and value pair using the specified field name and date value. The date value is written in the ISO-8601 format.
    • writeDateTime(datetimeValue)Writes the specified date and time value in the ISO-8601 format.
    • writeDateTimeField(fieldName, datetimeValue)Writes a field name and value pair using the specified field name and date and time value. The date and time value is written in theISO-8601 format.
    • writeEndArray()Writes the ending marker of a JSON array (']').writeEndObject()Writes the ending marker of a JSON object ('}').
    • writeFieldName(fieldName)Writes a field name.writeId(identifier)Writes the specified ID value.
    • writeIdField(fieldName, identifier)Writes a field name and value pair using the specified field name and identifier value.
    • writeNull()Writes the JSON null literal value.
    • writeNullField(fieldName)Writes a field name and value pair using the specified field name and the JSON null literal value.
    • writeNumber(number)Writes the specified decimal value.writeNumber(number)Writes the specified double value.
    • writeNumber(number)Writes the specified integer value.writeNumber(number)Writes the specified long value.
    • writeNumberField(fieldName, number)Writes a field name and value pair using the specified field name and decimal value.
    • writeNumberField(fieldName, number)Writes a field name and value pair using the specified field name and double value.
    • writeNumberField(fieldName, number)Writes a field name and value pair using the specified field name and integer value.
    • writeNumberField(fieldName, number)Writes a field name and value pair using the specified field name and long value.
    • writeObject(anyObject)Writes the specified Apex object in JSON format.
    • writeObjectField(fieldName, value)Writes a field name and value pair using the specified field name and Apex object.
    • writeStartArray()Writes the starting marker of a JSON array ('[').writeStartObject()Writes the starting marker of a JSON object ('{').
    • writeString(stringValue)Writes the specified string value.writeStringField(fieldName, stringValue)Writes a field name and value pair using the specified field name and string value.
    • writeTime(timeValue)Writes the specified time value in the ISO-8601 format.
    • writeTimeField(fieldName, timeValue)Writes a field name and value pair using the specified field name and time value in the ISO-8601 format.
  • JSONParser
    • clearCurrentToken()Removes the current token.
    • getBlobValue()Returns the current token as a BLOB value.
    • getBooleanValue()Returns the current token as a Boolean value.
    • getCurrentName()Returns the name associated with the current token.
    • getCurrentToken()Returns the token that the parser currently points to or null if there's no current token.
    • getDatetimeValue()Returns the current token as a date and time value.
    • getDateValue()Returns the current token as a date value.getDecimalValue()Returns the current token as a decimal value.
    • getDoubleValue()Returns the current token as a double value.getIdValue()Returns the current token as an ID value.
    • getIntegerValue()Returns the current token as an integer value.
    • getLastClearedToken()Returns the last token that was cleared by the clearCurrentToken method.
    • getLongValue()Returns the current token as a long value.
    • getText()Returns the textual representation of the current token or null if there's no current token.
    • getTimeValue()Returns the current token as a time value.
    • hasCurrentToken()Returns true if the parser currently points to a token; otherwise, returns false.
    • nextToken()Returns the next token or null if the parser has reached the end of the input stream.
    • nextValue()Returns the next token that is a value type or null if the parser has reached the end of the input stream.
    • readValueAs(apexType)Deserializes JSON content into an object of the specified Apex type and returns the deserialized object.
    • readValueAsStrict(apexType)Deserializes JSON content into an object of the specified Apex type and returns the deserialized object. All attributes in the JSONcontent must be present in the specified type.
    • skipChildren()Skips all child tokens of type JSONToken.START_ARRAY and JSONToken.START_OBJECT that the parser currentlypoints to.
  • JSONToken
    • END_ARRAY: The ending of an object value. This token is returned when '}' isencountered.
    • END_OBJECTFIELD_NAME: A string token that is a field name.
    • NOT_AVAILABLE:  The requested token isn't available.The start of an array value. This token is returned when '[' isencountered.
    • START_ARRAY: The start of an object value. This token is returned when '{' isencountered.
    • START_OBJECT: An embedded object that isn't accessible as a typical objectstructure that includes the start and end object tokens START_OBJECT and END_OBJECT but is represented as a raw object.
    • VALUE_EMBEDDED_OBJECTVALUE_FALSE: The literal “false” value.
    • VALUE_NULL:  The literal “null” value.
    • VALUE_NUMBER_FLOAT:  A float value.
    • VALUE_NUMBER_INT:  An integer value.1830Reference JSONToken EnumEnum Value Description
    • VALUE_STRING:  A string value.
    • VALUE_TRUE:  A value that corresponds to the “true” string literal.

参考


https://resources.docs.salesforce.com/208/latest/en-us/sfdc/pdf/salesforce_apex_language_reference.pdf

原创粉丝点击