Weitere ähnliche Inhalte
Ähnlich wie Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう (20)
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
- 4. AlfrescoのREST API
AlfrescoはPlatformとShareで構成される
PlatformはREST APIでコア機能を提供する
Shareも画面を構成する一部コンポーネントがREST APIで
HTML断片を提供する
Spring Web Scriptsで実装される
Alfresco Platform
(Alfrescoのコア機能をREST APIで提
供)
Alfresco Share
Alfresco Platform
(Alfrescoのコア機能をREST APIで提供)
Alfresco Share
(AlfrescoのGUIを提供)
ブラウザ
HTTP Request HTTP Response
HTTP Request HTTP Response
Alfresco
- 5. Spring Web Scriptsとは
AlfrescoのREST APIを実装するフレームワーク
Alfrescoが開発を進め、Spring Surfの一部としてSpringSource
に寄贈。のはずが…
以後Web Scriptsと呼び、基本的な構成と
REST APIの実装方法を見ていきます
- 6. 2種類のWeb Scripts
Repository Web Scripts
(Data Web Scripts)
Presentation Web Scripts
(Surf Web Scripts)
Alfresco Platform 生息場所
Alfresco Platform
Alfresco Share
主にXMLやJSON レスポンス 主にHTML
Alfrescoが管理するデータの取
得や更新
目的 UIのカスタマイズや拡張
Alfrescoのコアサービス呼び出
しを伴う処理をカプセル化し、
外部からのリクエストに対し
てその処理結果を返す
処理イメージ
Presentation Web ScriptsがUI
をレンダリングし、その中で
Repository Web Scriptsを呼ん
で必要なデータを取得しUI上
に表示する
http://docs.alfresco.com/5.1/concepts/ws-types.html
- 7. Web Scriptsを構成する3つの要素
定義ファイル
◦ 公開するREST APIの情報をxmlで定義する
ロジック
◦ REST API呼出時に実行するロジックをJavaScriptもしくはJavaで記述する
◦ MVCで言うところのController
◦ ビジネスロジックを実行し、レスポンス用のデータをセットする
テンプレート
◦ REST APIのレスポンスを生成するテンプレートをFreeMarkerで記述する
◦ MVCで言うところのView
※ 上記以外にもconfigファイル等あるがここでは割愛
- 8. 定義ファイル
ファイル名 : <web script id>.<http method>.desc.xml
REST APIの定義をxmlで記述する
REST APIのURLパターンやレスポンス形式、認証、トランザ
クション等を指定する
<webscript>
<shortname>Category Search Sample</shortname>
<description>Sample that finds all blog entries tagged with specified categories</description>
<url>/sample/blog/category/{category}</url>
<format default="html">argument</format>
<authentication>guest</authentication>
<transaction>required</transaction>
<lifecycle>sample</lifecycle>
</webscript>
categorysearch.get.desc.xml
- 9. ロジック
ファイル名 : <web script id>.<http method>.js
REST API呼出時に実行するロジックをJavaScriptで記述する
AlfrescoのJavaScript APIを使ってロジックを組み立てる
◦ ルートオブジェクトを介して、ユーザ/ノード等のコンテキスト情報やバッ
クエンドのJava API(コアサービス等)を利用可能
◦ ルートオブジェクトmodel, statusあたりにレスポンスに必要な情報を格納
すると、レスポンス用テンプレートで参照できる
※ ロジックはJavaでも記述可能(後述)
var category = search.luceneSearch("PATH:"/cm:generalclassifiable//cm:" + url.extension + """);
if (category == undefined) {
status.code = 404;
status.message = "Category " + url.extension + " not found.";
status.redirect = true;
} else {
// perform category search
var nodes = search.luceneSearch("PATH:"/cm:generalclassifiable//cm:" + url.extension + "//member"");
model.resultset = nodes;
}
categorysearch.get.js
- 10. テンプレート
ファイル名 : <web script id>.<http method>.<format>.ftl
REST APIのレスポンス内容をFreeMarkerで記述する
model, status等の内容や、テンプレートで利用可能なルート
オブジェクトを使ってレスポンスを構成する
<html>
<body>
<img src="${url.context}/images/logo/AlfrescoLogo32.png" alt="Alfresco" />
Category search: ${url.extension}
<br>
<table>
<#list resultset as node>
<tr>
<td><img src="${url.context}${node.icon16}"/>
<td><a
href="${url.serviceContext}/api/node/content/${node.nodeRef.storeRef.protocol}/${node.nodeRef.storeRef.identifier}/${n
ode.nodeRef.id}/${node.name?url}">${node.name}</a>
</tr>
</#list>
</table>
</body>
</html>
categorysearch.get.html.ftl
- 11. カスタムREST APIを作ってみよう
カスタムREST APIの仕様は以下のとおり
◦ URL : /sample/search?q={検索文字列}
◦ 認証 : ユーザ認証
◦ ロジック : 指定した検索文字列での検索結果を返す
◦ レスポンス形式 : html
◦ レスポンス内容 : 検索でヒットしたノードの名前とパスを表示する
- 12. カスタムREST APIを作ってみよう
定義ファイル
主要な設定項目
◦ url : リクエストパラメータを含むAPIの呼出URL
◦ format : レスポンスフォーマット
◦ authentication : API呼び出しに必要な認証
<webscript>
<shortname>Search Sample</shortname>
<description>Search Sample</description>
<url>/sample/search?q={searchTerm}</url>
<format default="html" />
<authentication>user</authentication>
<transaction>required</transaction>
<lifecycle>sample</lifecycle>
</webscript>
samplesearch.get.desc.xml
- 13. カスタムREST APIを作ってみよう
ロジック
よく使われるルートオブジェクト
◦ args : リクエストパラメータにアクセスするためのオブジェクト
◦ model : レスポンスに含めるデータを格納するオブジェクト
◦ search : 検索関連Java APIをラップして提供するオブジェクト
if (args.q == undefined || args.q.length == 0) {
model.results = [];
} else {
model.results = search.luceneSearch("TEXT:" + args.q);
}
samplesearch.get.js
- 14. カスタムREST APIを作ってみよう
テンプレート
#if, #list等のFreeMarkerディレクティブを利用
modelがロジックから共有され、resultsと書くだけで
model.resultsにアクセス可能
JavaScript API上でのノードオブジェクト(以下のnode等)は
ScriptNode型で、便利なプロパティを多数提供する
<html>
<head><title>Search Sample Web Script</title></head>
<body>
<#if results?has_content>
<table>
<tr><th></th><th>name</th><th>path</th></tr>
<#list results as node>
<tr>
<td><img src="${url.context}${node.icon16}"/></td>
<td>${node.name}</td>
<td>${node.displayPath}</td>
</tr>
</#list>
</table>
<#else>
<p>No search results</p>
</#if>
</body>
</html>
samplesearch.get.html.ftl
http://docs.alfresco.com/5.1/references/API-JS-ScriptNode.html
- 15. ルートオブジェクト
AlfrescoのJavaScript APIで利用可能なオブジェクト
◦ 実体はBaseProcessorExtensionを継承したJavaオブジェクト
◦ カスタムルートオブジェクトを実装することも可能
いくつかの種類のオブジェクトがある
◦ Web Scriptsの基本機能を提供 : model, args, session, url …
◦ コンテキストノードを提供 : companyHome, document, person, space …
◦ Java APIを提供 : actions, jsonUtils, people, search, workflow …
◦ コアサービスをそのまま提供 : siteService, taggingService …
記述場所によって利用できるものが異なる
Platform側のロジック : http://docs.alfresco.com/5.1/references/API-JS-rootscoped.html
Platform側のテンプレート : http://docs.alfresco.com/5.1/references/API-FreeMarker-
defaultmodel.html
Share側のロジック : http://docs.alfresco.com/5.1/references/APISurf-rootscoped.html
Share側のテンプレート: http://docs.alfresco.com/5.1/references/APISurf-templates.html
/ http://docs.alfresco.com/5.1/references/APISurf-components.html
http://docs.alfresco.com/5.1/references/dev-extension-points-javascript-root-objects.html
- 16. Web Scriptsファイルの配置場所
Repository Web Scripts
◦ Alfresco上の /Company Home/Data Dictionary/webscripts/
◦ <tomcat_dir>/shared/classes/alfresco/extension/templates/webscripts/
◦ classpath:alfresco/templates/webscripts/
Presentation Web Scripts
◦ <tomcat_dir>/shared/classes/alfresco/web-extension/site-webscripts/
◦ classpath:alfresco/site-webscripts/
- 17. Web Scriptsのリフレッシュ
Web Scriptsの内容修正を反映させる方法は以下の2つ
1. Alfrescoを再起動する
◦ 反映に時間がかかる
◦ JARファイルでパッケージされたWeb Scriptsの変更も対応可能
2. Web Scripts管理画面でリフレッシュする
◦ 一瞬で反映可能
◦ JARファイルでパッケージされたWeb Scriptsの変更は反映不能
※ 以下のページのRefresh Web Scriptsボタンをクリックするだけ
Platform : http://localhost:8080/alfresco/service/index
Share : http://localhost:8080/share/page/index
- 18. カスタムREST APIを動作確認する
Web Scripts管理画面にてカスタムREST APIが正常に登録さ
れているか確認(Browse by Web Script URIなどで)
◦ Platform : http://localhost:8080/alfresco/service/index
◦ Share : http://localhost:8080/share/page/index
実際にHTTPリクエストを投げて結果を確認
- 19. Java-backed Web Scripts
Javaでロジックを記述したWeb Scripts
定義ファイルとテンプレートはJavaScriptの場合と一緒
<webscript>
<shortname>Java-backed Web Scripts Search Sample</shortname>
<description>Java-backed Web Scripts Search Sample</description>
<url>/sample/javasearch?q={searchTerm}</url>
<format default="html" />
<authentication>user</authentication>
<transaction>required</transaction>
<lifecycle>sample</lifecycle>
</webscript>
samplejavasearch.get.desc.xml
<html>
<head><title>Search Sample Java-backed Web Scripts</title></head>
<body>
<div><p>Java-backed Web Scripts Sample</p></div>
<#if results?has_content>
<table>
<tr><th>name</th><th>path</th></tr>
<#list results as node>
<tr><td>${node.name}</td><td>${node.path}</td></tr>
</#list>
</table>
<#else>
<p>No search results</p>
</#if>
</body>
</html>
samplejavasearch.get.html.ftl
- 20. Java-backed Web Scripts
ロジックの記述
ロジックをJavaクラスで記述する
◦ DeclarativeWebScriptクラスを継承
◦ executeImpl()にロジックを記述
package jp.aegif.alfresco.sample;
public class SampleSearchWebScript extends DeclarativeWebScript {
private SearchService searchService;
private NodeService nodeService;
private PermissionService permissionService;
...
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) {
Map<String, Object> model = new HashMap<String, Object>();
String searchTerm = req.getParameter("q");
if (searchTerm != null && !searchTerm.isEmpty()) {
ResultSet resultSet = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
SearchService.LANGUAGE_FTS_ALFRESCO, searchTerm);
List<Map<String, String>> results = new ArrayList<Map<String, String>>();
for (ResultSetRow resultSetRow : resultSet) {
NodeRef nodeRef = resultSetRow.getNodeRef();
String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
String path = (String)nodeService.getPath(nodeRef).toDisplayPath(nodeService, permissionService);
Map<String, String> result = new HashMap<String, String>();
result.put("name", name);
result.put("path", path);
results.add(result);
}
model.put("results", results);
}
return model;
}
}
SampleSearchWebScript.java
- 21. Java-backed Web Scripts
Web Scripts定義とロジックの紐付け
Spring bean定義でロジッククラスを紐付ける
◦ bean id : webscript.<web script id>.<http method>
◦ class : ロジック実装クラス(DeclarativeWebScriptクラスを継承)
◦ parent : webscript beanを指定
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="webscript.samplejavasearch.get" class="jp.aegif.alfresco.sample.SampleSearchWebScript"
parent="webscript">
<property name="searchService" ref="SearchService" />
<property name="nodeService" ref="NodeService" />
<property name="permissionService" ref="PermissionService" />
</bean>
</beans>
webscript-context.xml
- 23. まとめ
Web Scriptsを使ったカスタムREST APIの作成方法を紹介しまし
た
今回使用したソースコード
https://bitbucket.org/tasuku_otani/alfresco-java-backed-web-scripts-sample
ビルド環境の作り方
http://www.slideshare.net/terajun/alfresco26-alfresco-sdk
http://labo-blog.aegif.jp/2016/05/alfresco-sdk-22jar.html
- 24. リファレンス
Alfrescoで実際に使われているWeb Scripts
◦ Platform :
https://github.com/Alfresco/community-edition/tree/master/projects/remote-
api
◦ Share :
https://github.com/Alfresco/share/tree/master/share
Web Scriptsに関するAlfrescoのドキュメント
◦ Platform :
http://docs.alfresco.com/5.1/references/dev-extension-points-
webscripts.html
◦ Share :
http://docs.alfresco.com/5.1/concepts/dev-extensions-share-surf-web-
scripts.html
Jeff Potts’ Web Scripts tutorial (must readだそうです…)
http://ecmarchitect.com/alfresco-developer-series-
tutorials/webscripts/tutorial/tutorial.html
- 25. おまけ
aegif Labo blog やってます
http://aegif-labo.blogspot.jp/
現時点でのAlfresco CEの最新版は…
◦ 最新版は5.2の201611-EA(Early Access)
https://community.alfresco.com/docs/DOC-6301
https://community.alfresco.com/docs/DOC-6467
◦ GA(Generally Available)リリースの最新版は5.1の201605-GA
https://community.alfresco.com/docs/DOC-6297
https://sourceforge.net/projects/alfresco/