(CRUD Name) = (HTTP Method Name) = (Grails Action Name)
- CREATE = POST = save
- READ = GET = show
- UPDATE = PUT = update
- DELETE = DELETE = delete
一般來說,GET 或 POST 的網址參數(GET params)與表單參數(BODY params),都可以在 Grails 用 params 物件取得參數值,例如:
name = params.name
password = params.password
但是遇到 PUT 方法 + 表單資料送出時,可能導致無法直接使用 params 取得表單資料。例如:
PUT http://localhost:8080/test1/rest/testPut
在一般使用 GET 或 POST 方法存取遠端資源時,HTTP Request 的 Content-Type 是 application/x-www-form-urlencoded 型態,所以附加的表單資料是 Form Data 方式處理。
但是在使用 PUT 方法的情況下,就必須改變 HTTP Request 的內容型態(Content-Type)。
利用 PUT 送出資料一般有兩種作法:XML 或 JSON。所以對應的 Content-Type 也必須先正確設定,然後附帶正確格式的資料。
例如使用 JSON 格式時,HTTP Request 的 Header 內容就會變更成以下:
可以看到兩個主要的差異:(1) Content-Type 變成 application/json 以及 (2) Form Data 變成 Request Payload。
這種作法是在 PUT 方法下,將表單資料先轉成 JSON 或 XML 格式,然後再以附帶資料方式送出給伺服器。
因為一般瀏覽器要測試 PUT 方法並不容易,可利用 Groovy 的 HttpBuilder 快速撰寫一個小型的測試代碼,專用於 PUT method 的測試:
在伺服器端接收資料時,也必須針對內容加以解析(搭配 JSON 或 XML Parser)。
以 Grails 為例,可以使用 request.JSON 或 request.XML 來取得解析後的資料。先在 grails-app/config/UrlMappings.groovy 加入 parseRequest: true 的設定。
"/$controller/$action?/$id?"(parseRequest: true) { ... }
在瞭解 PUT 方法必須搭配 JSON 或 XML 傳遞資料後,就可以調整 Ext JS 的表單設計。
先以一段 Ext JS 的小程式,搭配 Ext.Ajax.request 方法,測試 Ext JS 對 PUT 方法的支援機制:
Ext.Ajax.request({
method: 'PUT',
url: 'http://localhost:8080/test1/rest/testPut',
success: function() {
alert("ok");
},
failure: function() {
alert("no");
},
params: { a: 1, b: 2, c: 3 }
});
上面的程式碼中,使用 params 來傳送表單資料,這在 GET 與 POST 方法是管用的,但是遇到 PUT 就無法正確將資料傳遞給後端程式。
將 params 改用 jsonData 之後,就可以正確運作:
Ext.Ajax.request({
method: 'PUT',
url: 'http://localhost:8080/test1/rest/testPut',
success: function() {
alert("ok");
},
failure: function() {
alert("shit");
},
jsonData: { a: 1, b: 2, c: 3 }
});
使用 jsonData 來傳遞表單資料,會使 Ext JS 正確送出 PUT 需要搭配的 Content-Type: application/json 的 HTTP Header,並使用 Request Payload 的方式附加資料。如此一來 Server 端程式就能收到 JSON 格式資料。
但是在 Ext JS 表單中,預設是以 params 來傳遞資料,即使將 method 設定成 PUT 也是一樣。
在 Ext.form.Panel 具有一個隱藏版的參數:
jsonSubmit: true
開啟這個設定,就能促使表單在 submit() 函數呼叫時,改以 jsonData 取代 params 正確送出表單資料。
以下是一個經過驗證可行的 Ext JS 範例代碼,可以測試其中 jsonSubmit: true 設定的作用。
Ext.create('Ext.form.Panel', {
title: 'Simple Form',
jsonSubmit: true,
bodyPadding: 5,
width: 350,
// The form will submit an AJAX request to this URL when submitted
url: 'http://localhost:8080/test1/rest/testPut',
// Fields will be arranged vertically, stretched to full width
layout: 'anchor',
defaults: {
anchor: '100%'
},
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'a',
allowBlank: false
},{
fieldLabel: 'Last Name',
name: 'b',
allowBlank: false
}],
// Reset and Submit buttons
buttons: [{
text: 'Reset',
handler: function() {
this.up('form').getForm().reset();
}
}, {
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function() {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({
method: 'PUT',
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
}
}
}],
renderTo: Ext.getBody()
});
延伸閱讀
- http://stackoverflow.com/questions/7195872/request-params-and-put-method
- https://github.com/krasserm/grails-jaxrs/wiki/Getting-Started
- http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.form.Panel
- http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.form.Basic-cfg-jsonSubmit
- http://grails.org/doc/latest/guide/webServices.html
Ext JS 教學內容由思創軟體提供,共同作者 @lyhcode 與 @smlsun 目前在校園及企業從事 JavaScript(含 Node.js, Ext JS)與 Java(含 Groovy, Grails, Gradle) 教育訓練及顧問工作。
沒有留言:
張貼留言