etiquetas - showcases jsf
Retención de parámetros de cadena de consulta de solicitud GET en el envío de formulario JSF (2)
Tengo 3 páginas:
main.xhtml
-
agreement.xhtml
-
generated.xhtml
El serviceId
necesita dos parámetros para cargar correctamente: serviceId
y site
. Entonces, una url normal se ve así: /app/agreement.xhtml?site=US&serviceId=AABBCC
.
Tengo este botón en agreement.xhtml
<h:form>
<h:commandButton value="Generate License File" action="#{agreement.generateMethod}" />
</h:form>
El bean @RequestScoped
#{agreement}
tiene este método:
public String generateMethod(){
.......
return "generated";
}
Necesito que, al hacer clic, se ejecute el método generateMethod()
y, una vez hecho, el usuario se redirija a la página generated.xhtml
. Lo que sucede es que, al hacer clic, el navegador de páginas envía al usuario a /app/agreement.xhtml
y, dado que no envía los parámetros site
y serviceId
, se bloquea.
Intenté hacer que generateMethod()
devolviera un "generated?faces-redirect=true"
, pero todavía nada. ¿Algunas ideas?
Su generateMethod
tendría que regresar
return "generated?site=US&serviceId=AABBCC&faces-redirect=true";
Incluso puedes reemplazar &
con &
pero escapéalo en tu xhtml.
En su generated.xhtml
puede capturar los parámetros que se están pasando con <f:viewParam>
como este
<f:metadata>
<f:viewParam name="site" value="#{yourBean.site}"/><!--Make sure you have a setter-->
<f:viewParam name="serviceId" value="#{yourBean.serviceId}"/><!--Make sure you have a setter-
</f:metadata>
<h:head>
Su problema concreto se debe a que un JSF <h:form>
envía por defecto al URL de solicitud actual sin ninguna cadena de consulta. Mire más de cerca la salida HTML generada, verá
<form action="/app/agreement.xhtml" ...>
De este modo, debe incluir explícitamente esos parámetros de solicitud usted mismo. Hay varias formas de resolver esto. Si no estaba enviando un redireccionamiento, entonces simplemente podría agregarlos como entradas ocultas al formulario JSF.
<h:form>
<input type="hidden" name="site" value="#{param.site}" />
<input type="hidden" name="site" value="#{param.serviceId}" />
...
</h:form>
Solo que esos parámetros no volverán a aparecer en la URL en la barra de direcciones del navegador. Esto no es un problema si solo estás usando ajax en la misma página. Por <h:inputHidden>
no es adecuado, ya que perderá confusamente su valor cuando se produzca un error de conversión o validación en el formulario.
Para que vuelvan a aparecer en URL, necesitas <f:viewParam>
e includeViewParams
. Para que includeViewParams
funcione, debe declarar lo siguiente en la página de origen agreement.xhtml
...
<f:metadata>
<f:viewParam name="site" value="#{agreement.site}" />
<f:viewParam name="serviceId" value="#{agreement.serviceId}" />
</f:metadata>
... y la página de destino generated.xhtml
:
<f:metadata>
<f:viewParam name="site" value="#{generated.site}" />
<f:viewParam name="serviceId" value="#{generated.serviceId}" />
</f:metadata>
Ahora puede enviar una redirección que incluya los parámetros de vista de la siguiente manera:
public String generateMethod() {
// ...
return "generated?faces-redirect=true&includeViewParams=true";
}
Tenga en cuenta que el bean debe ser @ViewScoped
para mantener vivos esos parámetros entre abrir la página con el formulario y enviar el formulario, también en los errores de validación. De lo contrario, cuando se adhiere a un bean @RequestScoped
, debe retenerlos como <f:param>
en los componentes del comando:
<h:commandButton ...>
<f:param name="site" value="#{generated.site}" />
<f:param name="serviceId" value="#{generated.serviceId}" />
</h:commandButton>
No hay forma de configurarlos para <f:ajax>
dentro de los componentes de entrada, su bean debería realmente ser @ViewScoped
.
Alternativamente, si usa la biblioteca de utilidades JSF OmniFaces , entonces también puede simplemente reemplazar la <h:form>
por <o:form>
siguiente manera (vea también ejemplo de presentación ):
<o:form includeRequestParams="true">
Eso es básicamente todo. Esto generará una <form action>
con la cadena de consulta actual incluida.
<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>
Esos parámetros de solicitud están simplemente disponibles en el mapa de parámetros de solicitud del formulario enviado. No necesita metadatos / parámetros de vista adicionales y tampoco necesita enviar un redireccionamiento y su bean puede mantenerse @RequestScoped
, si es necesario.
public String generateMethod() {
// ...
return "generated";
}
O bien, si está utilizando una biblioteca de "URL bonita" como PrettyFaces o FacesViews o tal vez algo de cosecha propia y tiene la intención de enviarla exactamente a la misma URL que aparece en la barra de direcciones del navegador, puede usar useRequestURI
en useRequestURI
lugar.
<o:form useRequestURI="true">