1

私はこのサンプルコードを持っています:

<h:form>
    <h:commandButton action="#{fooBar.foo()}" value="Submit"/>
</h:form>

そして豆の中:

@ManagedBean
@ApplicationScoped
public class FooBar {
    public String foo() {
        final Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
        flash.put("message", "Hello World");
        return "hello?faces-redirect=true";
    }
}

そして最後にhello.xhtml

<h:body>
    #{flash.keep.message}
</h:body>

に移動してindex.xhtml[送信] をクリックすると、期待どおりにリダイレクトさhello.xhtmlれます。また、ページを更新しても、flash.keep の動作が優れているため、メッセージが表示されます。

今、何が起こっているのかを理解しようとしているので、ドキュメントを開きます。

このクラスにはメソッドがありますが、keep()その戻り値の型はvoidであり、Stringパラメーターが必要です。メッセージパラメーターを使用してメソッドを#{flash.keep.message}呼び出していますか? keep()私が知る限り、そうあるべきだったとは思いませ#{flash.keep(message)}んね。

それで、ここで何が起こっているのですか?

4

1 に答える 1

1

EL 解決は、実装によってカスタマイズできますELResolver。の評価には 2 つの EL リゾルバが関与し#{flash.keep.message}ます。最初のものは、JSF 組み込みFlashELResolverが で実行され#{flash}ます。ソース コードでわかるように (行番号は Mojarra 2.2.12 と一致します)、

216        // and the property argument is "keep"...
217        if (property.toString().equals(FLASH_KEEP_VARIABLE_NAME))
218        {
219            elContext.setPropertyResolved(true);
220          
221            // then this is a request to promote the value
222            // "property", which is assumed to have been previously
223            // stored in request scope via the "flash.now"
224            // expression, to flash scope.
225            result = base;
226            // Set a flag so the flash itself can look in the request
227            // and promote the value to the next request
228            FlashFactory ff = (FlashFactory) 
229                    FactoryFinder.getFactory(FactoryFinder.FLASH_FACTORY);
230            ff.getFlash(true);
231            ELFlash.setKeepFlag(facesContext);
232        }

これは、式が評価されるときにFlashELResolver呼び出されますELFlash.setKeepFlag(facesContext)(231 行目) 。#{flash.keep}また、プロパティを解決済みとして設定し (219 行目)、EL コンテキストが次のプロパティに進むことができるようにし、base(the #{flash}) を評価結果 (225 行目) として設定するため、実質的#{flash.keep}にまったく同じ#{flash}オブジェクトを返します。

そして、messageプロパティが の結果で評価される場合#{flash.keep}、これは基本的にまだ#{flash}ですが、「keep」フラグが設定されていると、EL ビルトインMapELResolverが実行されます。これは、#{flash}本質的に であるためです。javadocMapも参照してください(強調鉱山)。

public 抽象クラス Flash
extends Object
実装 Map<String,Object>

これは、以下のようにクラスでカスタマイズされたメソッドを呼び出します(Map#get()行番号は Mojarra 2.2.12 と一致します)。Flash

384     public Object get(Object key) {
385         Object result = null;
386 
387         FacesContext context = FacesContext.getCurrentInstance();
388         if (null != key) {
389             if (key.equals("keepMessages")) {
390                 result = this.isKeepMessages();
391             } else if (key.equals("redirect")) {
392                 result = this.isRedirect();
393             } else {
394                 if (isKeepFlagSet(context)) {
395                     result = getPhaseMapForReading().get(key);
396                     keep(key.toString());
397                     clearKeepFlag(context);
398                     return result;
399                 }
400 
401             }
402 
403         }

396 行目でわかるようkeep(key)に、フラグが設定されたときに呼び出されFlashELResolverます。

于 2016-06-25T14:45:27.923 に答える