¿Cómo crear una solicitud GET con parámetros, utilizando JSF y las reglas de navegación?

StackOverflow https://stackoverflow.com/questions/138617

  •  02-07-2019
  •  | 
  •  

Pregunta

¿Hay una manera de crear un enlace html usando 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 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 solo archivo configurable.

¿Fue útil?

Solución

Esta es una idea interesante. Tendría curiosidad por saber cómo funciona en la práctica.

Cómo obtener las reglas de navegación

La navegación se maneja mediante NavigationHandler . No es difícil obtener el NavigationHandler, pero la API no expone las reglas que utiliza.

Como yo lo veo, puedes:

  1. analiza faces-config.xml en la inicialización y almacena las reglas en el contexto de la aplicación ( fácil )
  2. implemente su propio NavigationHandler que ignora las reglas en faces-config.xml o las complementa con su propio archivo de reglas y expone su conjunto de reglas de alguna manera ( es viable, pero requiere un poco de trabajo )
  3. se burla de su propio FacesContext y páselo al controlador de navegación existente ( es realmente difícil hacer que coexistan dos objetos FacesContext en el mismo hilo y extremadamente ineficientes )

Ahora, tienes otro problema también. ¿Dónde vas a guardar las asignaciones para buscar las vistas? ¿Codificarlos en los frijoles?

Utilizando las reglas de navegación

De la mano, puedo pensar en dos maneras en que podría construir URLs que contienen parámetros desde el back-end. Ambos implican la definición de 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;
    }

}

GET

Para una solicitud GET, puede usar los parámetros UIP para establecer los valores y permitir que el renderizador cree la lista de parámetros.

<h:outputLink value="#{navBean.urlLink}">
    <f:param name="foo" value="#{navBean.value}" />
    <h:outputText value="get" />
</h:outputLink>

POST

Si desea establecer la URL en una vista durante una acción POST, puede hacerlo utilizando una redirección en una acción (invocada mediante un botón o un enlace de comando).

<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 contextos (portlets, etcétera). Usaría encodeResourceURL si codificara un enlace a una imagen o archivo de descarga.

Otros consejos

¿Ha intentado usar PrettyFaces? Es una extensión JSF de código abierto diseñada específicamente para hacer que las páginas JSF / JSF que se pueden marcar con posibles solicitudes GET.

PrettyFaces - SEO, parámetros dinámicos, Marcadores y navegación para JSF / JSF2

¿Ha considerado un formulario?

<h:form>
    <h:commandLink value="Click to see the message" action="#{handler.outcome}" />
    <h:inputHidden id="msgId" value="#{bean.msgId}"/>
</h:form>

Puedes usar un enlace de comando con etiquetas param anidadas. Esto es básicamente lo mismo que hubbardr dijo anteriormente:

<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:

Map requestMap = FacesContext.getCurrentInstance()
                 .getExternalContext().getRequestParameterMap();
String msgId = (String) requestMap.get("msgId");

Y luego haz lo que necesites hacer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top