Web服务就是让你的web应用提供一套web API,通常用SOAP 或 REST来实现。 .
REST就本身而言不是一种技术,而是一种架构模式。is not really a technology in itself, but more an architectural pattern. REST非常简单,以普通XML或JSON作为通信机制,结合可以表现底层系统状态的URL形式和 HTTP方法如 GET, PUT, POST和 DELETE.
每一个HTTP方法映射到一个action,如用GET方法获取数据,用PUT方法创建数据,用POST更新数据等等。在这个意义上 REST非常适合 CRUD.
要用Grails实现REST,第一步就是提供REST形式的URL映射 URL映射:
static mappings = { "/product/$id?"(resource:"product") }
这就将URI /product
映射到 ProductController
. 在controller内部每个HTTP方法,GET,PUT,POST和DELETE都映射到一个action上,如下表所示:
GET |
show |
PUT |
update |
POST |
save |
DELETE |
delete |
可以通过URL映射机制修改HTTP方法和URL的映射关系:
"/product/$id"(controller:"product"){ action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"] }
但是在这个例子中,Grails并不像前面使用过的resource
参数那样自动提供XML或JSON序列化,除非提供在URL映射中提供parseRequest
参数:
"/product/$id"(controller:"product", parseRequest:true){ action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"] }
controller可通过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 } } .. }
这里,如果参数中指定id,通过id
搜索Product
如果指定id的Product存在,则返回该Product,否则返回所有Product. 这样,如果访问 /products
我们会得到所有的Product,如果访问/product/MacBook
,我们只获取到一个MacBook记录.
为支持PUT
和 POST
你可以使用 params 对象。Grails中params对象具有读取XML数据包的能力。如下面的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 { render p.errors } }
在这个例子中,通过提取 params
对象中的 'product'
对应的值,我们可以通过Product
的构建器自动创建和绑定XML数据 。 注意这一行:
def p = new Product(params['product'])
这里我们不需要修改任何代码就可以以处理XML数据请求的方法处理表单提交。同样的方法也可以用来处理JSON请求.
如果需要对不同的客户端(REST,HTML等)提供不同的响应,你可以使用 content negotation
The Product
object is then saved and rendered as XML, otherwise an error message is produced using Grails' validation capabilities in the form:
<error> <message>The property 'title' of class 'Person' must be specified</message> </error>
Grails通过 XFire 插件来支持SOAP。XFire插件使用流行的XFire SOAP协议栈,它允许你通过特定的expose
属性将Grails的 services 作为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 文档 。
Grails没有直接提供对RSS和Atom的支持. You could construct RSS or ATOM feeds with the render method's XML capability. 可以通过Grails Feeds插件来构建RSS和Atom。改插件使用流行的 ROME 库. 下面是简单使用这个插件的例子:
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 } } } }