同步会话范围的托管bean

时间:2011-01-13 01:04:04

标签: jsf jsf-2

我的JSF 2.0应用程序中有2个屏幕。屏幕1搜索学生并列出表格中的学生。结果表中的学生姓名是指向学生详细信息页面(屏幕2)的链接。

我的托管bean:

@SessionScoped
public class TestController {
private Student studentOnUI; // Student being viewed on the UI 
// synchronized public getters and setters
public String viewStudentAction(String studentId) {
    this.studentOnUI = getStudentFromDB( studentId );   
    return "studentDetailedPage";
}
public synchronized String clearSearchAction() {
    this.studentOnUI = null;
    return "studentSearchPage";
}

screen 1 xhtml snippet

<!-- search fields -->
<h:commandButton  
    value="Clear Search"
    action="#{testController.clearSearchAction()}"/>
<!-- Search button -->
<!-- search results table -->

屏幕2 xhtml片段

<h:outputText value="#{testController.studentOnUI.name}" />
<h:dataTable 
  value="#{testController.studentOnUI.subjects}"
  var="subject">
  <h:outputText value="#{subject.score}"/>
</h:dataTable>

我面临以下问题:

  1. 运行搜索后,用户点击 学生姓名(进入屏幕 2)
  2. 当渲染响应阶段 屏幕2正在进行中(具有 EL引用 testController.studentOnUI),他 点击清除按钮(无需等待第一个请求完成)。现在 处理明确请求的线程 将testController.studentOnUI设置为null和 渲染中的第一个线程 响应阶段抛出 它的NullPointerException 评估板

    {testController.studentOnUI。*}。

  3. 虽然托管bean处理同步(正确吗?)但它并没有解决这里的并发问题,因为可能会发生以下情况

    1. 线程1(处理导航到屏幕2的请求) - 评估#{testController.studentOnUI.name}并愉快地呈现该值。然后退出testController.getStudentOnUI()synchronized方法。因此,线程1不再具有控制器实例上的锁(在会话范围内)。上下文切换发生。
    2. 线程2(处理请求清除 搜索结果) - 确实 testController.studentOnUI = null in clearSearchAction()。上下文切换 发生的情况。
    3. 线程1 - 评估页面中的下一个EL(#{testController.studentOnUI.subjects})并抛出NullPointerException(因为testController.studentOnUI现在为null)。
    4. 感谢我对这种方法做错的指示,或者是否需要采用不同的方法。

1 个答案:

答案 0 :(得分:0)

这是非常奇怪的行为,但我宁愿在JavaScript的第一页上禁用链接,使其“无法点击”。 试试jQuery:

1个按钮:$('#button')。attr(“disabled”,true);

2 link:$('a.something')。click(function(e){         e.preventDefault();     });

我不确定支持bean中的同步,因为JSF Controller必须将锁定放在Student对象上,而不是clear方法。我错了吗?