- if a number is greater than certain limit then it will convert it into exponent format.
- if the data type is date then it converted to some type but in UI side we want something different.
- Sometimes decimal fields also gets converted to some other formatting.
So, in-order to avoid any reformatting of data at client side. I wrote a ColdFusion function which will perform the conversion (CF Object -> JSON). I'm already using this in one of my project and it works fine without any problem. Hope it may help you if you're looking something like this.
Points to Remember:
- You can modify the code if you need certain type of formatting for date or number data type.
- For serializing ColdFusion components make sure the fields present as the properties of that component.
If you have any feedback for this I'm happy to listen it. Below is the code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cffunction name="JSONUtil" access="private" returntype="string" output="false" hint="Serialize complex object into JSON"> | |
<cfargument name="obj" type="any" required="true" hint="Object which will be converted into JSON" /> | |
<cfset var returnValue = createObject("Java","java.lang.StringBuilder") /> | |
<cfset var currentMetaData = getMetaData(obj) /> | |
<cfif isStruct(currentMetaData) AND structKeyExists(currentMetaData, "TYPE") AND compareNoCase(currentMetaData.TYPE, "component") EQ 0> | |
<cfset returnValue.append("{") /> | |
<cfset var isNOTFirstElem = false /> | |
<cfif structKeyExists(currentMetaData, "properties")> | |
<cfloop array="#currentMetaData.properties#" index="property"> | |
<cfif isNOTFirstElem> | |
<cfset returnValue.append(",") /> | |
</cfif> | |
<cfset var tempObj = evaluate("obj." & "get#property.name#()") /> | |
<cfif IsSimpleValue( tempObj )> | |
<cfset returnValue.append("""#property.name#"":""#reReplace(tempObj, '"', '\"', 'ALL')#""") /> | |
<cfelse> | |
<cfset returnValue.append("""#property.name#"":#JSONUtil(tempObj)#") /> | |
</cfif> | |
<cfset isNOTFirstElem = true /> | |
</cfloop> | |
</cfif> | |
<cfset returnValue.append("}") /> | |
<cfelseif isArray(obj)> | |
<cfset returnValue.append("[") /> | |
<cfset var isNOTFirstElem = false /> | |
<cfloop array="#obj#" index="arrayIndex"> | |
<cfif isNOTFirstElem> | |
<cfset returnValue.append(",") /> | |
</cfif> | |
<cfif IsSimpleValue( arrayIndex )> | |
<cfset returnValue.append("""#reReplace(arrayIndex, '"', '\"', 'ALL')#""") /> | |
<cfelse> | |
<cfset returnValue.append("#JSONUtil(arrayIndex)#") /> | |
</cfif> | |
<cfset isNOTFirstElem = true /> | |
</cfloop> | |
<cfset returnValue.append("]") /> | |
<cfelseif isQuery(obj)> | |
<cfset returnValue.append("{ ""recordCount"": #obj.recordCount#, ""data"": [") /> | |
<cfloop query="obj"> | |
<cfif obj.CurrentRow EQ 1> | |
<cfset returnValue.append("{") /> | |
<cfelse> | |
<cfset returnValue.append(",{") /> | |
</cfif> | |
<cfset var isNOTFirstElem = false /> | |
<cfloop array="#currentMetaData#" index="columnDetails"> | |
<cfif isNOTFirstElem> | |
<cfset returnValue.append(",") /> | |
</cfif> | |
<cfset returnValue.append("""#columnDetails.Name#"":""#reReplace(obj[columnDetails.Name][obj.CurrentRow], '"', '\"', 'ALL')#""") /> | |
<cfset isNOTFirstElem = true /> | |
</cfloop> | |
<cfset returnValue.append("}") /> | |
</cfloop> | |
<cfset returnValue.append("] }") /> | |
<cfelseif isStruct(obj)> | |
<cfset returnValue.append("{") /> | |
<cfset var isNOTFirstElem = false /> | |
<cfloop collection="#obj#" item="collectionItem"> | |
<cfif isNOTFirstElem> | |
<cfset returnValue.append(",") /> | |
</cfif> | |
<cfif StructKeyExists(obj, "#collectionItem#")> | |
<cfif IsSimpleValue(StructFind(obj, collectionItem))> | |
<cfset returnValue.append("""#collectionItem#"":""#reReplace(StructFind(obj, collectionItem), '"', '\"', 'ALL')#""")> | |
<cfelse> | |
<cfset returnValue.append("""#collectionItem#"":#JSONUtil( StructFind(obj, collectionItem) )#")> | |
</cfif> | |
<cfelse> | |
<cfset returnValue.append("""#collectionItem#"":""""")> | |
</cfif> | |
<cfset isNOTFirstElem = true /> | |
</cfloop> | |
<cfset returnValue.append("}") /> | |
<cfelseif IsSimpleValue(obj)> | |
<cfset returnValue.append("""#reReplace(obj, '"', '\"', 'ALL')#""") /> | |
<cfelse> | |
<cfthrow message="JSONUtil doesn't support object of type: #currentMetaData.getName()#" type="JSONParsingError" /> | |
</cfif> | |
<cfreturn returnValue.toString() /> | |
</cffunction> |