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

97

Qual é a diferença entre definir parâmetros de visualização como este:

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

E definindo a propriedade no ManagedBean assim:

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

Respostas:

144

<f:viewParam>:

  • Define o valor apenas durante a fase de atualização dos valores do modelo (desde que se estenda UIInput).

  • O valor definido não está disponível durante @PostConstruct, então você precisa de um adicional <f:event type="preRenderView" listener="#{bean.init}" />dentro do <f:metadata>para fazer a inicialização / pré-carregamento com base nos valores definidos. Desde o JSF 2.2 você pode usar <f:viewAction>para isso.

  • Permite conversão / validação aninhada <f:converter>e <f:validator>mais refinada. Até mesmo um <h:message>pode ser anexado.

  • Pode ser incluído como string de consulta GET usando o includeViewParamsatributo de <h:link>ou o includeViewParams=trueparâmetro de solicitação em qualquer URL.

  • Pode ser usado em um @RequestScopedbean, mas requer que o bean o seja @ViewScopedse você quiser que os parâmetros de visualização sobrevivam a quaisquer falhas de validação causadas por formulários incluídos na visualização, caso contrário, você precisa reter manualmente todos os parâmetros de solicitação para as solicitações subsequentes <f:param>no comando componentes.

Exemplo :

<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" />

com

private User user;

e um @FacesConverter("userConverter"). Invocar a página por http://example.com/context/user.xhtml?id=123 passará o idparâmetro pelo conversor e definirá o Userobjeto como uma propriedade de bean.


@ManagedProperty:

  • Define o valor imediatamente após a construção do bean.

  • O valor definido está disponível durante o @PostConstructqual permite uma inicialização / pré-carregamento fácil de outras propriedades com base no valor definido.

  • Não permite conversão / validação declarativa em vista.

  • A propriedade gerenciada de #{param}não é permitida em beans com um escopo mais amplo do que o escopo de solicitação, portanto, o bean deve ser @RequestScoped.

  • Se você confiar que uma propriedade gerenciada estará #{param}presente nas solicitações POST subsequentes, será necessário incluí-la <f:param>nos UICommandcomponentes.

Exemplo :

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

private User user;

@EJB
private UserService userService;

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

Mas você mesmo precisa gerenciar a validação sempre que userestiver nullmexendo com FacesContext#addMessage()ou algo assim.


Você pode usar ambos quando @PostConstructe includeViewParamsforem obrigatórios. Você só não poderá mais aplicar conversão / validação de baixa granularidade.


Veja também:

BalusC
fonte
1
Há outra alternativa para recuperar os parâmetros de solicitação em casos excepcionais: FacesContext.getCurrentInstance (). GetExternalContext (). GetRequestParameterMap (). Get ("parametername");
angelcervera de
1
@angel: Somente quando o bean tem um escopo mais amplo do que o escopo da solicitação, o que torna @ManagedPropertyum parâmetro de solicitação impossível.
BalusC de
oi @BalusC, confio no valor de id recuperado de param.id usando managedproperty em um segundo post. Como posso incluí-lo usando f: param? muito obrigado
sys_debug
1
@thufir: É definido durante a fase de atualização dos valores do modelo. O postconstruct é executado muito antes disso, diretamente após a construção do bean e a injeção de dependência. Ele está disponível no método listener que é invocado por <f:event type="preRenderView">ou no próximo JSF 2.2 <f:viewAction>.
BalusC de
6

2 outras diferenças:

  • @ManagedPropertyé utilizável apenas com beans gerenciados por JSF, não com beans gerenciados por CDI ( @Named);
    • <f:viewParam> funciona apenas com parâmetros de solicitações GET.
user1643352
fonte
1
Portanto, você pode usar a anotação: org.omnifaces.cdi.Param
dforce