Closed deusprogrammer closed 9 years ago
what you see is expected with the current release version using spring-4.0 underneath.
from your description, i guess you are sending a String
like brokerMessagingTemplate.convertAndSend("someString")
.
to get the value in your js, try using JSON.parse(message.body)
, just like you would do if you send an Object
like brokerMessagingTemplate.convertAndSend(myPlainObjectInstance)
.
note: that behavior will change with grails-2.5/grails-3.0 shipping spring-4.1+. from that spring version on, plain String
payloads will not be json-encoded anymore, meaning then the message.body
in your js code will have the string value someString
without double quoting.
hth, zyro
Thanks for the reply. Originally I was trying to pass one of my domain objects back, but that was causing an error, so I attempted to pass it back using
(object as JSON).toString()
And then the subscriber can't parse the JSON because of the added quotes.
Sent from my iPhone
On Jan 20, 2015, at 1:45 PM, zyro notifications@github.com wrote:
what you see is expected with the current release version using spring-4.0 underneath. from your description, i guess you are sending a String like brokerMessagingTemplate.convertAndSend("someString"). to get the value in your js, try using JSON.parse(message.body), just like you would do if you send an Object like brokerMessagingTemplate.convertAndSend(myPlainObjectInstance).
note: that behavior will change with grails-2.5/grails-3.0 shipping spring-4.1+. from that spring version on, plain String payloads will not be json-encoded anymore, meaning then the message.body in your js code will have the string value someString without double quoting.
hth, zyro
— Reply to this email directly or view it on GitHub.
does that mean you got it sorted for now like var obj = JSON.parse(JSON.parse(message.body))
?
Well...no =(. The client is an iOS app.
In any case, I have tried to get it to serialize a GORM domain object in convertAndSend, but it throws an exception. It also throws and exception when I attempt to pass it a POJO. Do I need to go annotate it with Jackson JSON annotations?
The exception is as follows:
No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.LinkedHashMap["payload"]->com.trinary.survey.ContestEntry["errors"]->grails.validation.ValidationErrors["messageCodesResolver"]).
The GORM objects have those validation entries in them...which seems to be giving the serializer problems.
ok very good you located the problem. so two options:
or, perhaps preferred:
brokerMessagingTemplate.convertAndSend((myDomainObject as JSON).toString())
var myJsObject = JSON.parse(JSON.parse(message.body));
alert(myJsObject.myProperty);
I'm finding the docs very hard to understand on the topic of configuring Jackson to support my domain properties. I haven't been able to get Jackson annotations to work on domain classes because Jackson isn't aware of all the grails stuff. Do you know of any good examples (in the context of a Grails app?)
For now I'm using the later option you mention, but I think the former would be better long-term.
The only problem with the second solution is that I'm not using JS as the client. I am using Android and iOS STOMP Clients.
@kastork for now, id suggest you stick with grails json serialization. as i said, once we move on to spring 4.1, one JSON.parse
will go away because then, String
payloads are sent as-is.
im not yet sure what the best solution is in the end, too. wether to write spring messageconverters that are aware of grails json impl. or to use jackson to serialize the grails classes. but that one may prove tricky as you mentioned. however, each way means more infrastructure being added to the plugin and im a bit reluctant to do that right now given grails3 is peeking around the corner.
once a grails3 milestone/rc working with spring-websocket plugin is out, ill revisit this topic and hopefully arrive at a solution worth some readme notes ;)
@deusprogrammer not sure i get the problem there. independent of the stomp impl, you always just get the message.body as String
, no? i mean except you are doing sth. with binary streaming or so...
that would mean you got to have a json lib handy anyway to get objects out of the payload? and does calling that deserialization two times (again as long we are speaking spring 4.0..) pose a problem?
In Swift, deserialization fails the first time using their built in JSON deserializer. So, no...sadly it's not an acceptable solution. Not your fault though. Still an awesome plugin.
On Tue, Feb 24, 2015 at 2:21 PM, zyro notifications@github.com wrote:
@kastork https://github.com/kastork for now, id suggest you stick with grails json serialization. as i said, once we move on to spring 4.1, one JSON.parse will go away because then, String payloads are sent as-is. im not yet sure what the best solution is in the end, too. wether to write spring messageconverters that are aware of grails json impl. or to use jackson to serialize the grails classes. but that one may prove tricky as you mentioned. however, each way means more infrastructure being added to the plugin and im a bit reluctant to do that right now given grails3 is peeking around the corner. once a grails3 milestone/rc working with spring-websocket plugin is out, ill revisit this topic and hopefully arrive at a solution worth some readme notes ;)
@deusprogrammer https://github.com/deusprogrammer not sure i get the problem there. independent of the stomp impl, you always just get the message.body as String, no? i mean except you are doing sth. with binary streaming or so... that would mean you got to have a json lib handy anyway to get objects out of the payload? and does calling that deserialization two times (again as long we are speaking spring 4.0..) pose a problem?
— Reply to this email directly or view it on GitHub https://github.com/zyro23/grails-spring-websocket/issues/20#issuecomment-75837625 .
2.0.0.M1 is release working together with grails-3.0.0.m2. no more double escaping for String payloads happening there. sadly no support for the grails-2.4.x line here. ok for you guys if i close this one?
Awesome! Works for me. My project is still in it's infancy anyways, so I can easily upgrade it to Grails 3.0
Thanks!
On Fri, Feb 27, 2015 at 9:27 AM, zyro notifications@github.com wrote:
2.0.0.M1 is release working together with grails-3.0.0.m2. no more double escaping for String payloads happening there. sadly no support for the grails-2.4.x line here. ok for you guys if i close this one?
— Reply to this email directly or view it on GitHub https://github.com/zyro23/grails-spring-websocket/issues/20#issuecomment-76411781 .
I'm seeing this issue after upgrading to Grails 3.1 (regardless of whether I use spring-websocket 2.1.0 or 2.3.0). The message body is coming through as a string with escaped quote marks, which breaks the JSON.parse()
call on the front-end.
In Grails 3.0.x, I get this on the client-side (using Stomp/SockJs): [{ "key": "value" }]
In 3.1.1, I get: [{ \"key\": \"value\" }]
Okay, I got this working again, but it wasn't very straightforward. Here's the rundown:
In my 3.0.9 app, I would push JSON over web sockets like so:
brokerMessagingTemplate.convertAndSend "/topic/data", json.toString()
... where json
is an instance of JsonBuilder
that I've used to convert my Groovy HashMap
to JSON
.
Then in my JS client app, I could parse the data like so:
JSON.parse(message.body)
After upgrading to 3.1.1, my JSON string was being escaped as detailed above. Here's how I worked around it:
toString()
from my convertAndSend
call: brokerMessagingTemplate.convertAndSend "/topic/data", json
["content": [{ "key": "value" }]]
. So in order to get the same data as I had in 3.0.9, my code on the front-end had to change to this: JSON.parse(message.body).content
I'm assuming something in the underlying Spring websocket implementation changed, and I'm trying to track down what exactly. This code I have works fine, but I'm a bit uneasy with it, if only because it doesn't really follow the documentation I had been following before.
please note that the cause for the behavior is an issue in spring-boot that got fixed in the meantime (spring-boot-1.3.3) but grails is currently still using spring-boot-1.3.2. so keep in mind that with the next grails upgrade, your JSON.parse(message.body)
, may become unnecessary again. for the root cause and other (more general) types of fixes please see:
I don't know if this is the way this is supposed to work in STOMP, but my JSON string is being returned quoted and escaped =/