如果这是一个重复的问题,请原谅我。我已经通过一些类似要求的问题/答案,但不知何故有点不知所措和混淆同时。我的要求是:
这是我的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"
}
问题:
如何从请求中检索整个JSON字符串? request.JSON在这里可以吗?如果是这样,request.JSON.timesheetJSON会产生我想要作为JSONObject的实际JSON吗?
解析我从请求中获取的JSON对象的最佳方法是什么?是grails.converters.JSON吗?或者还有其他简单的解析方法吗?像一些API一样,它会通过自动处理解析将JSON作为对象集合返回。或者以唯一的方式以编程方式解析JSON对象?
就像我说的那样,如果这个问题听起来很模糊,请原谅我。任何好的引用JSON解析与grails在这里也可能会有所帮助。
编辑:我现在获得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字符串。
答案 0 :(得分:4)
我已经写了一些代码来解释如何做到这一点,你可以在下面看到,但要清楚,首先要回答你的问题:
您上面写的JSON字符串将是POST有效负载到其余控制器的内容。 Grails将使用其数据绑定机制将incomming数据绑定到您应该准备的Command对象。它必须具有与JSON字符串中的参数对应的字段(参见下文)。将命令对象绑定到实际域对象后,只需操作字段和列表即可获得所需的所有数据
通过JSON对象解析的方法如下面的示例所示。进入请求实际上是一个嵌套的地图,只需用点来访问
现在有一些代码说明了如何做到这一点。 在你的控制器中创建一个接受"你的命令" object作为输入参数:
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)
}
}
}
它&#34; bindTo&#34; method是理解如何从incomming请求获取参数并将其映射到常规对象的关键逻辑。该对象属于&#34; YourClass&#34;它看起来像这样:
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
但你显然在你的代码中已正确使用它,否则它将无法正常工作,那么与&#34; println&#34;的那一行相同:
jsonArray1.size()
shuold be:
jsonArray.size()
和基本修复:
def object1 = jsonArray[1]
shuold be
def object1 = jsonArray[0]
你的数组大小== 1,索引从0开始.//它可以那么容易吗? ;)
然后&#34; object1&#34;又是一个JSONObject,因此您可以使用&#34;。&#34;来访问这些字段。或者作为地图,例如: object1.get(&#39; periodEnd&#39)
答案 1 :(得分: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]