JSFとナビゲーションルールを使用して、パラメーターを使用してGETリクエストを作成する方法
-
02-07-2019 - |
質問
h:outputLink、他のJSFタグまたはコードを使用してhtmlリンクを作成し、リクエストパラメータで非Facesリクエスト(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を1つの構成可能なファイルで定義する必要があります。
解決
これは興味深いアイデアです。実際にどのように機能するか知りたいです。
ナビゲーションルールの取得
ナビゲーションは、によって処理されます。 NavigationHandler 。 NavigationHandlerを取得することは難しくありませんが、APIは使用するルールを公開しません。
ご覧のとおり、次のことができます。
- 初期化時にfaces-config.xmlを解析し、アプリケーションコンテキストにルールを保存します( easy )
- faces-config.xmlのルールを無視する独自のNavigationHandlerを実装するか、独自のルールファイルでそれらを補完し、何らかの方法でルールセットを公開します(実行可能ですが、少し手間がかかります) >
- 独自の FacesContext を既存のナビゲーションハンドラに渡します(同じスレッド内で2つのFacesContextオブジェクトを共存させるのは本当に難しく、非常に非効率的です)
今、あなたにも別の問題があります。ビューを検索するために、どこにマッピングを保持しますか? Beanにハードコーディングしますか?
ナビゲーションルールの使用
オフハンドでは、パラメータを含むURLをバックエンドから構築できる2つの方法を考えることができます。どちらも、何らかの種類の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
POSTアクション中にビューにURLを設定する場合は、アクションのリダイレクト(ボタンまたはcommandLinkによって呼び出されます)を使用して実行できます。
<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
<h:outputText value="post" />
</h:commandLink>
メモ
ExternalContext.encodeActionURL は、文字列のエンコードに使用されます。これは、コンテキスト(ポートレットなど)を越えて移植可能なコードを作成するための良い習慣です。画像またはダウンロードファイルへのリンクをエンコードする場合は、 encodeResourceURL を使用します。
他のヒント
PrettyFacesを使用してみましたか?これは、ブックマーク可能なJSFページ/ GETリクエストを使用したJSFを可能にするために特別に設計されたオープンソースのJSF拡張です。
フォームを検討しましたか
<h:form>
<h:commandLink value="Click to see the message" action="#{handler.outcome}" />
<h:inputHidden id="msgId" value="#{bean.msgId}"/>
</h:form>
paramLinkタグをネストしたcommandLinkを使用できます。これは、上記のhubbardrと基本的に同じです。
<h:form>
<h:commandLink value="click here" action="${handler.outcome}">
<f:param name="msgId" value="${bean.id}" />
</h:commandLink>
</h:form>
次に、バッキングBeanで行う必要がある:
Map requestMap = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap();
String msgId = (String) requestMap.get("msgId");
そして、必要なことは何でもします。