вторник, 14 мая 2013 г.

8й - Практикум. Oracle ADF. Контекст пользователя. prepareSession, CONTEXT, dbms_session, JPublisher

Часто 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 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 вызвать инициализацию контекста.

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);
        }
    }
Переопределить метод можно и так, в меню Source-Override Method.



Подготовить 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

Исходный код

 
 




1 комментарий:

  1. Позже мне удалось найти универсальный способ генерации 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

    ОтветитьУдалить