会话范围内的意外行为



我有一个JSF页面,用户可以在其中向我的数据库输入他们的汽车。该表单有三个输入字段:

    <
  • 制造商/gh>
  • 登记

ManufacturerModel字段都是自动补全字段。为了完成Model字段,我需要知道用户在提交表单之前在Manufacturer字段中选择了什么值。为此,我设置了一个AJAX调用,将选中的值通知受管bean:

<p:autoComplete id="manufacturer"
                minQueryLength="3"
                completeMethod="#{carController.complete}"
                forceSelection="true">
   <p:ajax event="itemSelect"
           listener="#{carController.manufacturerSelected}" />
</p:autoComplete>

在受管bean中:

public void manufacturerSelected(SelectEvent se) {
    manufacturer = se.getObject().toString();
}

模型的自动完成字段和处理程序方法看起来大致相同,只是值略有不同。

为了在多个XHR请求中保留manufacturer值,我将bean设置为ConversationScoped,并在@PostConstruct注释方法中开始对话:

@Named
@ConversationScoped
public class CarController implements Serializable {
@Inject
private Conversation conversation;
@PostConstruct
private void init() {
    conversation.begin();
}

我所期望的是bean只为页面实例化一次,因为会话尚未结束,并保留manufacturer字段中的值。然而,这并不成立,并且为每个XHR请求再次实例化bean,导致manufacturer字段也变为null。在PostConstruct方法中设置一个断点表明它实际上正在被调用,manufacturerSelected方法也是如此。

我怀疑这与我没有手动传播会话ID的事实有关,但是文档说这个ID应该与任何面部请求自动传播。这是真的吗?这是否意味着XHR请求不一定是面向请求?

Edit:在bean中的各个位置设置断点显示每个XHR请求都有一个新bean (conversation.getId()不断变化),因此我显然没有传播ID的权利。如何使用ajax传播ID,以及在哪里可以使用EL获得ID ?

既然您没有真正使用会话(至少不是在您给出的示例中),为什么不使用视图作用域呢?这将完全满足您的需求,而不需要传播会话id的开销。

请注意,要使@ViewScoped工作,您必须将bean更改为JSF管理的bean(删除@Named)。这是由于Java EE 6中的设计错误/规范疏忽造成的。如果你想继续使用CDI,那么Seam 3的Java EE 6扩展可以修复这个错误。

是的。这是JSF 2和Primefaces一起不传播会话id的一个问题。您可以尝试下面的解决方法。(这是给那些因为同样的问题而最终在这里结束的人)。

<p:autoComplete id="manufacturer"
            minQueryLength="3"
            completeMethod="#{carController.complete}"
            forceSelection="true" onchange="updateManufacturer([{name:'cid',value:'#{javax.enterprise.context.conversation.id}'}])">
</p:autoComplete>
<p:remoteCommand name="updateManufacturer" action="#{carController.manufacturerSelected}"
                                 process="manufacturer" />

相关内容

  • 没有找到相关文章

最新更新