Доступ и использование файлов .jsf из базы данных - PullRequest
4 голосов
/ 01 июня 2011

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

Другими словами: я хотел бы сохранить большую часть моих страниц JSF в базе данных и хотел бы, чтобы JSF использовала базу данных в качестве источника данных для получения файлов JSF.

Я долго думал о решении и нашел несколько возможных путей. Однако я не смог реализовать ни один из них.

  1. Всякий раз, когда необходимо добавить / удалить новую страницу: манипулируйте файлами в пути к классам (например, удалите или добавьте файл в файл .war)
  2. Расширение пути к классу веб-приложения, чтобы оно могло получать файлы из определенного во время выполнения местоположения (т. Е. / Tmp или напрямую, используя соединение с базой данных)
  3. Предоставить JSF способ поиска ресурсов другим способом (это не представляется возможным?)

Мое окружение:

  • Java SE 6
  • Причал в качестве контейнера сервлета
  • Mojarra как реализация jsf

Теперь мой вопрос:

Может ли кто-нибудь позволить JSF находить страницы в месте, отличном от пути к классам по умолчанию, предпочтительно в базе данных?

Любой ответ с благодарностью!

Ответы [ 2 ]

2 голосов
/ 01 июня 2011

1: всякий раз, когда необходимо добавить / удалить новую страницу: манипулируйте файлами в пути к классам (например, удалите или добавьте файл в файл .war)

Это определенно возможно, если WAR расширена.Я не уверен насчет Jetty, но он работает для меня с Mojarra 2.x на Tomcat 7 и Glassfish 3. Достаточно просто записать файл в расширенную папку WAR обычным способом Java IO.

File file = new File(servletContext.getRealPath("/foo.xhtml"));

if (!file.exists()) {
    OutputStream output = new FileOutputStream(file);

    try {
        output.write(bytes); // Can be bytes from DB.
    } finally {
        output.close();
    }
}

Этонеобходимо выполнить до того, как наступит FacesServlet. A Filter - идеальное место.См. Также этот связанный ответ:


2: расширениепуть к классу веб-приложения, чтобы он мог получать файлы из определенного во время выполнения местоположения (т. е. / tmp или напрямую, используя подключение к базе данных)

Вы можете упаковать файлы Facelets в файл JARи поместите его в classpath и предоставьте Facelets ResourceResolver, который обслуживает файлы из JAR, если в WAR нет совпадений.Вы можете найти полные примеры кода в следующих ответах:


3: Предоставить JSF способ поиска ресурсов другим способом (это кажется невозможным?)

У вас достаточно игровой комнаты на заказ ResourceResolver.

0 голосов
/ 01 июня 2011

Хороший вопрос. Ответ BalusC - как всегда - полный и правильный.

Однако, если вы хотите создать приложение, в котором графический интерфейс построен динамически, есть способ, который может помочь вам лучше (в зависимости от того, чего вы действительно хотите достичь).

Представления JSF похожи на формы Swing - они представляют собой просто набор JavaBeans (tm), склеенных вместе. Большая разница состоит в том, что когда поле связано с выражением EL, вы не используете стандартные методы доступа, а скорее используете специальный метод (setValueExpression).

Это означает, что вы можете создать свой графический интерфейс из объектов (конкретные классы можно найти в javax.faces.component.html) чисто программным способом, а затем использовать атрибут привязки, чтобы отобразить его на странице. Что-то вроде:

<h:form>
    <h:panelGrid binding="#{formBuilder.component}"/>
</h:form>

А затем в управляемой форме bean-компонента Builder:

@PostConstruct
public void init() {
    HtmlInputText hit = new HtmlInputText();
    // properties are easy:
    hol.setStyle("border: 2px solid red");
    // binding is a bit harder:
    hit.setValueExpression("value", expression("#{test.counter}", String.class));

    HtmlOutcomeTargetLink hol = new HtmlOutcomeTargetLink();
    hol.setValue("link leading to another view");
    hol.setOutcome("whatever");

    component = new UIPanel();
    component.getChildren().add(hit);
    component.getChildren().add(hol);
}

private ValueExpression expression(String s, Class c){
    return FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(
            FacesContext.getCurrentInstance().getELContext(),
            s, c
    );
}

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

  • создать объектную модель вашего GUI
  • сопоставить модель с базой данных (в спящем режиме или с другой формой)
  • написать какой-нибудь адаптер или мост для построения объектов JSF из вашей объектной модели
  • создать управляемый компонент, который получает идентификатор формы, извлекает соответствующую форму из базы данных, строит из нее панель JSF и представляет ее как свойство, готовое для привязки.

Таким образом, вы можете иметь только один статический xhtml с одним тегом и использовать его для представления любого количества динамических форм.

Как я уже сказал, этот метод может быть лучше, чем просто хранение файлов, но не обязательно. Если вы просто хотите избавить себя от необходимости повторного развертывания, это является огромным излишним (опять же, вам НЕ нужно повторно развертывать приложения JSF просто для изменения форм). Если, с другой стороны, ваша цель состоит в том, чтобы иметь что-то вроде пользовательских и отредактированных форм, хорошей идеей может быть хорошая объектная модель и ее правильное хранение.

Удары впереди будут:

  • навигация (возможно, подойдет пользовательский обработчик навигации?)
  • проблемы с генерацией простого HTML
  • возможно, некоторые проблемы с жизненным циклом видимых форм
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...