java - vista - ¿Cómo crear una solicitud GET con parámetros, usando JSF y reglas de navegación?
menu de navegacion jsf (4)
¿Hay alguna manera de crear un enlace html utilizando h: outputLink, otra etiqueta o código JSF para crear una solicitud sin caras (HTTP GET) con parámetros de solicitud?
Por ejemplo, tengo la siguiente regla de navegación
<navigation-rule>
<navigation-case>
<from-outcome>showMessage</from-outcome>
<to-view-id>/showMessage.jsf</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
En mi página me gustaría mostrar el siguiente código html:
<a href="/showMessage.jsf?msg=23">click to see the message</a>
Podría simplemente escribir el código html en la página, pero quiero usar la regla de navegación para tener todas las URL definidas en un único archivo configurable.
¿Has considerado una forma?
<h:form>
<h:commandLink value="Click to see the message" action="#{handler.outcome}" />
<h:inputHidden id="msgId" value="#{bean.msgId}"/>
</h:form>
Esta es una idea interesante. Me gustaría saber cómo se desarrolla en la práctica.
Obteniendo las reglas de navegación
La navegación es manejada por NavigationHandler . Conseguir NavigationHandler no es difícil, pero la API no expone las reglas que usa.
Como yo lo veo, puedes:
- analizar faces-config.xml en la inicialización y almacenar las reglas en el contexto de la aplicación ( fácil )
- implementa tu propio NavigationHandler que ignora las reglas en faces-config.xml o las complementa con tu propio archivo de reglas y expone su conjunto de reglas de alguna manera ( funciona, pero toma un poco de trabajo )
- simula tu propio FacesContext y pásalo al controlador de navegación existente (es realmente difícil hacer que dos objetos FacesContext coexistan en el mismo hilo y sean extremadamente ineficientes )
Ahora, usted tiene otro problema también. ¿Dónde vas a guardar las asignaciones para buscar las vistas? ¿Codificarlos en los frijoles?
Usando las reglas de navegación
De forma manual, puedo pensar en dos maneras en que podrías construir URL que contengan parámetros desde el back-end. Ambos implican definir un bean de algún tipo.
<managed-bean>
<managed-bean-name>navBean</managed-bean-name>
<managed-bean-class>foo.NavBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
Fuente:
package foo;
import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
public class NavBean implements Serializable {
private String getView() {
String viewId = "/showMessage.faces"; // or look this up somewhere
return viewId;
}
/**
* Regular link to page
*/
public String getUrlLink() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
String viewId = getView();
String navUrl = context.getExternalContext().encodeActionURL(
extContext.getRequestContextPath() + viewId);
return navUrl;
}
/**
* Just some value
*/
public String getValue() {
return "" + System.currentTimeMillis();
}
/**
* Invoked by action
*/
public String invokeRedirect() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
String viewId = getView();
try {
String charEncoding = extContext.getRequestCharacterEncoding();
String name = URLEncoder.encode("foo", charEncoding);
String value = URLEncoder.encode(getValue(), charEncoding);
viewId = extContext.getRequestContextPath() + viewId + ''?'' + name
+ "=" + value;
String urlLink = context.getExternalContext().encodeActionURL(
viewId);
extContext.redirect(urlLink);
} catch (IOException e) {
extContext.log(getClass().getName() + ".invokeRedirect", e);
}
return null;
}
}
OBTENER
Para una solicitud GET, puede usar los UIParameters para establecer los valores y dejar que el procesador construya la lista de parámetros.
<h:outputLink value="#{navBean.urlLink}">
<f:param name="foo" value="#{navBean.value}" />
<h:outputText value="get" />
</h:outputLink>
ENVIAR
Si desea configurar el URL para una vista durante una acción POST, puede hacerlo utilizando un redireccionamiento en una acción (invocado por un botón o commandLink).
<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
<h:outputText value="post" />
</h:commandLink>
Notas
Tenga en cuenta que ExternalContext.encodeActionURL se utiliza para codificar la cadena. Esta es una buena práctica para producir código que sea portátil en todos los contextos (portlets, etcétera). Utilizaría encodeResourceURL si estuviera codificando un enlace a una imagen o descarga un archivo.
Podría usar un comandoLink con etiquetas param anidadas. Esto es básicamente lo mismo que Hubbardr dijo arriba:
<h:form>
<h:commandLink value="click here" action="${handler.outcome}">
<f:param name="msgId" value="${bean.id}" />
</h:commandLink>
</h:form>
Luego, en tu bean de respaldo debes hacer lo siguiente:
Map requestMap = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap();
String msgId = (String) requestMap.get("msgId");
Y luego haz lo que necesites hacer.
¿Intentó usar PrettyFaces? Es una extensión JSF de código abierto diseñada específicamente para hacer que las páginas JSF / JSF con favoritos sean posibles con solicitudes GET.
PrettyFaces - SEO, parámetros dinámicos, marcadores y navegación para JSF / JSF2