DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Languages
  4. Groovy 1.8.0 – meet JsonBuilder!

Groovy 1.8.0 – meet JsonBuilder!

Evgeny Goldin user avatar by
Evgeny Goldin
·
Jun. 20, 11 · Interview
Like (0)
Save
Tweet
Share
24.72K Views

Join the DZone community and get the full member experience.

Join For Free

Groovy 1.8.0 released in April brought a lot of new features to the language, one of them is native JSON support through JsonSlurper for reading JSON and JsonBuilder for writing JSON.

I recently used JsonBuilder in one of my projects and initially experienced some difficulties in understanding how it operates. My assumption was that JsonBuilder works similarly to MarkupBuilder but as I have quickly found out, it really doesn’t.

Let’s take a simple example. Assume we have a class Message that we would like to serialize to XML markup and JSON.

@groovy.transform.Canonical
class Message {
long id
String sender
String text
}

assert 'Message(23, me, some text)' ==
new Message( 23, 'me', 'some text' ).toString()

Here I used Groovy 1.8.0 @Canonical annotation providing automatic toString(), equals() and hashCode() and a tuple (ordered) constructor.

Let’s serialize a number of messages to XML.

def messages = [ new Message( 23, 'me', 'some text'       ),
new Message( 24, 'me', 'some other text' ),
new Message( 25, 'me', 'same text' )]

def writer = new StringWriter()
def xml = new groovy.xml.MarkupBuilder( writer )

xml.messages() {
messages.each { Message m -> message( id : m.id,
sender : m.sender,
text : m.text )}
}

assert writer.toString() == """
<messages>
<message id='23' sender='me' text='some text' />
<message id='24' sender='me' text='some other text' />
<message id='25' sender='me' text='same text' />
</messages>""".trim()

Well, that was pretty straightforward. Let’s try to do the same with JSON.

def json = new groovy.json.JsonBuilder()

json.messages() {
messages.each { Message m -> message( id : m.id,
sender : m.sender,
text : m.text )}
}

assert json.toString() ==
'{"messages":{"message":{"id":25,"sender":"me","text":"same text"}}}'

Wow, where did all other messages go? Why only one last message in the list was serialized?
How about this

json = new groovy.json.JsonBuilder()

json.messages() {
message {
id 23
sender 'me'
text 'some text'
}
message {
id 24
sender 'me'
text 'some other text'
}
}

assert json.toString() ==
'{"messages":{"message":{"id":24,"sender":"me","text":"some other text"}}}'

Same story. Initially I was puzzled, but then JsonBuilder source code showed that every invocation overrides the previous content:

JsonBuilder(content = null) {
this.content = content
}

def call(Map m) {
this.content = m
return content
}

def call(List l) {
this.content = l
return content
}

def call(Object... args) {
this.content = args.toList()
return this.content
}

def call(Closure c) {
this.content = JsonDelegate.cloneDelegateAndGetContent(c)
return content
}

As you see, one should invoke JsonBuilder exactly once, passing it a Map, List, varargs or Closure. This makes JsonBuilder very different from MarkupBuilder which can be updated as many times as needed. It could be caused by the JSON itself, whose format is stricter than free-form XML markup: something that started as a JSON map with a single Message, can not be made into array of Messages out of sudden.

The argument passed to JsonBuilder (Map, List, varargs or Closure) can also be specified in constructor so there’s no need to invoke a builder at all. You can simply initialize it with the corresponding data structure and call toString() right away. Let’s try this!

 

def listOfMaps = messages.collect{
Message m -> [ id : m.id,
sender : m.sender,
text : m.text ]}

assert new groovy.json.JsonBuilder( listOfMaps ).toString() ==
'''[{"id":23,"sender":"me","text":"some text"},
{"id":24,"sender":"me","text":"some other text"},
{"id":25,"sender":"me","text":"same text"}]'''.
readLines()*.trim().join()

Now it works :) After converting the list of messages to the list of Maps and sending them to the JsonBuilder in one go, the String generated contains all messages from the list. All code above is available in Groovy web console so you are welcome to try it out.

Btw, for viewing JSON online I recommend an excellent “JSON Visualization” application made by Chris Nielsen. “Online JSON Viewer” is another popular option, but I much prefer the first one. And for offline use “JSON Viewer” makes a good Fiddler plugin.

 

 

P.S.
If you need to read this JSON on the client side by sending, say, Ajax GET request, this can be easily done with jQuery.get():

 

<script type="text/javascript">
var j = jQuery

j( function() {
j.get( 'url',
{ timestamp: new Date().getTime() },
function ( messages ){
j.each( messages, function( index, m ) {
alert( "[" + m.id + "][" + m.sender + "][" + m.text + "]" );
});
},
'json'
);
})
</script>

Here I use a neat trick of a j shortcut to avoid typing jQuery too many times when using $ is not an option.

 

 

From http://evgeny-goldin.com/blog/groovy-jsonbuilder/?

Groovy (programming language) JSON

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 10 Best Practices for Web Application Testing
  • How To Build a Spring Boot GraalVM Image
  • Apache Kafka Is NOT Real Real-Time Data Streaming!
  • Best CI/CD Tools for DevOps: A Review of the Top 10

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: