2013-07-19 102 views
0

我有一個portlet,在該portlet中連接到數據庫並顯示一些數據。當啓用自動刷新時,我想從db中加載數據,然後每隔X秒刷新一次頁面(jsp)。在portlet中安排任務

但是,儘管我做udnerstand如何定時器和任務的工作,我沒有完全得到如何讓他們在一個portlet中工作。

我嘗試了兩種不同的方法,但沒有一個按我的預期工作。這是第一個使用Thread.sleep(xxx);功能

public void displayLog(final ActionRequest actionRequest, 
      final ActionResponse actionResponse) throws IOException, 
      PortletException { 

     do { 
      manager.setLastID(0); 
      redirectToLog(actionRequest, actionResponse); 

      try { 
       Thread.sleep(3000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } while(manager.isAutoRefresh().equals("y")); 
    } 

這裏是重定向功能:

public void redirectToLog(ActionRequest actionRequest, 
      ActionResponse actionResponse) throws IOException, PortletException { 

     // load messages and display them 
     manager.loadFromDB(); 

     // in case of error, redirect to error page 
     if (manager.isConnError()) { 
      actionResponse.setRenderParameter("jspPage", 
        "/html/visual/error.jsp"); 
      return; 
     } 

     // redirect 
     actionRequest.setAttribute("messages", manager.getMessages()); 
     actionRequest.setAttribute("refresh", manager.isAutoRefresh()); 
     actionRequest.setAttribute("serviceFilter", manager.getServiceFilter()); 
     actionResponse 
       .setRenderParameter("jspPage", "/html/visual/display.jsp"); 

    } 

的代碼獲得每3秒執行(如果我把一些打印語句在那裏,我可以看到它taht調用此函數)。但是,我沒有重定向到jsp頁面。相反,它只是「凍結」,並永久循環。

我也試過第二使用方法定時器:

class LogDbTask extends TimerTask { 
    private DbManager manager; 
    private PortletVisual portlet; 
    private ActionRequest actionRequest; 
    private ActionResponse actionResponse; 

    public LogDbTask(PortletVisual portlet, ActionRequest actionRequest, ActionResponse actionResponse) { 
     this.portlet = portlet; 
     this.actionRequest = actionRequest; 
     this.actionResponse = actionResponse; 
     manager = portlet.getManager(); 
    } 


    public void run() { 
     if (manager.isAutoRefresh().equals("y")) { 
      try { 
       manager.setLastID(0); 
       portlet.redirectToLog(actionRequest, actionResponse); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (PortletException e) { 
       e.printStackTrace(); 
      } 
     } else { 
      //Stop Timer. 
      this.cancel(); 
     } 
    } 
} 

我稱之爲使用

Timer timer = new Timer("LogDbTimer"); 
LogDbTask task = new LogDbTask(this, actionRequest, actionResponse); 
timer.schedule(task, 0, 3000); 

但問題保持不變 - 我從來沒有JSP頁面,altough這個功能是多次呼籲。我不是portlet的專家,也不是多線程應用程序。我究竟做錯了什麼?有一些簡單的方法來解決這個問題嗎?

對不起,令人疲憊的問題 - 我試圖把一些代碼示例在那裏。如果不理解,我將嘗試更正確地指定問題...

回答

1

Thread.sleep方法會一直「凍結」,因爲portlet永遠不會呈現視圖。它位於循環中,從不實際返回要顯示給用戶的頁面。

計時器任務方法在其設計中也存在缺陷。用戶的瀏覽器必須爲portlet代碼發送頁面請求,以便將任何內容發回給用戶。這實際上意味着TimerTask可能會執行,但是在響應已發送給用戶的時候,您無法再更新頁面。

我會建議將計時器邏輯移到客戶端。您可以編寫一些JavaScript來使用AJAX和resourceURL在那裏使用定時器輪詢portlet。您的serveResource方法可以返回刷新的數據,然後使用JavaScript更新視圖。這有助於防止整頁刷新以減少服務器負載並使頁面更有效地刷新。

您唯一的選擇是使用頁面刷新HTML元標記或JavaScript計時器來讓瀏覽器在您希望頁面更新時進行整頁刷新。這降低了避免AJAX需求的複雜性,但我認爲這是一個性能較低且不太優雅的解決方案。

+0

謝謝,我認爲會有這樣的問題...我會嘗試重寫它! – Smajl