Spring REST - String Serialization - bug or feature? - json

I found a very strange behavior in spring rest.
Having an endpoint like the following
#GetMapping("/foo")
public String foo() {
return "bar";
}
returns the value bar. Sounds correct, but this is not a valid json, the effective result should be "bar" (note the ""). One might argue that spring expects that if a method returns a string, you have already manually serialized the object, but if all other objects are serialized by spring, then i would expect to have a special way to tell that its already serialized but the default way should be to serialize the value.
Maybe i'm missing something here, that's the reason why i didn't created a ticket in the spring issue tracker jet.

Unregistering the StringHttpMessageConverter as described in this answer should do the trick: https://stackoverflow.com/a/37906098/505621

While not really an answer, there are 2 possible workarounds:
Encode it yourself
Just add the required quotation mark explicitly to the response string \".
This could for example be done by using JSONObject.quote(yourString).
Wrapping
Wrap your string into a simple object or custom class. Then Jackson knows what to do with it.
Collections.singletonMap("value", yourString);

Related

Unity JSONUtility to JSON list of base classes

I have a BaseClass and bunch of derived classes.
I also have List<BaseClass> that contains objects from those derived classes.
When I do JSONUtility.ToJson(List<BaseClass>) I get only properties of BaseClass and not derived classes.
And well... I guess it is logical, but can't I force it to use derived class if there's a one or JSONUtility isn't capable of it? So I need to write custom logic for that?
Thanks!
Very probably JSONUtility.ToJson(List<BaseClass>) gets the elements you need with reflection, so the object returned is based on the incoming type.
I would try to obtain the jsons one by one and combine them in the logic, pre casting each of the types. Not tested nor debugged, just an starting point idea to move on:
string jsons;
foreach (var baseClass in baseClassList) {
Type specificType = baseClass.GetType();
string jsonString = JsonUtility.ToJson((specificType)baseClass)
jsons = "[" + string.Join(",", jsonstring) + "]";
}
I faced the same issue, to be honest JsonUtility is not good option for working with List.
My recommendations:
Use array instead of list with this helper class
or Newtonsoft Json Unity Package
I also needed JSON serialization, to call a REST json API, and I suggest to avoid JSONUtility.
It doesn't handle lists or dictionaries, as you saw.
Also it cannot serialize properties defined with { get; set; }, only fields, which is not blocking but not very convenient.
I agree with the recommendation above, just use Newtonsoft. It can serialize anything, and you will also benefit of the Serialization Settings (you can for example setup the contract resolver to convert all property names to snake_case...). See https://www.newtonsoft.com/json/help/html/SerializationSettings.htm

Json object with backslash, gson serialization

I want to convert a java object to json object with string format*. I am using gson library. Is there any way to do that.
(I am not sure if it is the correct name for this structure) json object with string format:
*
{ [\"name\":\"Ajay\",\"age\":30,\"email\":\"ajay#ajay.com\"]}
I'm pretty sure gson itself can't handle this, but you can. Given string s looking like
{ [\"name\":\"Ajay\",\"age\":30,\"email\":\"ajay#ajay.com\"]}
you only need to call gson on s.replace("\\\"", "\""). Simply clean up you string, so it looks like it should (your quotation marks look differently, maybe you need to fix it, too).
This may be too abstruse, but if you create a JSON string (through GSON or another library like JSON.org) and GSON-serialize that string, you will get the backslashes. This has been an irritation for me, but it would work for your case, with more code than the replace but safer if backslashes are otherwise valid in your JSON.

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 ;)

Switch off UTF escaping in JsonBuilder

I'm trying to use JsonBuilder in groovy servlet (extending HttpServlet)
Here is a snippet:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
response.setContentType('text/plain')
response.setCharacterEncoding('utf-8')
def pw = response.getWriter()
pw.println(new JsonBuilder(['city': 'Москва']))
pw.println([сity: 'Москва'])
}
The output is
{"city":"\u041C\u043E\u0441\u043A\u0432\u0430"}
{сity=Москва}
I just don't know nothing about UTF escaping in JsonBuilder, googling also did not give my anything valuable. So I guess I'm stuck.
Does anybody know how to get the output for json exactly in same form as we get the output for regular groovy object?
I have encountered the same issue, and the above methods didn't work.
However this did:
http://groovy.codehaus.org/gapi/groovy/json/StringEscapeUtils.html
StringEscapeUtils.unescapeJavaScript(JsonOutput.toJson('Москва'))
As far as JavaScript and/or JSON goes, it is the exact same output.
You can easily confirm this yourself:
'Москва' == '\u041c\u043e\u0441\u043a\u0432\u0430'; // true
What you're seeing are Unicode string escape sequences, which are defined by the ECMAScript specification (JavaScript) and are allowed in JSON as well.
That said, I wouldn't worry about it too much, but if you insist on disabling the string escapes, you can use the JsonOutput object:
JsonOutput.prettyPrint(json.toString());
I've found it, I've found it.
So if you are as stubborn as me and don't want to recognize that (in a very wide range of applications) escaped sequence is exactly the same as non-escape, you can just use JsonOuput object, which is in the same standard package, groovy.xml.*:
JsonOutput.prettyPrint(json.toString())
If somebody's answer will be more detailed, I will delete my own answer and will mark the other answer as accepted. So I encourage you )))

Removing an entry from a GWT JSONObject

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.