实现 POST
接下来您的目标是要插入一个新的 Airport。创建一个如清单 16 所示的名为 simpleAirport.xml 的文件:
清单 16. simpleAirport.xml
<iata>oma</iata>
<name>Eppley Airfield</name>
<city>Omaha</city>
<state>NE</state>
<country>US</country>
<lat>41.3019419</lat>
<lng>-95.8939015</lng>
</airport>
如果资源的 XML 表示是扁平结构(没有深层嵌套元素),而且每一个元素名称都与类中的一个字段名称相对应的话,Grails 就能够直接从 XML 中构造出新类来。XML 文档的根元素是通过 params 寻址的,如清单 17 所示:
清单 17. 响应 HTTP POST
switch(request.method){
case "POST":
def airport = new Airport(params.airport)
if(airport.save()){
response.status = 201 // Created
render airport as XML
}
else{
response.status = 500 //Internal Server Error
render "Could not create new Airport due to errors:\n ${airport.errors}"
}
break
case "GET": //...
case "PUT": //...
case "DELETE": //...
}
}
XML 一定要使用扁平结构,这是因为 params.airport 其实是一个散列(Grails 是在后台将 XML 转换成散列的)。这意味着您在对 Airport 使用命名参数构造函数 — def airport = new Airport(iata:"oma", city:"Omaha", state:"NE")。
要测试新代码,就要使用 cURL 来 POST simpleAirport.xml 文件,如清单 18 所示:
清单 18. 使用 cURL 来发出一个 HTTP POST
@simpleAirport.xml http://localhost:9090/trip/rest/airport
> POST /trip/rest/airport HTTP/1.1
> Content-Type: text/xml
> Content-Length: 176
>
< HTTP/1.1 201 Created
< Content-Type: text/xml; charset=utf-8
<?xml version="1.0" encoding="utf-8"?><airport id="14">
<arrivals>
<null/>
</arrivals>
<city>Omaha</city>
<country>US</country>
<departures>
<null/>
</departures>
<iata>oma</iata>
<lat>41.3019419</lat>
<lng>-95.8939015</lng>
<name>Eppley Airfield</name>
<state>NE</state>
</airport>
如果 XML 比较复杂的话,则需要解析它。例如,还记得您先前定义的自定义 XML 格式么?创建一个名为 newAirport.xml 的文件,如清单 19 所示:
清单 19. newAirport.xml
<official-name>Eppley Airfield</official-name>
<city>Omaha</city>
<state>NE</state>
<country>US</country>
<location latitude="41.3019419" longitude="-95.8939015"/>
</airport>
现在,在 index 操作中,用清单 20 中的代码替代 def airport = new Airport(params.airport) 行:
清单 20. 解析复杂的 XML
airport.iata = request.XML.@iata
airport.name = request.XML."official-name"
airport.city = request.XML.city
airport.state = request.XML.state
airport.country = request.XML.country
airport.lat = request.XML.location.@latitude
airport.lng = request.XML.location.@longitude
request.XML 对象是一个持有原始 XML 的 groovy.util.XmlSlurper。它是根元素,因此您可以通过名称(request.XML.city)来寻找子元素。如果名称是用连字符连接的,或者使用了名称空间,就加上引号(request.XML."official-name")。元素的属性要使用 @ 符号(request.XML.location.@latitude)来访问(参见 参考资料,查看有关 XmlSlurper 的更多信息的链接)。
最后,使用 cURL 来测试它:curl --request POST --header "Content-Type: text/xml" --data @newAirport.xml http://localhost:9090/trip/rest/airport。