Как создать запрос GET с параметрами, используя JSF и правила навигации?

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

  •  02-07-2019
  •  | 
  •  

Вопрос

Есть ли способ создать ссылку html, используя h:outputLink, другой тег или код JSF для создания запроса без лиц (HTTP GET) с параметрами запроса?

Например, у меня есть следующее правило навигации

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

На моей странице я хотел бы вывести следующий HTML-код:

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

Я мог бы просто написать HTML-код на странице, но я хочу использовать правило навигации, чтобы все URL-адреса были определены в одном настраиваемом файле.

Это было полезно?

Решение

Это интересная идея.Мне было бы интересно узнать, как это происходит на практике.

Получение правил навигации

Навигацией занимается Навигационный обработчик.Получить NavigationHandler несложно, но API не раскрывает используемые им правила.

Насколько я понимаю, вы можете:

  1. проанализировать Face-config.xml при инициализации и сохранить правила в контексте приложения (легкий)
  2. реализовать свой собственный NavigationHandler, который игнорирует правила в face-config.xml или дополняет их собственным файлом правил и каким-то образом раскрывает свой набор правил (работоспособно, но требует немного работы)
  3. издеваться над своим собственным ЛицаКонтекст и передаем его существующему обработчику навигации (действительно сложно заставить два объекта FacesContext сосуществовать в одном потоке и крайне неэффективно)

Теперь у вас есть еще одна проблема.Где вы собираетесь хранить сопоставления для поиска представлений?Жестко запрограммировать их в bean-компонентах?

Использование правил навигации

Я могу придумать два способа создания URL-адресов, содержащих параметры, из серверной части.Оба предполагают определение какого-либо компонента.

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

Источник:

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 вы можете использовать UIParameters, чтобы установить значения и позволить средству визуализации построить список параметров.

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

ПОЧТА

Если вы хотите установить URL-адрес для представления во время действия POST, вы можете сделать это с помощью перенаправления в действии (вызываемого кнопкой или командной ссылкой).

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

Примечания

Обратите внимание, что ВнешнийКонтекст.encodeActionURL используется для кодирования строки.Это хорошая практика для создания кода, который можно переносить в разных контекстах (портлетах и ​​т. д.).Вы бы использовали кодироватьResourceURL если вы кодировали ссылку на изображение или файл загрузки.

Другие советы

Пробовали использовать PrettyFaces?Это расширение JSF с открытым исходным кодом, разработанное специально для возможности добавления в закладки страниц JSF/JSF с запросами GET.

PrettyFaces — SEO, динамические параметры, закладки и навигация для JSF/JSF2

Вы рассматривали форму?

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

Вы можете использовать команду CommandLink с вложенными тегами параметров.По сути, это то же самое, что сказал Хаббардр выше:

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

Затем в вашем компоненте поддержки вам нужно сделать:

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

А потом делайте все, что вам нужно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top