Журнал аудита для приложения JSF - возможно ли глобальное значение valueChangeListener? - PullRequest
4 голосов
/ 19 сентября 2011

Я пытаюсь реализовать функциональность журнала аудита для моего веб-приложения, которое записывает:

  • lastModified (отметка времени)
  • ifiedBy (информация о пользователе)
  • userComment (причина изменения значения)

для каждого из моих полей ввода (поля ввода распределены по нескольким формам с разными базовыми компонентами и разными классами valueHolder).

Первые два (lastModified и updatedBy) легко выполняются с помощью методов JPA AuditListener и @PrePersit и @PreUpdate.

Третий вариант немного сложнее, поскольку требует взаимодействия с пользователем. Лучше всего будет диалог, который запрашивает комментарий пользователя.

Итак, есть (как минимум) две открытые проблемы: Могу ли я установить «глобальное» значение valueChangeListener для всех полей ввода в моем приложении? Возможно ли это без присоединения <f:valueChangeListener> к каждому входному компоненту? Второе: как я могу получить комментарий пользователя. Моя идея состоит в том, чтобы поместить p:dialog в шаблон моей веб-страницы, но этот диалог должен знать, из какого компонента ввода он вызывается.

1 Ответ

4 голосов
/ 19 сентября 2011

Могу ли я установить "глобальный" valueChangeListener для всех полей ввода в моем приложении? Возможно ли это без подключения к каждому входному компоненту?

Да, с SystemEventListener, которые выполняются в течение PreRenderViewEvent. Вам нужно пройтись по дереву компонентов, полученному FacesContext#getViewRoot(), чтобы найти все компоненты, которые являются instanceofEditableValueHolder (или что-то более детальное), а затем добавить new YourValueChangeListener() по методу addValueChangeListener(). См. Также этот ответ о том, как зарегистрировать прослушиватель системных событий: Как применить фазелистенизер JSF2 после сборки viewroot?


Второе: как я могу получить комментарий пользователя. Моя идея состоит в том, чтобы добавить p: диалог в шаблон моей веб-страницы, но этот диалог должен знать, из какого компонента ввода он вызывается.

Вы могли бы в YourValueChangeListener#processValueChange() установить рассматриваемый компонент как свойство некоторого запроса или просмотра области, которую вы захватили, на evaluateExpressionGet().

Recorder recorder = (Recorder) context.getApplication().evaluateExpressionGet(context, "#{recorder}", Recorder.class);
recorder.setComponent(event.getComponent());
// ...

Он выполнит EL и автоматически создаст бин в своей области видимости, если это необходимо. Бин, в свою очередь, должен также содержать свойство, представляющее комментарий пользователя. Наконец, вы можете использовать его в своем <p:dialog>.

<p>You have edited #{recorder.component.label}, please mention the reason:</p>
...
<h:inputText value="#{recorder.comment}" />
...