Grails:从请求解析JSON的简便有效方法

问题描述 投票:2回答:2

如果这是重复的问题,请原谅我。我经历了一些要求类似的问题/答案,但同时又有点不知所措和困惑。我的要求是:

  • 我得到一个JSON字符串/对象作为请求参数。 (例如:params.timesheetJSON)
  • 然后我必须解析/迭代它。

这是我的grails控制器将接收的JSON:

{
    "loginName":"user1",
    "timesheetList":
    [
        {
            "periodBegin":"2014/10/12",
            "periodEnd":"2014/10/18",
            "timesheetRows":[
                {
                    "task":"Cleaning",
                    "description":"cleaning description",
                    "paycode":"payCode1"
                },
                {
                    "task":"painting",
                    "activityDescription":"painting description",
                    "paycode":"payCode2"
                }
            ]
        }
    ],
    "overallStatus":"SUCCESS"
}

问题:

  1. 我如何从请求中检索整个JSON字符串? request.JSON在这里可以吗?如果是这样,request.JSON.timesheetJSON是否会向我产生我想要作为JSONObject的实际JSON?

  2. 解析从请求中获得的JSON对象的最佳方法是什么?是grails.converters.JSON吗?还是有其他简单的解析方法?就像某些API一样,它将通过自动处理解析来将JSON作为对象的集合返回。还是以编程方式仅通过JSON对象解析?

[就像我说的,如果问题听起来含糊,请原谅我。任何使用grails进行JSON解析的良好参考在这里也可能会有帮助。

Edit:现在获取JSON字符串的方式有所变化。我将JSON字符串作为请求参数。

String saveJSON // This holds the above JSON string.

def jsonObject = grails.converters.JSON.parse(saveJSON) // No problem here. Returns a JSONObject. I checked the class type.
def jsonArray = jsonArray.timesheetList // No problem here. Returns a JSONArray. I checked the class type.
println "*** Size of jsonArray1: " + jsonArray1.size() // Returns size 1. It seemed fine as the above JSON string had only one timesheet in timesheetList

def object1 = jsonArray[1] // This throws the JSONException, JSONArray[1] not found. I tried jsonArray.getJSONObject(1) and that throws the same exception.

基本上,我现在想无缝遍历JSON字符串。

json grails grails-plugin
2个回答
4
投票

我写了一些代码,解释了如何做到这一点,您可以在下面看到,但要清楚,首先要解决您的问题:

  1. 您上面编写的JSON字符串将是REST负载中POST负载的内容。 Grails将使用其数据绑定机制将传入的数据绑定到您应准备的Command对象。它必须具有与JSON字符串中的参数相对应的字段(请参见下文)。将命令对象绑定到实际的域对象后,只需对字段和列表进行操作即可获得所需的所有数据。

  2. 通过JSON对象解析的方式在下面的示例中显示。传入的请求本质上是一个嵌套的地图,可以简单地通过一个点进行访问]]

  3. 现在提供一些说明如何执行此操作的代码。在您的控制器中,创建一个接受“ YourCommand”对象作为输入参数的方法:

    def yourRestServiceMethod (YourCommand comm){
        YourClass yourClass = new YourClass()
        comm.bindTo(yourClass)
    
        // do something with yourClass
        // println yourClass.timeSheetList
    }
    

    命令如下所示:

class YourCommand {
    String loginName
    List<Map> timesheetList = []
    String overallStatus

    void bindTo(YourClass yourClass){
        yourClass.loginName=loginName
        yourClass.overallStatus=overallStatus
        timesheetList.each { sheet ->
            TimeSheet timeSheet = new TimeSheet()
            timeSheet.periodBegin = sheet.periodBegin
            timeSheet.periodEnd = sheet.periodEnd
            sheet.timesheetRows.each { row ->
                TimeSheetRow timeSheetRow = new TimeSheetRow()
                timeSheetRow.task = row.task
                timeSheetRow.description = row.description
                timeSheetRow.paycode = row.paycode
                timeSheet.timesheetRows.add(timeSheetRow)
            }

            yourClass.timeSheetList.add(timeSheet)
        }
    }
}

其“ bindTo”方法是逻辑的关键部分,它了解如何从传入的请求中获取参数并将其映射到常规对象。该对象的类型为“ YourClass”,看起来像这样:

class YourClass {
    String loginName
    Collection<TimeSheet> timeSheetList = []
    String overallStatus
}

属于该类的所有其他类:

class TimeSheet {
    String periodBegin
    String periodEnd
    Collection<TimeSheetRow> timesheetRows = []
}

和最后一个:

class TimeSheetRow {
    String task
    String description
    String paycode
}

希望此示例对您足够清楚,可以回答您的问题

编辑:根据新要求扩展答案

查看您的新代码,我发现您撰写该帖子时可能输入了错字

def jsonArray = jsonArray.timesheetList

应该是:

def jsonArray = jsonObject.timesheetList

但是您显然在代码中正确地使用了它,因为否则它将无法正常工作,然后与“ println”的那一行相同:

jsonArray1.size()

应该是:

jsonArray.size()

和基本修正:

def object1 = jsonArray[1]

shuold be

def object1 = jsonArray[0]  

您的数组大小为== 1,索引从0开始。//可以那么容易吗? ;)

然后“ object1”还是一个JSONObject,因此您可以使用“。”来访问字段。或作为地图,例如: object1.get('periodEnd')

我看到您的示例包含错误,这使您实现了更复杂的JSON解析解决方案。我将您的示例重写为工作版本。 (至少现在针对Grails 3.x)

String saveJSON // This holds the above JSON string.

def jsonObject = grails.converters.JSON.parse(saveJSON) 
println jsonObject.timesheetList // output timesheetList structure

println jsonObject.timesheetList[0].timesheetRows[1] // output second element of timesheetRows array: [paycode:payCode2, task:painting, activityDescription:painting description]
    

0
投票

我看到您的示例包含错误,这使您实现了更复杂的JSON解析解决方案。我将您的示例重写为工作版本。 (至少现在针对Grails 3.x)

String saveJSON // This holds the above JSON string.

def jsonObject = grails.converters.JSON.parse(saveJSON) 
println jsonObject.timesheetList // output timesheetList structure

println jsonObject.timesheetList[0].timesheetRows[1] // output second element of timesheetRows array: [paycode:payCode2, task:painting, activityDescription:painting description]
    
© www.soinside.com 2019 - 2024. All rights reserved.