Liferay6.2:Registering JSON Web Services - 註冊JSON WebService
文章目錄
Registering JSON Web Services - 註冊JSON WebService
Liferay的開發人員使用名為Service Builder的工具來構建服務。 使用Service Builder構建服務時,所有被啟用的遠端服務(即service.xml中具有屬性remote-service ="true"的實體)都將公開為JSON Web service。 為remote-enabled service建立每個*Service.java介面時,會在該介面的類級別上新增@JSONWebService 註解。 該介面的所有公共方法都會被註冊並可用作JSON Web service。
Service.java介面原始檔不能直接修改。 如果需要對其方法進行更多控制(例如,如果需要在暴露一些方法時隱藏某些方法),可以配置ServiceImpl類。 當使用@JSONWebService註解對服務實現類(*ServiceImpl)進行修飾時,將忽略service介面,並在其位置使用serviceImpl類進行配置。 換句話說,serviceImpl中的@JSONWebService註解會覆蓋service介面中的任何JSON Web service配置。
當啟動Liferay Portal時,它會掃描service類以獲取註解。 使用@JSONWebService註解修飾的每個類將會被檢查,並通過JSON Web services API公開其方法。 如前所述,ServiceImpl配置會在註冊期間覆蓋
但是,Liferay Portal不會掃描註解修飾的所有可用類。 相反,它只掃描services。 更確切地說,它掃描在portal(入口網站)的application context中註冊的所有類,包括plugin類。也就是掃描BeanLocator可用的所有類。 實際上,portal會掃描在其Spring context中註冊的所有類以及其外掛的Spring context。 如果使用Service Builder構建外掛服務,則service會自動註冊到Spring context,並提供給BeanLocator使用。 這也意味著你可以在plugin的Spring context中註冊任何物件,portal會掃描它以獲取遠端服務! Liferay不強迫使用Service Builder。
現在開始學習如何將plugin的遠端服務註冊為JSON Web service。Liferay的開發人員使用相同的機制。 這就是為什麼Liferay Portal的遠端服務(remote service)被公開為JSON Web service的開箱即用的原因。
Registering Plugin JSON Web Services - 註冊外掛的JSON Web Services
假設你有一個名為SupraSurf的portlet,它有一些服務。 並且決定將它們作為遠端服務公開。 在其SurfBoard實體上啟用remote-service屬性後,你將重建服務。 Service Builder重新生成SurfBoardService介面,並向其新增@JSONWebService 註解。 此註解告訴portal介面的公共方法將作為JSON Web service公開,使它們成為plugin的JSON API的一部分。
預設情況下,portlet服務的掃描是禁用狀態。 要啟用掃描,你需要在portlet的web.xml檔案中新增適當的過濾器定義(filter definition)。 幸運的是,Liferay提供了一種自動新增過濾器的方法。 只需在Liferay IDE中單擊Build WSDD按鈕,同時在Overview模式下編輯service.xml檔案,或者只調用build-wsdd Ant target。 在構建WSDD時,Liferay的Plugins SDK修改了portlet的web.xml,併為外掛啟用了JSON Web service。 在幕後,Plugins SDK為外掛註冊了SecureFilter和JSONWebServiceServlet。 你只需為plugin啟用一次JSON Web服務即可。
如果你的入口網站伺服器未執行,需要先啟動。 然後將portlet plugin部署到Liferay。
要從portal獲取有關注冊plugin服務的一些反饋,請配置portal以記錄plugin的資訊性訊息(即其INFO…訊息)。 有關詳細資訊,請參閱Using Liferay Portal 中有關Liferay日誌記錄系統的部分。
要測試Liferay的JSON Web service註冊過程,請為plugin的service新增一個簡單的方法。 編輯*ServiceImpl類並新增以下方法:
public String helloWorld(String worldName) {
return "Hello world: " + worldName;
}
重建服務並重新部署plugin。 請注意,portal會列印一條訊息,如下所示,通知我們已為portlet配置一個action。 這表明服務方法現在已註冊為JSON Web Web服務操作。
INFO [JSONWebServiceActionsManagerImpl:117] Configured 1 actions for\
/suprasurf-portlet
Liferay Portal自己的service action採用同樣的機制註冊。 它們預設情況下已經啟用,因此無需配置。
接下來,讓我們學習如何為遠端服務形成對映URL,以便我們可以訪問。
Mapping and Naming Conventions - 對映與命名約定
你可以按照以下命名約定形成公開服務的對映URL:
http://[server]:[port]/api/jsonws/[plugin-context-name].[service-class-name]/[service-method-name]
仔細看一下最後三個括號中的條目:
- plugin-context-nameplugin的上下文名稱(例如,在我們的示例中為suprasurf-portlet)。 對於portal的服務,應省略plugin-context-name和後續的內容(subsequent period)。
- service-class-name是從service的類名生成的小寫,減去Service或ServiceImpl字尾。 例如,將surfboard指定為SurfBoardService類的plugin-context-name。
- service-method-name是從服務的方法名稱生成的,方法是將其camel case駝峰式轉換為小寫,並使用短劃線(-)分隔單詞。
接下來我們在建立的plugin service和portal service上演示這些命名約定,通過使用命名約定來對映服務方法的URL
對於我們建立的服務方法,URL是這樣的:
http://localhost:8080/api/jsonws/suprasurf-portlet.surfboard/hello-world
請注意URL的context名稱部分。 對於portal來說,它是相似的。 這是我們想要訪問的portal service方法:
@JSONWebService
public interface UserService {
public com.liferay.portal.model.User getUserById(long userId) {...}
這是portal service方法的URL:
http://localhost:8080/api/jsonws/user-service/get-user-by-id
每種服務方法都繫結到一種HTTP方法型別。 名稱以get,is或has開頭的任何方法都假定為只讀方法,預設情況下對映為GET HTTP方法。 所有其他方法都對映為POST HTTP方法。
你可能已經注意到,plugin services是通過portal context訪問的。以這種方式傳送的request可以利用認證憑證(authentication credentials ) ,該認證與使用者的當前門戶session相關聯。
接下來,我們將學習如何列出入口網站提供的JSON Web service。
Listing Available JSON Web Services - 列出可用的JSON Web Service
要檢視已註冊和可供使用的服務方法,請將瀏覽器開啟到以下地址:
http://localhost:8080/api/jsonws
API頁面列出了portal的已註冊和公開的服務方法。要獲取每個方法的詳細資訊,請單擊方法名稱。你將看到該方法的完整簽名,其所有引數以及可丟擲的Exception列表。有關遠端服務方法的其他資訊,你可以在Liferay Portal的Javadocs中查詢該方法。使用瀏覽器中的簡單表單,你甚至可以呼叫服務方法。在開發portlet服務時,這對於測試來說非常方便。
這個API頁面也列出了plugin的遠端服務。如果已部署了啟用遠端服務的多個plugin,請單擊API頁面上的Context Path選擇器。此選擇器列出了所有可用的plugin context path(包括portal的路徑)。選擇plugin的context path或portal的context path,以列出context path中可用的所有遠端服務。
如前文所述所述,你可以使用*ServiceImpl類中的@JSONWebService註解來控制註冊。這將覆蓋介面中定義的任何配置。你還可以在方法級別使用註解控制方法的可見性。
讓我們來了解如何忽略特定方法。
Ignoring a Method - 忽略特定方法
要使方法不作為服務公開,請使用以下選項修飾該方法:
@JSONWebService(mode = JSONWebServiceMode.IGNORE)
使用此註解的方法不會成為JSON Web Service API中的一部分。
接下來學習如何定義自定義HTTP方法名稱和URL名稱。
HTTP Method Name and URL - HTTP 方法與URL
在方法級別,你可以定義HTTP方法名稱和URL名稱。 只需使用這樣的註解:
@JSONWebService(value = "add-board-wow", method = "PUT")
public boolean addBoard(
在此例中,plugin的服務方法addBoard對映到URL方法名稱add-board-wow。 它的完整URL現在是http// localhost:8080/api/jsonws/suprasurf-portlet.surfboard/add-board-wow,可以使用HTTP PUT方法訪問。
如果JSON Web Service註解中的URL方法名稱以斜槓字元(/)開頭,則僅使用方法名稱來形成服務URL; 類名被忽略:
@JSONWebService("/add-something-very-specific")
public boolean addBoard(
同樣,您可以通過在類級別註解中設定值來更改URL的類名稱部分:
@JSONWebService("sbs")
public class SurfBoardServiceImpl extends SurfBoardServiceBaseImpl {
這會將所有服務的方法對映到URL類名稱sbs,不再是預設的類名surfboard。
接下來,我們將向您展示一種不同的方式來公開服務方法,即手動註冊。
Manual Registration Mode - 手動註冊
假設你想要公開大多數服務方法的同時隱藏一些特定方法(即黑名單方法)。 或者想要明確指定那些要公開的方法(白名單方法)。 這也可以通過在類級別註釋上指定手動模式來實現。 然後,你只需註解那些你想要公開的方法。
@JSONWebService(mode = JSONWebServiceMode.MANUAL)
public class SurfBoardServiceImpl extends SurfBoardServiceBaseImpl{
...
@JSONWebService
public boolean addBoard(
現在只有addBoard方法和使用@JSONWebService修飾的任何其他方法將成為JSON Web Service API的一部分; 此服務的所有其他方法將從API中排除。
注意:Liferay的JSON Web service 的對外訪問預設是需要許可權驗證的,這與local service不同,呼叫本地服務都是在portlet UI中,已經進行過許可權驗證。而遠端訪問為了安全性的考慮,需要在遠端服務方法中整合Liferay的許可權認證,可參考Security and Permissions 。也可以將許可權認證關閉,在*Service類級別上有@AccessControlled註解修飾,與@JSONWebService 類似,此註解也可以在ServiceImpl 中進行重新宣告覆蓋,以下是@AccessControlled的預設宣告
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface AccessControlled {
public boolean guestAccessEnabled() default false;
public boolean hostAllowedValidationEnabled() default true;
}
我們可以覆蓋為:
@AccessControlled(guestAccessEnabled = true, hostAllowedValidationEnabled = false)
@JSONWebService(value = "cneerp-json-webservice")
public class CneCommonProblemServiceImpl extends CneCommonProblemServiceBaseImpl {}