我有这个示例代码:
<h:form>
<h:commandButton action="#{fooBar.foo()}" value="Submit"/>
</h:form>
并在bean中:
@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行为非常好。
现在我想了解发生了什么,所以我打开了documentation。
此类中有一个keep()
方法,但其返回类型为void
,并且它需要一个String
参数。那么#{flash.keep.message}
是否使用message参数调用keep()
方法?我真的不这么认为,据我所知它应该是#{flash.keep(message)}
,不是吗?
那么这里发生了什么?
答案 0 :(得分:1)
可以使用ELResolver
实现自定义EL解析。有两个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)
表达式时调用#{flash.keep}
(第231行)。它还将属性设置为已解析(第219行),以便EL上下文可以使用下一个属性前进,并将base
(#{flash}
)设置为评估结果(第225行),因此有效#{flash.keep}
返回完全相同的#{flash}
对象。
然后,当message
属性要对#{flash.keep}
的结果进行评估时,#{flash}
基本上仍为#{flash}
,但使用&#34;保持&#34;标志集,EL-builtin MapELResolver
被执行。这是因为Map
基本上是Map#get()
,另见javadoc(强调我的)。
公共抽象类Flash
扩展对象
实现Map&lt; String,Object&gt;
这会调用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 }
类customized如下(行号与Mojarra 2.2.12匹配):
keep(key)
正如您在第396行所见,它会在设置标志时调用FlashELResolver
,如from sklearn.feature_extraction.text import CountVectorizer
train_vectorizer = CountVectorizer()
train = [
'this is the first',
'set of documents'
]
train_matrix = train_vectorizer.fit_transform(train)
train_vocab = train_vectorizer.vocabulary_
test = [
'this is the second',
'set of documents'
]
test_vectorizer = CountVectorizer(vocabulary=train_vocab)
test_matrix = test_vectorizer.fit_transform(test)
print(train_vocab)
print(train_matrix.toarray())
print('\n')
print(test_vectorizer.vocabulary_)
print(test_matrix.toarray())
所示。