Для чего могут использоваться <f: metadata>, <f: viewParam> и <f: viewAction>?

Кто-нибудь может прояснить, как мы можем использовать этот фрагмент в целом или, в качестве примера, в реальном мире?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>

1 ответ

Решение

Параметры процесса GET

<f:viewParam> управляет настройкой, преобразованием и проверкой параметров GET. Это как <h:inputText>, но тогда для GET параметров.

Следующий пример

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

делает в основном следующее:

  • Получить значение параметра запроса по имени id,
  • Преобразовать и проверить его при необходимости (вы можете использовать required, validator а также converter атрибуты и гнездо <f:converter> а также <f:validator> в этом вроде как с <h:inputText>)
  • Если преобразование и проверка завершаются успешно, установите его как свойство bean-компонента, представленное #{bean.id} значение, или если value атрибут отсутствует, затем установите его как атрибут запроса на имя id так что это доступно #{id} в представлении.

Поэтому, когда вы открываете страницу как foo.xhtml?id=10 тогда значение параметра 10 получить таким образом в bean-компоненте, прямо перед отображением представления.

Что касается проверки, следующий пример устанавливает параметр в required="true" и допускает значения только от 10 до 20. Любой сбой проверки приведет к отображению сообщения.

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
</f:metadata>
<h:message for="id" />

Выполнение бизнес-действия по параметрам GET

Вы можете использовать <f:viewAction> за это.

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>
<h:message for="id" />

с

public void onload() {
    // ...
}

<f:viewAction> однако является новым с JSF 2.2 (<f:viewParam> уже существует с JSF 2.0). Если вы не можете обновить, то лучше всего использовать <f:event> вместо.

<f:event type="preRenderView" listener="#{bean.onload}" />

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

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

Если вы также хотите пропустить случаи "Преобразование / проверка завершились неудачей", сделайте следующее:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

С помощью <f:event> этот способ по сути является обходным путем, именно поэтому <f:viewAction> был введен в JSF 2.2.


Передать параметры просмотра в следующий вид

Вы можете "пропустить" параметры просмотра в ссылках навигации, установив includeViewParams приписывать true или добавив includeViewParams=true параметр запроса.

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">

который генерирует с вышеупомянутым <f:metadata> пример в основном по следующей ссылке

<a href="next.xhtml?id=10">

с исходным значением параметра.

Этот подход требует только того, чтобы next.xhtml также имеет <f:viewParam> на тот же параметр, иначе он не будет передан.


Используйте GET формы в JSF

<f:viewParam> также может использоваться в сочетании с GET-формами в формате "обычный HTML".

<f:metadata>
    <f:viewParam id="query" name="query" value="#{bean.query}" />
    <f:viewAction action="#{bean.search}" />
</f:metadata>
...
<form>
    <label for="query">Query</label>
    <input type="text" name="query" value="#{empty bean.query ? param.query : bean.query}" />
    <input type="submit" value="Search" />
    <h:message for="query" />
</form>
...
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
     ...
</h:dataTable>

В основном это @RequestScoped боб:

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}

Обратите внимание, что <h:message> для <f:viewParam>, а не простой HTML <input type="text">! Также обратите внимание, что отображается входное значение #{param.query} когда #{bean.query} пусто, потому что в противном случае отправленное значение вообще не будет отображаться при ошибке проверки или преобразования. Обратите внимание, что эта конструкция недопустима для компонентов ввода JSF (она делает это уже "под прикрытием").


Смотрите также:

Отправляйте параметры из представления в другое представление, из представления отправителя в представление получателя используйте viewParam и includeViewParams=true

В отправителе

  1. Объявите параметры для отправки. Мы можем отправить String, Object,…

Sender.xhtml

<f:metadata>
      <f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
  1. Мы отправим идентификатор параметра, он будет включен в “includeViewParams=true” в ответ Строка события нажатия кнопки Нажмите кнопку, чтобы запустить senderMB.clickBtnDetail(dto) с dto от senderMB._arrData

Sender.xhtml

<p:dataTable rowIndexVar="index" id="dataTale"value="#{senderMB._arrData}" var="dto">
      <p:commandButton action="#{senderMB.clickBtnDetail(dto)}" value="見る" 
      ajax="false"/>
</p:dataTable>

В senderMB.clickBtnDetail(dto) мы назначаем _strID аргументом, полученным из события кнопки (dto), здесь это Sender_DTO и присваиваем senderMB._strID

Sender_MB.java
    public String clickBtnDetail(sender_DTO sender_dto) {
        this._strID = sender_dto.getStrID();
        return "Receiver?faces-redirect=true&includeViewParams=true";
    }

Ссылка при нажатии станет http://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*

В Recever

  1. Получить viewParam Receiver.xhtml. В Receiver мы объявляем f:viewParam для получения параметра из запроса на получение (получение), имя параметра получателя должно совпадать с именем отправителя (страница)

Receiver.xhtml

<f:metadata><f:viewParam name="ID" value="#{receiver_MB._strID}"/></f:metadata>

Он получит идентификатор параметра из представления отправителя и назначит Receiver_MB._strID

  1. Использование viewParam В Receiver мы хотим использовать этот параметр в sql-запросе перед отрисовкой страницы, чтобы использовать событие preRenderView. Мы не собираемся использовать конструктор, потому что конструктор будет вызываться до получения viewParam. Итак, мы добавляем

Receiver.xhtml

<f:event listener="#{receiver_MB.preRenderView}" type="preRenderView" />

в f: тег метаданных

Receiver.xhtml

<f:metadata>
<f:viewParam name="ID" value="#{receiver_MB._strID}" />
<f:event listener="#{receiver_MB.preRenderView}"
            type="preRenderView" />
</f:metadata>

Теперь мы хотим использовать этот параметр в нашем методе чтения базы данных, он доступен для использования

Receiver_MB.java
public void preRenderView(ComponentSystemEvent event) throws Exception {
        if (FacesContext.getCurrentInstance().isPostback()) {
            return;
        }
        readFromDatabase();
    }
private void readFromDatabase() {
//use _strID to read and set property   
}
Другие вопросы по тегам