2013-09-01 31 views
6

對於在此問題中使用的許多概念和技術而言,我相當新穎,因此我希望能夠爲社區初學者提供一點理解和幫助。我正在使用Play Framework 2.1.3版本,並且需要將數據發佈到RESTful Web服務,以便將其插入到遠程數據庫中。將返回一個XML響應,指示成功或失敗。如何使用Play Framework 2.1爲初學者訪問REST風格的Web服務

我確定您知道Play Framework的文檔相當缺乏,對初學者沒有任何幫助,因此我不確定如何通過最佳實踐來完成此任務。我正在尋找針對此問題的Java解決方案,目前我沒有時間學習Scala語言。我對Web服務的經驗相當有限,通常我會在應用程序中實現DAO設計模式(或根據需要使用衆多可用的ORM庫之一),並使用JDBC直接連接到數據庫。這不是一個選項。

我的第一個問題是,是否有推薦的訪問Web服務的設計模式?然後,考慮Play MVC框架,如何最好地實現這樣的設計模式,打包數據(假設應用程序已經捕獲並驗證了用戶的數據),發送它並將響應處理回給用戶?

我知道這是一個相當長的問題,但我的背後的意圖是爲初學者創建一個知識庫,他們可以輕鬆地進入有限的經驗,閱讀,理解和複製他們在這裏找到的工作解決方案。在搜索網頁的時候,我發現了一些不相關的片段,但沒有具體涉及這些技術,也沒有最新的教程。感謝您的時間。

+0

這個職位是非常相似的,雖然不是直線上升複製我相信:http://stackoverflow.com/questions/4379485/restful-on-play-framework - 與此相結合表演!待辦事項列表的例子,這應該給你一個堅實的起點。 – pfairbairn

+0

感謝您的迴應,因爲問題在2010年被問到,我認爲它是指玩遊戲框架版本1,因爲遊戲2僅在2012年發佈。它們絕不相同。然而,我可能是錯的,並且會複查帖子。我更關注這裏的最佳實踐。 – Hegemon

+0

公平點,但是交叉引用該帖子與Java Play 2.1待辦事項列表,http://www.playframework.com/documentation/2.1.x/JavaTodoList,有關路由的信息,使用POST,GET和PUT進行HTTP請求會使該SO帖子看起來很有用,即使它有點過時。 – pfairbairn

回答

11

創建請求很簡單。首先你提供一個URL。有多種方法可將內容類型,查詢參數,超時等添加到請求中。然後你選擇一個請求類型,並可選擇添加一些內容發送。實例:

WSRequestHolder request = WS.url("http://example.com"); 
request.setQueryParameter("page", "1"); 
Promise<Response> promise = request.get(); 
Promise<Response> promise = WS.url("http://example.com").post(content); 

的複雜的部分是發送它,並使用請求的響應。我假設你有一個控制器應該根據Web服務的響應返回一個Result給用戶。結果通常是一個渲染模板或者只是一個狀態碼。

播放通過使用Futures and Promises避免阻止。控制器的async方法採用Promise<Result>,並在稍後的某個點返回結果(未來值)。上面顯示的getpost方法提供了一個簡單易用的承諾。你不需要關心他們的實現,你只需要知道他們承諾一旦請求完成就提供一個Response

注意這裏的問題:當創建與WS.url("...").get()的請求,它會給你一個Promise<Response>即使async需要Promise<Result>。在這裏,您必須自己實現另一個承諾,該承諾將使用map方法將響應轉換爲結果。如果你遵循Play文檔,這看起來有點混亂,因爲Java沒有關閉(但是),並且所有東西都必須包裝在一個類中。不過,您不必在方法調用中使用匿名類。如果你喜歡更簡潔的代碼,你也可以做這樣的:

return async( 
    request     
    .get()     // returns a `Promise<Response>` 
    .map(resultFromResponse) // map takes a `Function<Response, Result>` and 
          // returns the `Promise<Result>` we need 
); 

對象resultFromResponse可能看起來像如下。它實際上就像某種回調方法的繁瑣定義,它只需要Response作爲參數並返回Result

Function<Response, List<T>> resultFromResponse = 
    new Function<Response /* 1st parameter type */, Result /* return type */>() { 
     @Override 
     public Result apply(Response response) { 
      // example: read some json from the response 
      String message = response.asJson().get("message"); 
      Result result = ok(message); 
      return result; 
     } 
    }; 

由於@itsjeyd的意見,當你calling webservices in Play 2.2.x不裹在async調用更多的指出。您只需返回Promise<Result>

public static Promise<Result> index() { 
    return request.get().map(resultFromResponse); 
} 
+1

感謝您的深入響應,儘管大部分內容都可以在Play網站上找到,但您已經設法清除所有混淆。我會試一試。 – Hegemon

+1

+1爲一個偉大的答案。 @Hegemon既然你希望這成爲「各種知識庫」,我想補充一點,就是玩! 2.2.x,通過'async'返回'Result's已被棄用;調用其他Web服務的操作應該返回'Promise '而不是。這可以通過將上面的'return'語句改爲'return request.get()。map(resultFromResponse);'來實現。 – itsjeyd