1

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 }
        }
    }
    ...        
}
3
  • Can you inspect Request and see what kind of response are you receiving, It looks you are receiving xml response instead of json response. Please confirm the same. Commented Mar 18, 2016 at 0:00
  • Yes. We are getting back XML now and not JSON, but I'm not sure what changed between 2.2.3 and 2.3.11 to cause this or how to get it working again. Commented Mar 18, 2016 at 0:13
  • Can you give us the Accept Header of Ajax Request ? Also try setting the Accept header to application/json. Check here stackoverflow.com/questions/1145588/… Commented Mar 18, 2016 at 0:33

1 Answer 1

2

Based on this article (http://mrhaki.blogspot.com/2014/07/grails-goodness-enable-accept-header.html) regarding accept headers, I added the following line to my Config.groovy and it corrected my issue.

Config.groovy

grails.mime.use.accept.header = true
grails.mime.disable.accept.header.userAgents = [] // <-- Added this line
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.