Pergunta

Existe uma maneira de criar um link HTML usando h:? OutputLink, outra tag JSF ou código para criar um não rostos solicitar (HTTP GET) com parâmetros de solicitação

Por exemplo, eu tenho o seguinte navigation-rule

<navigation-rule>
    <navigation-case>
        <from-outcome>showMessage</from-outcome>
        <to-view-id>/showMessage.jsf</to-view-id>
        <redirect/>
    </navigation-case>
</navigation-rule>

Na minha página que eu gostaria de saída o seguinte código html:

<a href="/showMessage.jsf?msg=23">click to see the message</a>

Eu poderia simplesmente escrever o código HTML na página, mas eu quero usar a regra de navegação, a fim de ter todas as urls definidos em um único arquivo configurável.

Foi útil?

Solução

Esta é uma ideia interessante. Eu seria curioso para saber como ele garimpa para fora na prática.

Obter as regras de navegação

A navegação é tratada pelo NavigationHandler . Conseguir o NavigationHandler não é difícil, mas a API não expõe as regras que utiliza.

A meu ver, você pode:

  1. de análise faces-config.xml na inicialização e armazenar as regras no contexto de aplicação ( fácil )
  2. implementar seu próprio NavigationHandler que ignora as regras em faces-config.xml ou suplementos los com o seu próprio arquivo de regras e expõe o seu conjunto de regras de alguma forma ( viável, mas leva um pouco de trabalho )
  3. zombar seu próprio FacesContext e passá-lo para o manipulador de navegação existente ( realmente difícil fazer dois FacesContext objeto coexistem na mesma linha e extremamente ineficiente )

Agora, você tem um outro problema também. Onde você está indo para manter os mapeamentos para procurar os pontos de vista? Codificar-los no feijão?

Usando as regras de navegação

Off lado, eu posso pensar de duas maneiras que você poderia construir URLs contendo parâmetros do back-end. Ambos envolvem a definição de um feijão de algum 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>

Fonte:

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 um pedido GET, você pode usar as UIParameters para definir os valores e deixe a construção renderizador a lista de parâmetros.

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

POST

Se você deseja definir o URL para uma visão durante uma ação POST, você pode fazê-lo usando um redirecionamento em uma ação (chamado por um botão ou commandLink).

<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
    <h:outputText value="post" />
</h:commandLink>

Notas

Note que ExternalContext.encodeActionURL é usado para codificar a string. Esta é uma boa prática para a produção de código que é portátil através de contextos (portlets, etc.). Você usaria encodeResourceURL se você estivesse codificando um link para um arquivo de imagem ou download.

Outras dicas

Tentei usar PrettyFaces? É uma extensão JSF de código aberto projetado especificamente para tornar as páginas JSF bookmarkable / JSF com GET solicita possível.

PrettyFaces - SEO, parâmetros dinâmicos, marcadores e navegação para JSF / JSF2

Você considerou um formulário?

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

Você pode usar um commandLink com etiquetas param aninhadas. Este é basicamente o mesmo que hubbardr disse acima:

<h:form>
  <h:commandLink value="click here" action="${handler.outcome}">
    <f:param name="msgId" value="${bean.id}" />
  </h:commandLink>
</h:form>

Então em seu bean de apoio que você precisa fazer:

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

E, em seguida, fazer o que você precisa fazer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top