當這套 REST API 不能滿足使用者的需求時,需要增加新的 REST Web Service。 本文將介紹如何在不修改現有代碼的前提下,向 IBM HTTP://www.aliyun.com/zixun/aggregation/13696.html">SmartCloud Entry 中添加定制的 REST Web Service。
IBM SmartCloud Entry 並非從一磚一瓦開始構造自己的 REST Web Service,而是借助了一些工具。 在正式開始之前,您需要對下列名詞有一定的瞭解。
REST: 全稱是 Representational state transfer。 它是一種 Web 服務的 風格,與作為傳統 Web 服務(以 SOAP 為基礎)相比,具有輕量化、易於構建、無狀態以及使用 HTTP 協定等優勢。 JAX-RS:全稱是JAVA TM API for RESTful Web Services,是一個 JAVA 程式設計語言的應用程式介面。 它提供了對創建 REST 風格的 Web Service 的支援。 借助從 JAVA SE 5 開始引入的標注(Annotation ),JAX-RS 可以簡化部署 Web Service 的過程。 Restlet:誕生於 2005 年,是一個針對 JAVA 語言開發人員的開源專案。 Restlet 旨在以一種簡單的方式,向開發人員提供各個應用場景下實現 REST Web Service 的方法。 雖然早在 JAX-RS 誕生前,Restlet 已經存在了,但是 Restlet 仍然提供了對 JAX-RS 的支援。 目前 Restlet 的最新穩定版本是 2.1.1,本文的所有內容都是基於 Restlet 2.1.1 來進行說明。 OSGi:全稱是 Open Services Gateway initiative,一直都被視為一種成熟的模組化系統框架,它一般包括桌面應用程式、Web 應用程式、移動應用程式,以及中介軟體。 它提供了一種底層的基礎設施,可用來開發具有模組化、動態性的面向服務應用程式。
Restlet 實現 JAX-RS
在 Restlet 2.1.1 中,可以將 Restlet 分成兩個部分:
REST 應用開發 Core:包含 Restlet API 和 Restlet Engine Extension:包含 Restlet 對支援各個技術的擴展,如 Servlet 和 JAX-RS
如果您對 Restlet 稍有了解,可以知道僅靠 Restlet 的 Core 部分就能夠實現 REST Web API。 而 IBM SmartCloud Entry 則用 JAX-RS 來定義 REST 資源,之後借助 Restlet 對 JAX-RS 的擴展來關聯 Restlet Engine 和 REST 資源,從而實現 REST Web API。 對於這兩種方式的優劣,在這裡不做贅述,您可以從網上找到說明。 接下來將簡要介紹 IBM SmartCloud Entry 的實現方式。
清單 1. 將 JAX-RS application 與 Restlet 關聯
package com.developerworks.rest.test;import org.restlet.Component;import org.restlet.ext.jaxrs.JaxRsApplication;import javax.ws.rs.core.Application;public class TestComponent extends Component { public static Application jaxRsApplication; public TestComponent() { super(); // 創造 JAX-RS runtime final JaxRs Application application = new JaxRsApplication(getCoNtext().createChildCoNtext()); 將一個 JAX-RS application 添加到 JAX-RS runtime application.add(jaxRsApplication); 將 JAX-RS runtime 必須添加到一個 Component 中 getDefaultHost().attach(application); }}
清單 1 展示了如何用 Restlet 對 JAX-RS 的擴展來關聯 Restlet 和 JAX-RS application。
將 REST Web API 部署到 Servlet 容器中
IBM SmartCloud Entry 是以 OSGi 為核心框架開構建的,所使用的 Servlet 容器是 OSGi 內嵌的 Jetty。 清單 2 展示了如何將一個 Restlet Component 部署到 Servlet 容器中,這裡我們用到了 Restlet 對 Servlet 的擴展。
清單 2. 將 Restlet Component 部署到 Servlet 容器中
package com.developerworks.rest.test;import java.util.Properties;import javax.ws.rs.ext.RuntimeDelegate;import org.osgi.service.HTTP.HttpCoNtext;import org.osgi.service.HTTP.HttpService;import org.restlet.engine.Engine; import org.restlet.ext.jaxrs.internal.spi.RuntimeDelegateImpl;import org.restlet.ext.servlet.ServerServlet; public class TestApiWhiteboard { static { Engine.getInstance().setUserClassLoader(TestComponent.class.getClassLoader ()); } private HttpService HTTP; 調用該函數啟動 REST Web Service public void startup() { ServerServlet serverServlet = new ServerServlet(); Properties initParams = new Properties(); initParams.put("org.restlet.component", TestComponent.class.getName()); HttpCoNtext HTTPCoNtext = HTTP.createDefaultHttpCoNtext(); try { HTTP.registerServlet("/test", serverServlet, initParams, HTTPCoNtext); } catch (Exception e) { e.printStackTrace(); } } public void shutdown() { HTTP.unregister("/test"); }}
清單 2 將之前實現的 Component 作為參數傳遞給 ServerServlet,再將 ServerServlet 註冊進 Servlet 容器。 至此,我們已經能夠發佈 REST Web Service 了,但是等等,我們的 Web Service 空空如也,我們還沒有添加 REST 資源。