json - Groovy JsonBuilder strange behavior when toString() -


i need create json use body in http.request. i'm able build dynamically json, noticed strange behavior when calling builder.tostring() twice. resulting json totally different. i'm think related kind of buffer or so. i've been reading documentation can't find answer. here code test.

import groovy.json.jsonbuilder  def builder = new jsonbuilder()  def map = [     cata: ["cata-element1", "cata-element2"],     catb:[],     catc:["catc-element1"] ]  def = map.inject([:]) { res, k, v ->     def b = v.inject([:]) {resp, ->         resp[i] = k         resp     }     res += b } println  def root = builder.query {     bool {         must a.collect{ k, v ->             builder.match {                 "$v" k             }         }     }     should([         builder.simple_query_string {             query "text"         }     ]) } println builder.tostring() println builder.tostring() 

this print following lines. pay attention last 2 lines

[cata-element1:cata, cata-element2:cata, catc-element1:catc] {"query":{"bool":{"must":[{"match":{"cata":"cata-element1"}},{"match":{"cata":"cata-element2"}},{"match":{"catc":"catc-element1"}}]},"should":[{"simple_query_string":{"query":"text"}}]}} {"match":{"catc":"catc-element1"}} 

in code can send first tostring() result variable , use when needed. but, why change when invoking more 1 time?

i think happening because using builder inside closure bool. if make print builder.content before printing result (buider.tostring() calling jsonoutput.tojson(builder.content)) get:

[query:[bool:consolescript54$_run_closure3$_closure6@294b5a70, should:[[simple_query_string:[query:text]]]]] 

adding println builder.content bool closure can see builder.content modified when closure evaluated:

def root = builder.query {     bool {         must a.collect{ k, v ->             builder.match {                 "$v" k                 println builder.content             }         }     }     should([         builder.simple_query_string {             query "text"         }     ]) }  println jsonoutput.tojson(builder.content) println builder.content 

the above yields:

[query:[bool:consolescript55$_run_closure3$_closure6@39b6156d, should:[[simple_query_string:[query:text]]]]] [match:[cata:cata-element1]] [match:[cata:cata-element2]] {"query":{"bool":{"must":[{"match":{"cata":"cata-element1"}},{"match":{"cata":"cata-element2"}},{"match":{"catc":"catc-element1"}}]},"should":[{"simple_query_string":{"query":"text"}}]}} [match:[catc:catc-element1]] 

you can avoid different builder closure inside:

def builder2 = new jsonbuilder()  def root = builder.query {     bool {         must a.collect{ k, v ->             builder2.match {                 "$v" k             }         }     }     should([         builder.simple_query_string {             query "text"         }     ]) } 

or better:

def root = builder.query {     bool {         must a.collect({ k, v -> ["$v": k] }).collect({[match: it]})     }     should([         simple_query_string {             query "text"         }     ]) } 

Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -