Removing an entry from a GWT JSONObject - json

Let's say I have a JSONObject in GWT that looks like this: {"name1":value1, "name2":value2}. Is there a way to remove the "name2":value2 key/value pair and change this object to {"name1":value1}? I have not found any methods that help with this approach in the GWT Javadoc.
I know there are workarounds to this, of course. Since my JSONObject is small, I am currently making a new one and putting in it all the key/value pairs other than the one I want to remove. But this won't work when I plan to pass in the JSONObject to a child function; since only the JSONObject's reference is passed in Java, I need a mutator function to actively change what the method parameter's JSONObject points to. In the worse case, I could convert the JSONObject to a String and regexp out what I don't want. But this seems prone to error and ugly. Any suggestions?

Actually, put()ing a null (as opposed to a JSONNull) value will delete the value for the given key.

Related

io.vertx.core.json.JsonObject: How to get the type of the value for given key?

I'm using the following package for JsonObject:
http://vertx.io/docs/apidocs/io/vertx/core/json/JsonObject.html
If I get a JsonObject with key 'fieldName' and I want to get its value, I have to use functions such as 'getString', 'getInteger', 'getArray' etc. I mean that I have to know in advanced the type of the value. What happens if I don't know it?
Is there any generic function of retrieving value from JsonObject without knowing its type?
Use getValue(String).
It returns an Object then you can test the type and cast accordingly.
Notes for the comments: Checking the code on GitHub, looks like the getField(String) method is present in the 2.x branch. Looks like getValue(String) is delegated to getField(String) method (see the code). As of August 2017, there's no getField(String) in the master (see the code).

Deserialize an anonymous JSON array?

I got an anonymous array which I want to deserialize, here the example of the first array object
[
{ "time":"08:55:54",
"date":"2016-05-27",
"timestamp":1464332154807,
"level":3,
"message":"registerResourcePath ('', '/sap/bc/ui5_ui5/ui2/ushell/resources/')",
"details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":"URL prefixes set to:","details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":" (default) : /sap/bc/ui5_ui5/ui2/ushell/resources/","details":"","component":"sap.ui.ModuleSystem"}
]
I tried deserializing using CL_TREX_JSON_SERIALIZER, but it is corrupt and does not work with my JSON, here is why
Then I tried /UI2/CL_JSON, but it needs a "structure" that perfectly fits the object given by the JSON Object. "Structure" means in my case an internal table of objects with the attributes time, date, timestamp, level, messageanddetails. And there was the problem: it does not properly handle references and uses class description to describe the field assigned to the field-symbol. Since I can not have a list of objects but only a list of references to objects that solution also doesn't works.
As a third attempt I tried with the CALL TRANSFORMATION as described by Horst Keller, but with this method I was not able to read in an anonymous array, and here is why
My major points:
I do not want to change the JSON, since that is what I get from sap.ui.log
I prefere to use built-in functionality and not a thirdparty framework
Your problem comes out not from the anonymity of array, but from the awkwardness of SAP JSON (De)serializer, which doesn't respect double quotes, which enclose JSON attributes. The issue is thoroughly described in this answer.
If you don't want to change your JSON on-the-fly, the only way you have is to change CL_TREX_JSON_DESERIALIZER class like this.
/UI5/CL_JSON_PARSER parses JSONs with unknown format.
Note that it's got "for internal use" written on it so many times that you probably should take it seriously and clone its code to fixate it.

replace value of JSON field using SPEL in SpringXD

I get json in stream and try to replace value of one field in payload.
transform --expression=payload.replaceAll() does not fit my needs as it treat payload as String.
I think of such operation
transform --expression=#jsonPath(payload,'$.result.grupy[*].lp')='new_value'
but it does not perform this assigment. How construct SPEL/JsonPath expression to set new value?
I need something like payload.setField('lp','new_value')
It's not possible to do that; you would need a custom processor module, or a custom SpEL function, to make changes like that.
The #jsonPath function simply returns an element from the JSON.
Not sure why payload.replace() expression doesn't fit your requirements, but the #jsonPath() SpEL-fuction is for extraction the data from JSON, not for modification.
From other side you misunderstood a bit a concept of transformer component. It returns a new object, but doesn't modify the request.
To achieve your requirements you should take a look to the Content Enricher, which exactly is intended to modify the incoming payload and return it as a reply.
To simplify your life you should take a look to the <int:object-to-map-transformer> to have ability to change field from the next <int:enricher> component.
Right, for this purpose you should write your own processor module.

Grails, create domain object from json-string with has-many relation

I'm trying to parse a grails parameter map to a Json String, and then back to a parameter map. (For saving html form entries with constraint-violations)
Everything is fine as long as there is no hasMany relationship in the parameter-map.
I'm using
fc.parameter = params as JSON
to save the params as JSON String.
Later I'm trying to rebuild the parameter map and create a new Domain-Object with it:
new Foo(JSON.parse(fc.parameter))
Everything is fine using only 1:1 relationships (states).
[states:2, listSize:50, name:TestFilter]
But when I try to rebuild a params-map with multi-select values (states)
[states:[1,2], listSize:50, name:TestFilter]
I'm getting this IllegalStateException:
Failed to convert property value of type org.codehaus.groovy.grails.web.json.JSONArray to required type java.util.Set for property states; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [de.gotosec.approve.State] for property states[0]: no matching editors or conversion strategy found
I tried to use this, but without success:
JSON.use("deep") {
new Foo(JSON.parse(fc.parameter))
}
You can use JsonSlurper instead of the converters.JSON of grails, it maps JSON objects to Groovy Maps. I think this link also might help you.
Edit: Now, if the problem is binding the params map to your domain, you should try using bindData() method, like:
bindData(foo, params)
Note that this straightforward use is only if you're calling bindData inside a controller.
What seems to be happening in your case is that Grails is trying to bind a concrete type of List (ArrayList in the case of JsonSlurper and JSONArray in the case of converters.JSON) into a Set of properties (which is the default data structure for one-to-many associations). I would have to take a look at your code to confirm that. But, as you did substitute states: [1,2] for a method of your app, try another test to confirm this hypothesis. Change:
states:[1,2]
for
states:[1,2] as Set
If this is really the problem and not even bindData() works, take a look at this for a harder way to make it work using object marshalling and converters.JSON. I don't know if it's practical for you to use it in your project, but it sure works nicely ;)

Groovy map must be converted to JSON object with numerical object key

I am doing some processing with Groovy/Grails and the results are a map of type <String, Float>.
When returning the JSON object to the calling function (in this case, it's a flot diagram which requires [number,number] format), the key needs to be a number. This, in theory, is fine as my key to the map is a number in string form. I can't, however, figure out a way to create the JSON object with a numerical key.
I get results like this:
{"1":-9.814244910221474,"2":-9.710478606504552,"3":-9.636841089398253,"4":-9.524104819110796,"5":-9.522597036735684 ...}
instead of:
{1:-9.814244910221474,2:-9.710478606504552,3:-9.636841089398253,4:-9.524104819110796,5:-9.522597036735684 ...}
Does anyone know a way to force the JSON Map.encodeAsJSON() to produce an integer key? I've tried explicitly creating a map of type < integer,integer > before encoding it, and that doesn't work either.
Mike, Im looking at the json spec -- it appears that the keys must be strings. You should handle this client side.
http://www.json.org/