The root symptom of our issue is that after switching our project from Grails 2.2.3 to 2.3.11, our jQuery Ajax calls started returning XML instead of JSON.
The code snippets below illustrate how things are configured in our GSP, controllers, and service and show an example of a static data set that is returned as an object (a list of maps containing string pairs of code/name values). The controller returns this list using the withFormat clause to the GSP. In Grails 2.2.3, this was always JSON, but now in 2.3.11, it is XML.
Through experimentation, I found that if I change the order of the JSON and XML lines in the withFormat clause in the controller to put JSON first, then everything works. I do not like the idea of changing every action in every controller to make this work again.
- What changed in Grails 2.3.x to break this existing functionality?
- What can we change with how we are making these calls to get the desired JSON functionality back instead of XML?
- This seems like something that should be able to be configured at the application level and not change every jQuery Ajax call or change every controller action.
myTest.gsp
var fetchData = function () {
$.ajax({
url: "${g.createLink(controller:'myController', action:'myAction')}",
async: true,
type: 'get',
dataType: "json",
success: function (data) {
if (data) {
// Not shown -- Do something useful with the data
}
},
error: function (request, status, error) {
show.alert("Error with the data. \nStatus: " + status + ", \nError: " + error );
}
});
};
MyController.groovy
class MyController {
def myService
...
def myAction() {
def results = myService.myAction()
withFormat {
xml { render results as XML }
json { render results as JSON }
}
}
...
}
MyService.groovy
class MyService {
def myMap = [ AK: 'Alaska', AL:'Alabama', ... , WY:'Wyoming' ]
def myAction() {
def results = []
myMap.each {
def item = [:]
item.code = it.key
item.name = it.value
result.add(item)
}
return results
}
}
Config.groovy
grails.mime.use.accept.header = true
UPDATE:
I have a "fix", but I'm not very happy with it and would welcome alternate answers or explanations as to why this functionality broke between 2.2.3 and 2.3.11.
I changed the order of the JSON and XML types in the withFormat closure in my controller action to put JSON first and the issue is "resolved".
I am not happy with this as it will require me to change all 68 of my actions in all of my controllers. This is introducing a lot of potential risk as other functionality may change with me changing this volume of code all for something that worked fine in a previous version of Grails. Is there something at a global level that I can change to address this?
MyController.groovy
class MyController {
def myService
...
def myAction() {
def results = myService.myAction()
withFormat {
json { render results as JSON } // <-- MOVED THIS TO BE FIRST
xml { render results as XML }
}
}
...
}