web-dev-qa-db-ja.com

JSFフォーム送信でのGETリクエストクエリ文字列パラメーターの保持

私は3ページあります。

  • _main.xhtml_
  • _agreement.xhtml_
  • _generated.xhtml_

_agreement.xhtml_が正しくロードするには、serviceIdsiteの2つのパラメーターが必要です。したがって、通常のURLは次のようになります:_/app/agreement.xhtml?site=US&serviceId=AABBCC_。

このボタンは_agreement.xhtml_にあります

_<h:form>
   <h:commandButton value="Generate License File" action="#{agreement.generateMethod}" />   
</h:form>
_

_@RequestScoped_ Bean _#{agreement}_には次のメソッドがあります。

_public String generateMethod(){
    .......
    return "generated";
}
_

クリックするとgenerateMethod()メソッドが実行され、ユーザーが_generated.xhtml_ページにリダイレクトされる必要があります。何が起こっているかというと、ページブラウザーはクリックすると、ユーザーを_/app/agreement.xhtml_に送信し、パラメーターsiteserviceIdを送信しないため、クラッシュします。

generateMethod()が_"generated?faces-redirect=true"_を返すようにしようとしましたが、それでも何も返りません。何か案は?

20
Nacho321

JSF <h:form>がデフォルトで現在のリクエストURLにクエリ文字列なしで送信するため、具体的な問題が発生します。生成されたHTML出力をよく見ると、

<form action="/app/agreement.xhtml" ...>

したがって、これらのリクエストパラメータを自分で明示的に含める必要があります。これを解決するにはいくつかの方法があります。リダイレクトを送信しない場合は、それらを非表示の入力としてJSFフォームに追加できます。

<h:form>
    <input type="hidden" name="site" value="#{param.site}" />
    <input type="hidden" name="site" value="#{param.serviceId}" />
    ...
</h:form>

ただし、これらのパラメーターは、ブラウザーのアドレスバーのURLには表示されません。同じページでajaxのみを使用している場合、これは問題になりません。 <h:inputHidden>は、フォームで変換または検証エラーが発生すると混乱して値が失われるため、適切ではありません。

それらをURLに再表示させるには、<f:viewParam>およびincludeViewParamsが必要です。 includeViewParamsを動作させるには、ソースページbothで次のように宣言する必要がありますagreement.xhtml ...

<f:metadata>
    <f:viewParam name="site" value="#{agreement.site}" />
    <f:viewParam name="serviceId" value="#{agreement.serviceId}" />
</f:metadata>

...およびターゲットページgenerated.xhtml

<f:metadata>
    <f:viewParam name="site" value="#{generated.site}" />
    <f:viewParam name="serviceId" value="#{generated.serviceId}" />
</f:metadata>

これで、次のようにビューパラメータを含むリダイレクトを送信できます。

public String generateMethod() {
    // ...

    return "generated?faces-redirect=true&includeViewParams=true";
}

検証エラーの場合にも、フォームでページを開いてからフォームを送信するまでの間、これらのパラメータを維持するために、Beanは@ViewScopedである必要があります。それ以外の場合、@RequestScoped Beanを使用するときは、コマンドコンポーネントで<f:param>として保持する必要があります。

<h:commandButton ...>
    <f:param name="site" value="#{generated.site}" />
    <f:param name="serviceId" value="#{generated.serviceId}" />
</h:commandButton>

入力コンポーネント内で<f:ajax>に設定する方法はありません。Beanは実際には@ViewScopedになります。


または、JSFユーティリティライブラリ OmniFaces をすでに使用している場合は、<h:form><o:form>に次のように置き換えることもできます( showcaseの例も参照 ):

<o:form includeRequestParams="true">

基本的にはこれですべてです。これにより、現在のクエリ文字列が含まれた<form action>が生成されます。

<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>

これらのリクエストパラメータは、フォーム送信のリクエストパラメータマップで使用できるようになります。追加のメタデータ/ viewparamsは必要なく、リダイレクトを送信する必要もありません。また、必要に応じてBeanを@RequestScopedに保つことができます。

public String generateMethod() {
    // ...

    return "generated";
}

または、PrettyFacesやFacesViewsなどの「かわいらしいURL」ライブラリを使用している場合や、独自に開発したもので、ブラウザのアドレスバーに表示されるURLとまったく同じURLに送信する場合は、代わりにuseRequestURIを使用できます。 。

<o:form useRequestURI="true">

以下も参照してください。

32
BalusC

あなたのgenerateMethodは戻る必要があります

return "generated?site=US&amp;serviceId=AABBCC&amp;faces-redirect=true";

&amp;&ですが、xhtmlでエスケープしてください。

あなたのgenerated.xhtmlで渡されるパラメータをキャッチできます<f:viewParam> このような

<f:metadata>
    <f:viewParam name="site" value="#{yourBean.site}"/><!--Make sure you have a setter-->
    <f:viewParam name="serviceId" value="#{yourBean.serviceId}"/><!--Make sure you have a setter-
</f:metadata>
<h:head>
5
Andy