CKEditor5(リッチ・テキスト・エディタ)に表示する画像をオブジェクト・ストレージに配置し、事前認証リクエストを使って参照する実装について記事(CKEditor5による画像アップロードを実装する(4) - 画像をオブジェクト・ストレージに保存する)を書いています。
カード・リージョンやレポートに画像を表示する方がリッチ・テキスト・エディタに画像を埋め込むより用途としては多いはずなので、カードに表示する画像をオブジェクト・ストレージに配置するような実装を試してみました。
SQLワークショップのユーティリティのクイックSQLを使って、使用する表を作成します。
以下のモデルから、表IMG_ITEMS、IMG_IMAGESを作成します。
# prefix: img
# pk: guid
# ondelete: set null
items
name vc80 /nn
images
item_id /fk items
location vc400 /nn
file_name vc80
mime_type vc200
last_updated date /nn
SQLの生成、SQLスクリプトを保存、レビューおよび実行を順次実施します。表の作成までを実施し、アプリケーションの作成は行いません。
アプリケーション作成ウィザードを起動します。
アプリケーションの名前は画像ビューワーとします。ホーム・ページの編集を開いて削除し、代わりにファセット検索のページを追加します。
ページ名も画像ビューワーとします。表示形式はレポートを選択します。フォームの画面をウィザードで作成するためにレポートを選んでいます。フォームを含めるにチェックを入れます。アプリケーションの作成後にレポートからカードに変更します。ソースとなる表としてIMG_ITEMSを選択します。
ページの追加をクリックします。
アプリケーションが作成されます。
オブジェクト・ストレージを扱うための設定を行います。記事CKEditor5による画像アップロードを実装する(4) - 画像をオブジェクト・ストレージに保存するで行なっている準備作業(APEXワークスペース・スキーマへの権限付与、クリデンシャルMY_OCI_CREDの作成、バケットimagesの作成等)は実施済みとします。
アプリケーション定義の置換として、置換文字列G_REGION、G_NAMESPACE、G_BUCKET、G_CREDENTIALに置換値を設定します。
記事CKEditor5による画像アップロードを実装する(4) - 画像をオブジェクト・ストレージに保存するの事前承認リクエストの発行を参照し、アプリケーション・アイテムG_PREAUTH_URLを作成します。
アプリケーションの計算を作成します。計算として設定するコードは以下です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
C_BASE_URL constant varchar2(200) := 'https://objectstorage.us-ashburn-1.oraclecloud.com/n/' || :G_NAMESPACE || '/b/images/p/'; | |
l_request clob; | |
l_response clob; | |
l_response_json json_object_t; | |
l_access_uri varchar2(400); | |
begin | |
select json_object( | |
key 'accessType' value 'AnyObjectRead', | |
key 'name' value 'standard-' || sys_guid(), | |
key 'timeExpires' value systimestamp + interval '1' day | |
) into l_request from dual; | |
apex_web_service.clear_request_headers; | |
apex_web_service.set_request_headers('Accept', 'application/json', p_reset => false); | |
apex_web_service.set_request_headers('Content-Type', 'application/json', p_reset => false); | |
l_response := apex_web_service.make_rest_request( | |
p_url => C_BASE_URL | |
,p_http_method => 'POST' | |
,p_body => l_request | |
,p_credential_static_id => 'OCI_API_ACCESS' | |
); | |
l_response_json := json_object_t(l_response); | |
l_access_uri := l_response_json.get_string('accessUri'); | |
return 'https://objectstorage.us-ashburn-1.oraclecloud.com' || l_access_uri; | |
end; |
レポートのページ(ページ番号1)を開き、リージョンImg Itemsを選択します。
識別のタイプをクラシック・レポートからカードに変更します。ソースのタイプをSQL問合せに変更し、SQL問合せを以下のSELECT文に置き換えます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
select i.id, i.name, :G_PREAUTH_URL || g.location location, g.file_name | |
from img_items i join | |
( | |
select id, item_id, location, file_name, mime_type from | |
( | |
select | |
row_number() over (partition by item_id order by last_updated desc) rn, | |
id, item_id, location, file_name, mime_type | |
from img_images | |
) | |
where rn = 1 | |
) g on i.id = g.item_id |
リージョンImg Itemsを選択し、プロパティ・エディタの属性を開きます。
タイトルの列としてNAMEを選択します。メディアのソースとしてURL列、URL列としてLOCATIONを選択します。位置、外観、サイズ指定はデフォルトのまま変更しません。
カードの編集画面を開くため、カード・リージョンImg Itemsにアクションを作成します。
作成したアクションの識別のタイプとしてカード全体を選択します。リンクのタイプとしてこのアプリケーションのページにリダイレクト、ターゲットはページ2とします。
ターゲットをクリックして、リンク・ビルダー・ターゲットを開いて設定します。
ターゲットのページは2を選択します。アイテムの設定の名前としてP2_ID、値として&ID.を設定します。
以上でOKをクリックします。
ページ・デザイナにてページ番号2のフォームのページを開きます。イメージ・ファイルのアップロードを実装します。
Region Bodyにページ・アイテムP2_IMAGEを作成します。
識別の名前をP2_IMAGE、タイプとしてファイル参照...を選択します。ラベルはImageとします。設定の表示形式としてBlock Dropzoneを選択します。
記憶域タイプとしてTable APEX_APPLICATION_TEMP_FILESを選択し、ファイルをパージするタイミングとしてEnd of Requestを選びます。アップロードされたファイルは表APEX_APPLICATION_TEMP_FILESの1行として保存されます。そのファイルは次に作成するプロセスにてオブジェクト・ストレージにアップロードするので、リクエストが終了したら不要になります。そのため、リクエスト終了時にパージする(End of Request)ように設定します。
オブジェクト・ストレージにアップロードするプロセスを作成します。
最初に以下のパッケージIMG_UTILを作成します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
APEX_APPLICATION_TEMP_FILESにアップロードされた画像を、オブジェクト・ストレージに | |
アップロードする。 | |
仕様部 | |
*/ | |
create or replace package img_util as | |
procedure upload_image( | |
p_id in number | |
,p_item_value in varchar2 | |
,p_region in varchar2 | |
,p_namespace in varchar2 | |
,p_bucket in varchar2 | |
,p_credential in varchar2 | |
); | |
end img_util; | |
/ | |
/** | |
パッケージ本体 | |
*/ | |
create or replace package body img_util as | |
procedure upload_image( | |
p_id in number | |
,p_item_value in varchar2 | |
,p_region in varchar2 | |
,p_namespace in varchar2 | |
,p_bucket in varchar2 | |
,p_credential in varchar2 | |
) | |
as | |
l_image_id img_images.id%type; | |
l_file_name img_images.file_name%type; | |
l_location img_images.location%type; | |
l_mime_type img_images.mime_type%type; | |
l_blob blob; | |
l_put_response dbms_cloud_oci_obs_object_storage_put_object_response_t; | |
e_file_upload_exception exception; | |
begin | |
/* | |
* APEXの機能でアップロードされたファイルを取得する。 | |
*/ | |
select blob_content, filename, mime_type into l_blob, l_file_name, l_mime_type | |
from apex_application_temp_files | |
where name = p_item_value; | |
/* | |
* 仮のLOCATIONで、表IMG_IMAGESに行を挿入しIDを取得する。 | |
* 取得したIDでオブジェクト・ストレージのオブジェクト名を決定します。 | |
*/ | |
insert into img_images(item_id, file_name, mime_type, location, last_updated) | |
values(p_id, l_file_name, l_mime_type, 'temp', sysdate) | |
returning id into l_image_id; | |
l_location := p_id || '/' || l_image_id || '/' || l_file_name; | |
/* | |
* 画像をオブジェクト・ストレージにアップロードする。 | |
*/ | |
l_put_response := dbms_cloud_oci_obs_object_storage.put_object | |
( | |
namespace_name => p_namespace | |
,bucket_name => p_bucket | |
,object_name => l_location | |
,content_type => l_mime_type | |
,put_object_body => l_blob | |
,region => p_region | |
,credential_name => p_credential | |
); | |
if l_put_response.status_code <> 200 then | |
raise e_file_upload_exception; | |
end if; | |
/* | |
* オブジェクト名と更新日を更新する。 | |
*/ | |
update img_images set location = l_location, last_updated = sysdate where id = l_image_id; | |
end upload_image; | |
end img_util; | |
/ |
プロセスを作成し、プロセス・フォームImg Itemの下に配置します。識別の名前をオブジェクト・ストレージに保存とします。タイプはAPIの呼出しを選びます。設定にてパッケージIMG_UTILのプロシージャUPLOAD_IMAGEを呼び出すように指定します。
サーバー側の条件のタイプとしてリクエストは値に含まれる、値にCREATE SAVEを指定します。
p_id = P2_ID
p_item_value = P2_IMAGE
p_region = G_REGION
p_namespace = G_NAMESPACE
p_bucket = G_BUCKET
p_credential = G_CREDENTIAL
以上でアプリケーションは完成です。実行すると先頭のGIF動画のような動作をします。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/image-viewer-preauth-obs.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完