ViewParam против @ManagedProperty(value = "#{param.id}")

В чем разница между определением параметров просмотра следующим образом:

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

И определяем свойство в ManagedBean следующим образом:

@ManagedProperty(value = "#{param.id}")
private Integer id;

2 ответа

Решение

<f:viewParam>:

  • Устанавливает значение только на этапе обновления значений модели (поскольку оно расширяется UIInput).

  • Установленное значение недоступно во время @PostConstruct, так что вам нужно дополнительное <f:event type="preRenderView" listener="#{bean.init}" /> внутри <f:metadata> выполнить инициализацию / предварительную загрузку на основе заданных значений. Начиная с JSF 2.2 вы можете использовать <f:viewAction> вместо этого.

  • Позволяет для вложенных <f:converter> а также <f:validator> для более детального преобразования / проверки. Даже <h:message> можно прикрепить

  • Может быть включен как строка запроса GET, используя includeViewParams атрибут <h:link> или же includeViewParams=true Параметр запроса в любом URL.

  • Может быть использован на @RequestScoped боб, но для этого требуется боб @ViewScoped если вы хотите, чтобы параметры представления выдерживали любые сбои проверки, вызванные формами, заключенными в представление, в противном случае вам нужно вручную сохранить все параметры запроса для последующих запросов <f:param> в компонентах команды.

Пример:

<f:metadata>
    <f:viewParam id="user_id" name="id" value="#{bean.user}"
        required="true" requiredMessage="Invalid page access. Please use a link from within the system."
        converter="userConverter" converterMessage="Unknown user ID."
    />
</f:metadata>
<h:message for="user_id" />

с

private User user;

и @FacesConverter("userConverter"), Страница вызова по http://example.com/context/user.xhtml?id=123 пройдет id параметр через конвертер и установить User Объект как свойство бина.


@ManagedProperty:

  • Устанавливает значение сразу после построения бина.

  • Заданное значение доступно во время @PostConstruct что позволяет легко инициализировать / предварительно загружать другие свойства на основе заданного значения.

  • Не допускает декларативного преобразования / проверки в представлении.

  • Управляемая собственность #{param} не допускается на бобах с более широкой областью, чем область запроса, поэтому бин должен быть @RequestScoped,

  • Если вы полагаетесь на управляемое свойство #{param} присутствовать в последующих запросах POST, то вам нужно включить его как <f:param> в UICommand компоненты.

Пример:

@ManagedProperty("#{param.id}")
private Long id;

private User user;

@EJB
private UserService userService;

@PostConstruct
public void init() {
    user = userService.find(id);
}

Но вы должны сами управлять проверкой всякий раз, когда user является null возиться с FacesContext#addMessage() или что-то.


Вы можете использовать их оба, когда оба @PostConstruct а также includeViewParams обязательны. Вы только больше не сможете применять детализированное преобразование / проверку.


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

2 других отличия:

  • @ManagedProperty может использоваться только для bean-компонентов, управляемых JSF, но не для bean-компонентов, управляемых CDI (@Named);
    • <f:viewParam> работает только с параметрами запросов GET.
Другие вопросы по тегам