Como você passa os parâmetros de visualização ao navegar por uma ação no JSF2?
Pergunta
De uma ação no meu feijão, estou tentando redirecionar para outra página esperando um parâmetro de exibição. Qual é a maneira recomendada de fazer isso no JSF2?
Por exemplo, digamos que minha página de origem é:http: //localhost/page1.xhtml
Possui um botão de comando que chama uma ação:
<h:commandButton value="submit" action="#{myBean.submit}" />
onde meu feijão se parece:
@ManagedBean
@RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success";
}
E agora, eu quero o retorno da ação 'submeter' para navegar parahttp: //localhost/page2.xhtml? id = 2
Eu tentei fazer isso com uma par-param no meu caso de navegação, mas com resultados estranhos. O snippet FACES-Config parece o seguinte:
<navigation-rule>
<from-view-id>/page1.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect>
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
</navigation-case>
</navigation-rule>
O comportamento estranho é, mesmo que o MyBean esteja definido para solicitar escopo, ele chama apenas MyBean.getId () na primeira vez em que carrego meu aplicativo e reutiliza o mesmo valor para todas as chamadas subsequentes, produzindo parâmetros de exibição incorretos para a página2.
Portanto, estou procurando uma maneira melhor de fazer isso ou uma razão/solução para o motivo pelo qual a par-param não está sendo solicitada do meu feijão a cada vez.
Solução
A coisa não intuitiva sobre os parâmetros de aprovação no JSF é que você não decide o que enviar (na ação), mas o que deseja receber (na página de destino).
Quando você faz uma ação que termina com um redirecionamento, os metadados da página de destino são carregados e todos os parâmetros necessários são lidos e anexados à URL como params.
Observe que esse é exatamente o mesmo mecanismo que com qualquer outra ligação do JSF: você não pode ler o valor do InputText de um lugar e escrevê -lo em outro lugar. A expressão de valor definida no ViewParam é usada para leitura (antes do redirecionamento) e para escrever (após o redirecionamento).
Com o seu feijão, você acabou de fazer:
@ManagedBean
@RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success?faces-redirect=true&includeViewParams=true";
}
// setter and getter for id
Se o lado receptor tiver:
<f:metadata>
<f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>
Isso fará exatamente o que você deseja.
Outras dicas
Sem uma solução mais agradável, o que eu encontrei para funcionar é simplesmente construir minha corda de consulta no retorno do feijão:
public String submit() {
// Do something
return "/page2.xhtml?faces-redirect=true&id=" + id;
}
Não é a mais flexível das soluções, mas parece funcionar como eu quero.
Também usando essa abordagem para limpar o processo de construção da sequência de consultas:http://www.warski.org/blog/?p=185
Confira estes:
- http://andyschwartz.wordpress.com/2009/07/31/whats-new-n-jsf-2/#get
- http://mkblog.exadel.com/2010/07/learning-jsf2-page-params-and-page-actions/
Você vai precisar de algo como:
<h:link outcome="success">
<f:param name="foo" value="bar"/>
</h:link>
...e...
<f:metadata>
<f:viewParam name="foo" value="#{bean.foo}"/>
</f:metadata>
Julgando de esta página, algo assim pode ser mais fácil:
<managed-bean>
<managed-bean-name>blog</managed-bean-name>
<managed-bean-class>com.acme.Blog</managed-bean-class>
<managed-property>
<property-name>entryId</property-name>
<value>#{param['id']}</value>
</managed-property>
</managed-bean>
Você pode fazer isso usando as Primefaces como esta:
<p:button
outcome="/page2.xhtml?faces-redirect=true&id=#{myBean.id}">
</p:button>
Basta adicionar o atributo visto para redirecionar a tag como abaixo:
<redirect include-view-params="true">
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
Aqui são alguns exemplos de navegação.
Uma solução sem referência a um feijão:
<h:button value="login"
outcome="content/configuration.xhtml?i=1" />
No meu projeto, eu precisava dessa abordagem:
<h:commandButton value="login"
action="content/configuration.xhtml?faces-redirect=true&i=1" />