Часто 3х звеные приложения организованы так, что сервер приложений ходит к БД под одним пользователем (владельцем схемы), а пользователи подключаются к серверу приложений под своими именами. А в контексте БД надо знать что за пользователь обращается к данным. Вот тут и используется возможность указать в контексте БД пользовательскую информацию.
В Oracle для этого можно использовать пакет - dbms_session. А писать туда информацию лучше на методе prepareSession(SessionData sessionData) из ApplicationModuleImpl. Дело в том, что Application Module участвует в пуле модулей и его экземпляр может передаваться между разными пользователями. Перед тем как отдать экземпляр одного пользователя другому, его состояние сохраняется в БД (по умолчанию в таблицу PS_TXN) , а перед тем как вернуть экземпляр обратно пользователю, состояние загружается из БД (по умолчанию). Отслеживать эти моменты можно на методе - prepareSession. Для Application Module надо подготовить Impl java класс.
Для облегчения написания взаимодействия с БД объектами (пакетами, функциями, процедурами) в JDeveloper интегрирован JPublisher с помощью которого можно генерировать автоматически классы - обертки.
Подготовим в БД пакет - MY_CTX (Использую схему HR для XE):
Надо создать еще контекст:
CREATE OR REPLACE CONTEXT context_namespace USING my_ctx;
И для этого пакета создадим java класс MyCtx (см. исходный код).
Есть одна неприятность, для Oracle Express Edition (XE) JPublisher не работает. Я это сделал на другом сервере.
Далее из Impl класса - Application Module вызвать инициализацию контекста.
Подготовить VO, где для критерия использовать имя текущего пользователя из контекста (пакет my_ctx)
И разместить этот VO на странице. Таким образом после авторизации, попадем на страницу на которой будет выведена информация из БД о текущем пользователе.
После авторизации
Для примера надо завести на WLS несколько пользователей из таблицы employees - поле last_name.
Пример основан на практикуме 01
Источники:
ADF BC, Overriding prepareSession, and PL/SQL
http://it.toolbox.com/blogs/jjflash-oracle-journal/adf-bc-overriding-preparesession-and-plsql-54789
Исходный код
В Oracle для этого можно использовать пакет - dbms_session. А писать туда информацию лучше на методе prepareSession(SessionData sessionData) из ApplicationModuleImpl. Дело в том, что Application Module участвует в пуле модулей и его экземпляр может передаваться между разными пользователями. Перед тем как отдать экземпляр одного пользователя другому, его состояние сохраняется в БД (по умолчанию в таблицу PS_TXN) , а перед тем как вернуть экземпляр обратно пользователю, состояние загружается из БД (по умолчанию). Отслеживать эти моменты можно на методе - prepareSession. Для Application Module надо подготовить Impl java класс.
Для облегчения написания взаимодействия с БД объектами (пакетами, функциями, процедурами) в JDeveloper интегрирован JPublisher с помощью которого можно генерировать автоматически классы - обертки.
Подготовим в БД пакет - MY_CTX (Использую схему HR для XE):
create or replace package my_ctx is /** * %author ARYLKOV * 14.05.2013 */ -- Имя контекста CTX_NAME constant varchar2(30) := 'context_namespace'; CTX_USERNAME constant varchar2(30) := 'username'; procedure set_user(p_username varchar2); function get_user return varchar2; end my_ctx; / create or replace package body my_ctx is procedure set_user(p_username varchar2) is begin dbms_session.set_context(namespace => CTX_NAME, attribute => CTX_USERNAME, value => p_username); end; function get_user return varchar2 is v_get_user varchar2(30 char); begin SELECT SYS_CONTEXT(CTX_NAME, CTX_USERNAME) into v_get_user FROM dual; return(v_get_user); end; end my_ctx; /
Надо создать еще контекст:
CREATE OR REPLACE CONTEXT context_namespace USING my_ctx;
И для этого пакета создадим java класс MyCtx (см. исходный код).
Есть одна неприятность, для Oracle Express Edition (XE) JPublisher не работает. Я это сделал на другом сервере.
Далее из Impl класса - Application Module вызвать инициализацию контекста.
Переопределить метод можно и так, в меню Source-Override Method.public class AppModuleImpl extends ApplicationModuleImpl { .... public void prepareSession(SessionData sessionData) { super.prepareSession(sessionData); MyCtx ctx; try { ctx = new MyCtx(getConnection()); SecurityContext sc= ADFContext.getCurrent().getSecurityContext(); ctx.setUser(sc.getUserName()); } catch (SQLException e) { System.out.println(e); } }
Подготовить VO, где для критерия использовать имя текущего пользователя из контекста (пакет my_ctx)
И разместить этот VO на странице. Таким образом после авторизации, попадем на страницу на которой будет выведена информация из БД о текущем пользователе.
После авторизации
Для примера надо завести на WLS несколько пользователей из таблицы employees - поле last_name.
Пример основан на практикуме 01
Источники:
ADF BC, Overriding prepareSession, and PL/SQL
http://it.toolbox.com/blogs/jjflash-oracle-journal/adf-bc-overriding-preparesession-and-plsql-54789
Исходный код
Позже мне удалось найти универсальный способ генерации java кода для пакетов, в том числе и для XE. Для этого делается cmd файл. Пример.
ОтветитьУдалитьРазместил командный файл в :\oracle\product\11.2.0\client_1\BIN\jpub.cmd.
Содержимое:
set ORACLE_HOME=C:\oracle\product\11.2.0\client_1
set CLASSPATH=%ORACLE_HOME%\jdbc\lib\ojdbc5.jar;%ORACLE_HOME%\sqlj\lib\translator.jar;%ORACLE_HOME%\sqlj\lib\runtime12.jar
"C:\Program Files (x86)\Java\jdk1.6.0_26\bin\java.exe" -Duser.region=us -Duser.language=en oracle.jpub.Doit -user=HR/1 -url=jdbc:oracle:thin:@rylkovvm:1521:XE -s HR.MY_CTX -dir=src -package=practice.adf.model.java -compile=false