Web服务是指在Web程序中提供Web的应用程序接口(API),它有SOAP和REST两种典型的实现方式。
REST
REST并不是一个独立成技术,只能说是一种架构模式。REST相当简单,只限于使用XML或JSON纯文本作为传播介质,以及使用URL模式,而这些模式代表底层系统和HTTP方法(比如GET、PUT、POST和DELETE)。
每个HTTP方法都映射到一个行为(action)。例如,GET表示获取数据,PUT表示创建数据,POST表示更新,等等。
这样一来,就让人感觉,REST非常适合CRUD(Create创建+Retrieve获取+Update更新+Delete删除)。
URL模式
Grails实现REST的第一步是提供RESTful的URL映射。
static mappings = { "/product/$id?"(controller:"product"){ action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"] } }
这里我们使用URL映射的能力,映射到HTTP方法,从而给控制器提供RESTful的API。每个HTTP方法(比如GET、PUT、POST、DELETE)都映射到控制器中唯一的行为。
XML编组(Marshal)——只读方法
控制器实现本身可以使用Grails的XML编组功能,来实现GET方法:
import grails.converters.* class ProductController { def show = { if(params.id && Product.exists(params.id)) { def p = Product.findByName(params.id) render p as XML } else { def all = Product.list() render all as XML } } .. }
我们在这里做的是:如果我们通过name搜索到了一个产品,那么就返回这个产品;否则返回所有产品。这样,如果我们访问/products,就可以获取所有产品,或者访问/product/MacBook,那我们就可以得到一个产品MacBook。
XML编组——更新方法
Grails能够读取传入的XML包,来加强params对象。你可以使用这些params对象,从而支持更新方法(比如PUT和POST)。假设传入的XML包如下:
<?xml version="1.0" encoding="ISO-8859-1"?> <product> <name>MacBook</name> <vendor id="12"> <name>Apple</name> </vender> </product>
你可以使用《数据绑定》章节讲到的相同技术,通过params对象来读取XML包。
def save = {
def p = new Product(params['product'])
if(p.save()) { render p as XML } else { def errors = p.errors.allErrors.collect { g.message(error:it) } render(contentType:"text/xml") { error { for(err in errors) { message(error:err) } } } } }
本例中,我们使用关键字'product',创建params对象的索引,从而能够使用Product类的构造器,来创建和绑定XML。下行有一个有趣之处:def p = new Product(params['product'])
也就是不需要更改代码,就可以用处理XML请求的方式,来处理提交表单数据的提交操作。相同的技术也可以应用于JSON请求。
###如果你需要对不同的客户端(REST、HTML,等等)进行不同的响应,那么就可以使用内容协商(content negotation )###
然后,Product对象被保存,并以XML形式显示(render),否则,就使用Grails的表单中的验证能力,产生错误信息。
<error> <message>The property 'title' of class 'Person' must be specified</message> </error>
Grails可以使用XFire插件实现对SOAP的支持。XFire插件使用谈广受欢迎的XFire SOAP 栈,将SOAP支持集成到Grails中。XFire允许使用专门的expose属性,将Grails服务显示为SOAP服务。
class BookService {
static expose=['xfire']
Book[] getBooks(){ Book.list() as Book[] } }
然后就可以通过以下地址访问WSDL:
http://127.0.0.1:8080/your_grails_app/services/book?wsdl
关于XFire插件的更多信息,请参考wiki中的文档。
RSS和Atom
Grails中并不提供对RSS和Atom的直接支持。你可以使用render方法的XML功能,来构造RSS或ATOM的Feeds。然而,Grails还有一个Feeds插件,使用流行的ROME库,提供RSS和Atom构造器(builder)。这种用法的例子如下:
def feed = { render(feedType:"rss", feedVersion:"2.0") { title = "My test feed" link = "http://your.test.server/yourController/feed"
Article.list().each() { entry(it.title) { link = "http://your.test.server/article/${it.id}" it.content // return the content } } } }
锐飞人翻译自Grails1.0文档. http://grails1.0api.cn/