Java add function to json object without using quotes. - java

I'm building a json object in java. I need to pass a function into my javascript and have it validated with jquery $.isFunction(). The problem I'm encountering is I have to set the function in the json object as a string, but the json object is passing the surrounding quotes along with object resulting in an invalid function. How do I do this without having the quotes appear in the script.
Example Java
JSONObject json = new JSONObject();
json.put("onAdd", "function () {alert(\"Deleted\");}");
Jquery Script
//onAdd output is "function () {alert(\"Deleted\");}"
//needs to be //Output is function () {alert(\"Deleted\");}
//in order for it to be a valid function.
if($.isFunction(onAdd)) {
callback.call(hidden_input,item);
}
Any thoughts?

You can implement the JSONString interface.
import org.json.JSONString;
public class JSONFunction implements JSONString {
private String string;
public JSONFunction(String string) {
this.string = string;
}
#Override
public String toJSONString() {
return string;
}
}
Then, using your example:
JSONObject json = new JSONObject();
json.put("onAdd", new JSONFunction("function () {alert(\"Deleted\");}"));
The output will be:
{"onAdd":function () {alert("Deleted");}}
As previously mentioned, it's invalid JSON, but perhaps works for your need.

You can't. The JSON format doesn't include a function data type. You have to serialise functions to strings if you want to pass them about via JSON.

Running
onAdd = eval(onAdd);
should turn your string into a function, but it's buggy in some browsers.
The workaround in IE is to use
onAdd = eval("[" + onAdd + "]")[0];
See Are eval() and new Function() the same thing?

Related

Is toString() mandatory while accessing the individual element of a JSON object in Java

I am quite new to Java and trying to understand the effect of using toString() while accessing the individual string elements of JSON object in Java.
Below are the steps followed:
Parse the JSON data. Let's assume only string elements are there in parsed JSON data.
JSONParser parser = new JSONParser();
JSONObject jsonObj = (JSONObject) parser.parse(json_data);
{
"firstname" : "new",
"lastname" : "human",
"id" : "some_id"
}
Try to access the individual elements.
Access without toString():
Public static String firstname = jsonObj.get("firstname");
Access with toString():
Public static String firstname = jsonObj.get("firstname").toString();
I do not see a difference when I try to print the data.
However I would like to know the difference between the above 2 methods, and also will there be any issues if I use without toString() in this particular case.
Appreciate your help.
Thank you
When you have some Int or other type of data type variables in your model class and you want to parse it into a string so for that we use toString(), it will convert int or any other data variable into a string, in your case here you already have string so no need to change again and again and JSON uses string variables when it comes from backend so that the purpose.
toString() returns string representation of property/object on which this method is called.
Whenever we print an object reference, it invokes the toString() method internally as a result , it is not making difference.
Because you are using Json, there is no difference.
You can use the Option, you like more

Append new value to javax.json.JsonObject

The code that we already have return us JsonObject. What I want to do is to add a new key and the value for it.
For example, we have an object like this:
{"id":"12","name":"test"}
I want to transform it into this:
{"id":"12","name":"test","status":"complete"}
I didn't find what I need in documentation except using put method. So I wrote this code:
JsonObject object = getJsonObject();
JsonString val = new JsonString() {
public JsonValue.ValueType getValueType() {
return JsonValue.ValueType.STRING;
}
public String getString() {
return "complete";
}
public CharSequence getChars() {
return (CharSequence) "complete";
}
};
object.put("status", val);
But it doesn't work, crashing with :
java.lang.UnsupportedOperationException
I can't understand what is wrong. Have I any other option to complete such a task?
I don't think JsonObject instances are meant to be modified.
I think your best option is to create a new object, copy the existing properties and add the new property to it.
You can use https://docs.oracle.com/javaee/7/api/javax/json/JsonObjectBuilder.html
Not sure if object.put works but you can use the following way to append the details to JSON value:
You can create a different JSON object with the key and value that you want to add to the JSON object and the user object.merge(status, complete, String::concat);
merge() checks for the key:'status' in your JSON object if it does'nt find it then it adds that key:value pair or else it replaces it
.You are not able to compile it because you may not be using jre 1.8.
I've Just verified the following method:
Just create a new JSONObject(org.json.JSONObject not javax.json.JsonObject)
JSONObject modifiedJsonObject= new JSONObject(object.toString());
modifiedJsonObject.put("status", "complete");

Matching JSON object with an instance

Assume I have following DTO:
class C {
String a;
String b;
}
And I have the JSON:
{
"c" : {
"a" : "aaa",
"b" : "bbb"
}
}
What I want to do is, accomplish following test:
C expected = new C("aaa","bbb");
mockMvc.perform(get("url"))
.andExpect(jsonPath("$.c", is(expected)));
It fails. If I first serialize expected to JSON and then try to match, it again fails because it's a string. Is this possible?
Always remember: There is no such thing as a "JSON object". JSON is a serialization format for objects. JSON is always a string. You can convert from object to JSON and back (and hence from object to string and back). But
{ "a": "b" }
is a JavaScript object, not JSON (even if it looks very similar).
This in fact is the answer to your question: When you serialize expected, you get JSON (the transport format, i.e. the string). This isn't what jsonPath() checks. jsonPath() validates against JavaScript types.
This blog post suggests that you need to check each field individually:
.andExpect(jsonPath("$.c.a", is(expected.a)))
.andExpect(jsonPath("$.c.b", is(expected.b)));
which is tedious. What you need is
a) to configure your JSON framework to use a mapping system that sorts keys and
b) you need to figure out what type jsonPath("$.c", ...) returns - it's probably the type which your JSON framework uses to represent generic JavaScript objects.
The check then looks like this:
C c = new C("aaa","bbb");
String serialized = JSON.serialize(c); // to string
JSObject expected = JSON.parse(serialized); // to generic JavaScript object
mockMvc.perform(get("url"))
.andExpect(jsonPath("$.c", is(expected)));
Note that this only works if JSObject has a proper implementation for equals().
If you can afford to modify your "C" class to add it an "equals" operator and to modify slightly your JSON file, I would suggest you to transform your JSON string into an instance of "C". This can be done with a good JSON-ifier (Jackson or GSON). Then you just have to compare the 2 instances.
Some examples with GSON:
class C {
String a;
String b;
public boolean equals(C obj) { return a.equals(obj.a) && b.equals(obj.b); }
}
// Your JSON file should look like that
{
"a" : "aaa",
"b" : "bbb"
}
// So the test is simple
C expected = new C("aaa","bbb");
C json = gson.fromJson(jsonString, C.class);
if (expected.equals(json)) {
// Do whatever you want here
}
If you cannot afford to change the JSON file, just create another class to contains your main class, like this:
class Wrapper {
C c;
}
Wrapper jsonW = gson.fromJson(jsonString, Wrapper.class);
C json = jsonW.c;
...
If you cannot afford the addition of the equals operator, I suggest to create JSON string based on the 2 "C" instance objects and compare the strings. Your jsonString becomes a real "C" object (json) before ending into a new string (jsonStr).
String expectedStr = gson.toJson(expected);
String jsonStr = gson.toJSON(json);
if (expectedStr.equals(jsonStr)) {
// Do whatever you want here
}

Parse json string to object using Gson

I tried converting my json string to java object by using Gson but somehow it was not successful and I haven't figured out why..
My Json string
{
"JS":{
"JS0":{
"Name":"ABC",
"ID":"5"
},
"JS1":{
"Location":"UK",
"Town":"LD"
},
"JS2":{
"Usable":"true",
"Port":"ABC"
}
}
}
In java code I have 4 classes, JS, JS0, JS1 and JS2
JS class contains JS0, JS1 and JS2 variables
JS0, JS1 and JS2 classes contain fields as in Json string example, e.g. JS0 contains 02 fields, String Name and String ID
In all classes I have getter/setter for variables, 02 constructors (01 with empty parameters and another one with all variables in the parameter field)
And for using Gson:
Gson gson = new Gson();
jsObject = gson.fromJson(sb.toString(), JS.class);
When I access JS0, JS1 and JS2 objects from jsObject, they are null...
Can someone show me what did I do wrong?
Thank you very much,
The problem here is, you are trying to convert
{
"JS" : {
/* rest of JSON */
}
}
to JS object, but the above JSON is a representation of Java class like this
class Foo {
JS JS;
}
So, you need to get the value of JS from the JSON string first, then call fromJSON to deserialize it with the JS.class passed as the second parameter.
OR
Create a simple class containing only JS as a variable, then call fromJSON with that class passed as the second parameter of fromJSON like this:
Java
class Foo {
JS JS;
}
jsObject = gson.fromJson(sb.toString(), Foo.class);

Java , How can I pass a tree form output in a data collection type?

How can I pass the output of a method which has multiple level from one class to another in Java . Is there anything which can hold a "tree-like" data apart from tree itself?
for example : if I want to return String data type , the method will be like :
private String method () {
return string; }
What kind of datatype can i use if I want to return an output like the following ?
enter code here
:Thing
:ValuePartition
:Spiciness
:Medium
:DomainConcept
:Food
:IceCream
:Pizza
:NamedPizza
:Mushroom
:AmericanHot
:Caprina
:Margherita
:MeatyPizza
:NonVegetarianPizza
You can use JSON: http://json.org/java/
Your function can return a String (Serialized JSON) or a JSONObject Type.
You JSONObject or String would look something like this.
{
Thing : {
ValuePartition : '',
Spiciness : 'medium',
DomainConcept : '',
Food : ['IceCream','Pizza']
}
}

Categories

Resources