понедельник, 26 ноября 2012 г.

Сохранение настроек в ADF-приложении (часть 1) - используем Context Params

Уже не раз в разговорах с ADF-разработчиками подымался вопрос о том, где хранить значения специфичных настроек приложения.  Вариантов ответов на данный вопрос несколько, поэтому я решил в серии постов рассмотреть основные варианты и дать рекомендации по их применению.
Итак, первый вариант - это использование стандартного дескриптора web.xml, а точнее элемента context-param.


Предположим, что в нашем приложении есть 2 настроечных параметра - числовой и текстовый, соответственно в web.xml мы можем их описать так:
<?xml version = '1.0' encoding = 'UTF-8'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
  <!-- fragment starts--!>
  <context-param>
    <description>My custom string parameter</description>
    <param-name>myStringParam</param-name>
    <param-value>Sample value</param-value>
  </context-param>
  <context-param>
    <description>My custom int parameter</description>
    <param-name>myIntParam</param-name>
    <param-value>2012</param-value>
  </context-param>
  <!-- fragment ends --!>
</web-app>

а в редакторе JDeveloper это будет выглядеть так:










Обратиться к контекстным параметрам из Java-кода довольно просто:
FacesContext fctx = FacesContext.getCurrentInstance();
ServletContext servletContext = (ServletContext) fctx.getExternalContext().getContext();
String myIntParam = servletContext.getInitParameter("myStringParam");

Из EL еще проще#{initParam.myStringParam}

В моем примере текстовое сообщение в заголовке PanelBox получается из параметра myStringParam, а код обработчика нажатия кнопки анализирует myIntParam:











Чтобы поменять значения контекстных параметров можно воспользоваться присутствующей в Weblogic функциональностью Deployment Plans.  Она позволяет нам повлиять на значения в дескрипторах развертывания без ручной модификации самих дескрипторов.  Это весьма удобно - теперь администратору не нужно пересобирать EAR/WAR, достаточно написать deployment plan и выполнить повторный deploy EAR с новым планом.  Deployment plan имеет 2 основные секции - объявление переменных и описание правил замены. При описании правил замены используется XPath. Следующий план меняет значения двух наших контекстных переменных:

<?xml version='1.0' encoding='UTF-8'?>
<deployment-plan xmlns="http://xmlns.oracle.com/weblogic/deployment-plan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/deployment-plan http://xmlns.oracle.com/weblogic/deployment-plan/1.0/deployment-plan.xsd" global-variables="false">
  <application-name>UsingContextParams.ear</application-name>
  <variable-definition>
      <variable>
          <name>stringParamVar</name>
          <value>Changed Value of the String Parameter</value>
      </variable>
     <variable>
          <name>intParamVar</name>
          <value>abracadabra</value>
      </variable> 
 </variable-definition>
  <module-override>
    <module-name>UsingContextParams_ViewController_webapp1.war</module-name>
    <module-type>war</module-type>

    <module-descriptor external="false">
      <root-element>web-app</root-element>
      <uri>WEB-INF/web.xml</uri>
      <variable-assignment>
         <name>stringParamVar</name>
         <xpath>/web-app/context-param/[param-name="myStringParam"]/param-value</xpath>
         <operation>add</operation>
      </variable-assignment>
      <variable-assignment>
         <name>intParamVar</name>
         <xpath>/web-app/context-param/[param-name="myIntParam"]/param-value</xpath>
         <operation>add</operation>
      </variable-assignment>
	  </module-descriptor>
  </module-override>
  <config-root>d:/work/source/adf/_STRUCTURED/Architecture/StoringConfigurationValues/plan</config-root>
</deployment-plan>

Теперь нам достаточно выполнить повторное развертывание приложения с ссылкой на Deployment Plan:










затем повторно обратиться к нашему приложению и убедиться что изменения отразились:














Краткое резюме по использованию данного подхода на практике:

  • удобен, когда настроечных параметров немного и они редко меняются;
  • не требует отдельного хранилища значений параметров (БД, LDAP-каталог и проч.)
  • подходит только для глобальных параметров приложения, без специфичных значений для ролей и отдельных пользователей; 
  • изменение значений параметров требует повторного развертывания приложения;
  • значения сохраняются в не шифрованном виде, что не подойдет для хранения паролей;
Код данного примера можно забрать в GitHub.

2 комментария:

  1. Добрый день! Спасибо за статью.
    Столкнулся с проблемой: при деплое приложения с deployment plan через weblogic console, deployment plan не применяется, остаются параметры из web.xml.
    Если деплоить через библиотеку weblogic.Deployer с указанием deployment plan, изменения подтягиваются и выставляются замененные параметры из deployment plan.
    Вы не знаете, чем вызвана проблема?
    Версия weblogic 10.3.5.0

    ОтветитьУдалить
  2. >Столкнулся с проблемой: при деплое приложения с deployment plan через weblogic console, deployment plan не применяется, остаются параметры из web.xml.

    А где у Вас plan.xml находится? В одном каталоге с ear-ом? Насколько я помню, console подцепляет план если EAR лежет в $SOME_DIR/app, a plan.xml - в $SOME_DIR/plan . См тут http://docs.oracle.com/cd/E15523_01/web.1111/e13702/config.htm#i1060138

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