在POST请求后重新创建ViewScoped bean时,重新执行f:viewAction [英] Re-execute f:viewAction when ViewScoped bean is recreated following a POST request
问题描述
环境:带有Mojarra 2.2.12&的JSF 2.2 CDI ViewScoped豆类javax.faces.STATE_SAVING_METHOD
设置为client
.
Environment: JSF 2.2 with Mojarra 2.2.12 & CDI ViewScoped beans & javax.faces.STATE_SAVING_METHOD
set to client
.
为了通过<f:viewParam ... />
正确初始化我的bean,我想在重新创建 bean 时(重新)执行<f:viewAction action="#{bean.onLoad}" />
(视图已从LRU,请参见 com.sun.faces.numberOfLogicalViews )在POST请求之后.
In order to properly initialize my bean thanks to <f:viewParam ... />
, I would like to (re-)execute <f:viewAction action="#{bean.onLoad}" />
when my ViewScoped
bean is recreated (view was pushed out from the LRU, cf. com.sun.faces.numberOfLogicalViews) following a POST request.
<f:metadata>
<f:viewParam maxlength="100" name="name" value="#{bean.file}" />
<f:viewAction action="#{bean.onLoad}" />
</f:metadata>
<o:form includeRequestParams="true">
<!-- action can only work if onLoad has been called -->
<p:commandButton action="#{bean.action}" />
</o:form>
有什么想法吗?
注释:
- 我知道
postBack="true"
,但是它不适合在每个 POST请求中调用bean.onLoad()
. - 我无法在
@PostConstruct
方法中调用onLoad()
,因为viewParam
尚未设置值(请参见
- I'm aware of
postBack="true"
but it's not suitable asbean.onLoad()
would be called on every POST request. - I cannot call
onLoad()
in@PostConstruct
method because values have not been set byviewParam
yet (cf. When to use f:viewAction versus PostConstruct?).
推荐答案
我知道
postBack="true"
,但是它不适合使用bean.onLoad()会在每个POST请求中调用.
I'm aware of
postBack="true"
but it's not suitable as bean.onLoad() would be called on every POST request.
您可以仅在onPostback
属性中使用EL,在其中检查模型值和/或请求参数是否存在.
You can just use EL in onPostback
attribute wherein you check if the model value and/or request parameter is present.
如果需要模型值,则只需检查其是否存在:
If the model value is required, then just check if it's present or not:
<f:metadata>
<f:viewParam maxlength="100" name="name" value="#{bean.file}" required="true" />
<f:viewAction action="#{bean.onLoad}" onPostback="#{empty bean.file}" />
</f:metadata>
如果不需要模型值,则还要检查请求参数:
If the model value is not required, then check the request parameter too:
<f:metadata>
<f:viewParam maxlength="100" name="name" value="#{bean.file}" />
<f:viewAction action="#{bean.onLoad}" onPostback="#{empty bean.file and not empty param.name}" />
</f:metadata>
我无法在
@PostConstruct
方法中调用onLoad()
,因为viewParam尚未设置值.
I cannot call
onLoad()
in@PostConstruct
method because values have not been set by viewParam yet.
鉴于您的代码段中存在 <o:form>
,我看到您正在使用 OmniFaces .完全相同的实用程序库提供了CDI @Param
批注,用于注入,转换和在@PostConstruct
运行之前验证HTTP请求参数.
Given the presence of <o:form>
in your snippet, I see that you're using OmniFaces. The very same utility library offers a CDI @Param
annotation for the very purpose of injecting, converting and validating HTTP request parameters before the @PostConstruct
runs.
因此,整个<f:viewParam><f:viewAction>
可以按以下方式替换:
The entire <f:viewParam><f:viewAction>
can therefore be replaced as below:
@Inject @Param(name="name", validators="javax.faces.Length", validatorAttributes=@Attribute(name="maximum", value="100"))
private String file;
@PostConstruct
public void onLoad() {
if (!Faces.isValidationFailed()) {
// ...
}
}
或者如果您手头有Bean验证(又名JSR303):
Or if you've Bean Validation (aka JSR303) at hands:
@Inject @Param(name="name") @Size(max=100)
private String file;
@PostConstruct
public void onLoad() {
if (!Faces.isValidationFailed()) {
// ...
}
}
这篇关于在POST请求后重新创建ViewScoped bean时,重新执行f:viewAction的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!