技术开发 频道

精通 Grails: RESTful Grails

  实现 POST

  接下来您的目标是要插入一个新的 Airport。创建一个如清单 16 所示的名为 simpleAirport.xml 的文件:

  清单 16. simpleAirport.xml

<airport>
  
<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

def index = {      
  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

$ curl --verbose --request POST --header "Content-Type: text/xml" --data
      @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

<airport iata="oma">
  
<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

def airport = new Airport()
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。

0
相关文章