ViewParam vs @ManagedProperty (value = "# {param.id}" )

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

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

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

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

Ответ 1

<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 bean, но для этого требуется bean @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 как свойство bean.


@ManagedProperty:

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

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

  • Не разрешает декларативное преобразование/валидацию в представлении.

  • Управляемое свойство #{param} не разрешено на beans с более широкой областью действия, чем область запроса, поэтому bean требуется @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, путем fidingling с FacesContext#addMessage() или что-то в этом роде.


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


См. также:

Ответ 2

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

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