На днях необходимо было реализовать отображение картинок в 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 прописываем
Преимущества: простота, легкость формирования ссылки на картинку итд.
Недостатки: картинка должна сначала как-то попасть в нужную директорию на сервере с нужным именем.
Второй способ:
Тот который описан в демонстрационном приложении (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 приложения).
Естественно все лишнее на странице можно скрыть при помощи условий.
Некоторые замечания по данному способу:
- Из парсинг-схемы будет видно только таблица или вьюшка. С синонимы хоть и будут работать, но создать страницу с типом «Форма на базе таблицы или представления» на синоним не выйдет.
- Попытки создать страницу типа «Форма на базе таблицы или представления» из схемы которая не находится в webschema (в моем случае на appschema.PersData) закончились неудачей. И хоть данные видно, изображение не отображается. Видимо, что бы отображать картинку, объект должен находится в парсинг схеме.
Страницу не обязательно создавать на основе «Форма на базе таблицы или представления»
Теперь создадим на странице item P3_ID типа hide, и сделаем ссылку на этуже страницу в регионе типа report.
Создаем еще один регіон типа HTML и бросаем на него элемент file browse, а так же 2 процесса: Automated Row Fetch (причем сначала он не позволит Вам выбрать нужную схему, но потом создавшись, позволит) и Automatic Row Processing (DML).
У первого есть минус – нужно создавать 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 у меня без редактирования ничего не вышло.Так же частично я описывал тут.
http://apex.oracle.com/pls/otn/DKUBICEK.my_image_display?p_image_id=3390640906422855233 Это означает, что любой встречный без аутентификации зная ссылку может перебором айдишников просмотреть изображение, и надо думать, как обезопасится от такого. Так же стоит сказать, что в описании забыли важный момент: что бы работал такой способ нужно отредактировать функцию apex_030200.wwv_flow_epg_include_mod_local у меня без редактирования ничего не вышло.Так же частично я описывал тут.



















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