11 окт. 2010 г.

Отображение картинок в Oracle Apex.

На днях необходимо было реализовать отображение картинок в Oracle Application Express (ApEx). Казалось бы тривиальная задача, но тривиальна она лишь при определенных условиях.
Все что ниже описывает ситуацию, когда есть сервер СУБД Oracle 10g EE и Apex версий 3.1.2 или 3.2 (разницы не заметили), сервер приложений Oracle HTTP Server (компонент Oracle Application Server 10g Release 2).

Краткая предыстория:

Есть используемое десктоповое приложение, использующее прикладную схему Oracle. В ней хранятся все данные приложения (таблици, представления итд), а так же логика работы (пакеты, функции итд). Была поставленная задача сделать простенький web интерфейс к ней. В приложении есть таблица с личными данными сотрудников (ФИО, дата рождения, фотография, адрес). Назовем эту прикладную схему APPSCHEMA. Для работы с Apex необходимо в настройках Workspace добавить схему, которая станет видимой из конструктора приложений (Home>Manage Workspaces>Manage Workspace to Schema Assignments).
Проблема в том, что приложение уже работает и администратор не хочет включать уже работающую APPSCHEMA  и давать полный доступ web-приложению к всем объектам схемы (что вообще то логично). К тому же web здесь используется как новшество и пока в качестве эксперимента. Поэтому было принято решение создать схему для веба и выдать ей грант на соответственный объект в схеме APPSCHEMA.

Тестовый пример

Для чистоты эксперимента, создадим пустое web-приложение и парсинг схему (Parsing Schema) с тестовым (демонстрационным) приложением и прикладную схему приложения.
create user APPSCHEMA identified by "1"
Default Tablespace "MYSPACE"
Temporary Tablespace "TEMP"
quota unlimited on "MYSPACE";

grant connect to APPSCHEMA;

create table appschema.PersData (
  Id number(10), 
  Surname varchar2(50), 
  Name varchar2(50), 
  FatherName varchar2(50), 
  br date,
  address varchar2(100),
  photo blob
)
  Tablespace MYSPACE
;
create unique index appschema.persdatapkindex on appschema.persdata (id asc) tablespace myspace;
alter table appschema.persdata add  (constraint pk_persdata primary key (id )) ;
Загрузим данные (load.ctl):
load data
infile *
append
into table appschema.PersData
fields terminated by '|'
(
  Id,
  Surname,
  Name ,
  FatherName,
  br,
  address,
  photo lobfile(Id) terminated by eof
)
begindata
1|Иванов|Иван|Иванович|17.09.1960|г. Град ул. Городская 4|
2|Петров|Петр|Петрович|23.04.1972|г. Град ул. Городская 10|
Имя картинки должно быть 1 и 2 без расширений итд. Грузим командой, запущенной в каталоге с ctl файом и картинками.
sqlldr userid=APPSCHEMA/1@alias control=load.ctl log=_load.log
Создадим схему для апекс приложения:
create user webschema identified by "1"
Default Tablespace "MYSPACE"
Temporary Tablespace "TEMP"
quota unlimited on "MYSPACE";
Добавим её в apex (Home>Manage Workspaces>Manage Workspace to Schema Assignments). Создадим чистое (пустое) приложение, выбрав в качестве парсинг схемы webschema.

Первый способ:

Итак, первый самый простой и наименее функциональный: непосредственное размещение картинке, где-то в каталогах Apache сервера.
В директорию на сервере Oracle Apache  ORACLE_HOME\Apache\images\ создаем каталог APPSCHEMA и в неё кидаем файл flixtrix2.jpg. На странице создаем HTML регион и в Region Source прописываем
reg



Преимущества: простота, легкость формирования ссылки на картинку итд.
Недостатки: картинка должна сначала как-то попасть в нужную директорию на сервере с нужным именем.

Второй способ:

Тот который описан в демонстрационном приложении (Sample Application). Для начала дадим грант webschema на выборку из appschema.PersData.
Grant select on appschema.PersData to webschema;
Создадим вью
create or replace view webschema.persdataview as
select Id, photo from appschema.PersData;
Создадим страницу как форму на основании таблицы или представления см скрины.










Можно поменять полю P5_ID тип hiden and protection просто на hiden. Добавляем итем P5_IMAGE типа «Display as Text» (обязательно does not save state).
В Source тема P5_IMAGE прописываем:
RETURN '<img src="'||APEX_UTIL.GET_BLOB_FILE_SRC('P5_PHOTO',:P5_id)||'" />';


В результате должны получить следующее (прошу обратить внимание на адрес(url), там явно передается параметр P5_ID, на самом деле, данные параметры могут быть переданы при переходе на эту страницу, как зависит от вашего web приложения).

 
Естественно все лишнее на странице можно скрыть при помощи условий.
Некоторые замечания по данному способу:
  1. Из парсинг-схемы будет видно только таблица или вьюшка. С синонимы хоть и будут работать, но создать страницу с типом «Форма на базе таблицы или представления» на синоним не выйдет.
  2. Попытки создать страницу типа «Форма на базе таблицы или представления» из схемы которая не находится в webschema (в моем случае на appschema.PersData) закончились неудачей. И хоть данные видно, изображение не отображается. Видимо, что бы отображать картинку, объект должен находится в парсинг схеме. 
 
Страницу не обязательно создавать на основе «Форма на базе таблицы или представления»


Теперь создадим на странице item P3_ID типа hide, и сделаем ссылку на этуже страницу в регионе типа report.
Создаем еще один регіон типа HTML и бросаем на него элемент file browse, а так же 2 процесса: Automated Row Fetch (причем сначала он не позволит Вам выбрать нужную схему, но потом создавшись, позволит) и Automatic Row Processing (DML).
Есть еще способы, которые описаны у Denes Kubicek: Вариант1 и Вариант 2
У первого есть минус – нужно создавать public синоним на my_image_display (без этого не работало). Так же жестко привязана к таблице функция. Так же просмотреть картинки можно по ссылке вида:
http://apex.oracle.com/pls/otn/DKUBICEK.my_image_display?p_image_id=3390640906422855233 Это означает, что любой встречный без аутентификации зная ссылку может перебором айдишников просмотреть изображение, и надо думать, как обезопасится от такого. Так же стоит сказать, что в описании забыли важный момент: что бы работал такой способ нужно отредактировать функцию  apex_030200.wwv_flow_epg_include_mod_local у меня без редактирования ничего не вышло.Так же частично я описывал тут.

Комментариев нет:

Отправить комментарий