Ответ 1
Это интересная идея. Мне было бы интересно узнать, как это происходит на практике.
Получение правил навигации
Навигация осуществляется с помощью NavigationHandler. Удержание NavigationHandler не сложно, но API не раскрывает правила, которые он использует.
Как я вижу, вы можете:
- parse faces-config.xml при инициализации и хранении правил в контексте приложения (легко)
- реализовать свой собственный NavigationHandler, который игнорирует правила в faces-config.xml или дополняет их собственным файлом правил и каким-то образом предоставляет свой набор правил (работоспособный, но требует немного работы).
- mock your FacesContext и передать его существующему обработчику навигации (действительно сложно сделать два объекта FacesContext сосуществовать в одном потоке и чрезвычайно неэффективное)
Теперь у вас еще одна проблема. Где вы собираетесь хранить сопоставления для просмотра взглядов? Скопируйте их в beans?
Использование правил навигации
Сразу, я могу подумать о двух способах создания URL-адресов, содержащих параметры, из внутреннего интерфейса. Оба они включают определение bean.
<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
Для запроса GET вы можете использовать UIParameters для установки значений и позволить рендереру построить список параметров.
<h:outputLink value="#{navBean.urlLink}">
<f:param name="foo" value="#{navBean.value}" />
<h:outputText value="get" />
</h:outputLink>
POST
Если вы хотите установить URL-адрес для представления во время действия POST, вы можете сделать это, используя перенаправление в действии (вызванное кнопкой или командойLink).
<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
<h:outputText value="post" />
</h:commandLink>
Примечания
Обратите внимание, что ExternalContext.encodeActionURL используется для кодирования строки. Это хорошая практика для создания кода, который переносится через контексты (портлеты и т.д.). Вы бы использовали encodeResourceURL, если бы вы кодировали ссылку на изображение или файл загрузки.