2013-04-09 28 views
1

我正在使用Apache Tomcate 7.0.39,Eclipse Java EE Juno,Java JRE 7 & Java JDK 1.7.0_13。Java.util.timer計時器空指針異常

我的計時器有問題。我有兩個函數,第一個函數啓動計時器並執行任務,另一個函數停止計時器。 但是,定時器永遠不會停止,因爲它是空的。

我的Java代碼:

public class TestXMLSQLTimerLocal 
{ 
    public Timer timer; 

    public TestXMLSQLTimerLocal() 
    { 

    } 

    public void start() 
    { 
     this.timer = new Timer(); 
     TimerTask task = new TimerTask() 
     { 
      public void run() 
      { 
      //Some code 
      } 
     }; 

     timer.scheduleAtFixedRate(task, 0, 60000); 
    } 
    public void stop() { 
     this.timer.cancel(); 
    } 
} 

我的JSP頁面:

<%@page import="com.accenture.api.TestXMLSQLTimerLocal" %> 
<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<% 
String text = "Press the Start button to begin !"; 
String action = request.getParameter("action"); 
TestXMLSQLTimerLocal TM = new TestXMLSQLTimerLocal(); 
if ("Start".equals(action)) 
{ 
    TM.start(); 
    text = "The data are being transferred. Press the Stop button when you want to stop the transfer !"; 
} 
if("Stop".equals(action)) 
{ 
    TM.stop(); 
    text = "The transfer is stopped. Press the Start button to begin the transfer again !"; 
} 
%> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
    <title>Transfer Module</title> 
</head> 
<body> 
    <form name="StartTM" action="#"> 
     <input type="hidden" name="action" value="Start"/> 
     <input type="submit" value="Start"/> 
    </form> 
    <br /> 
    <p><%=text%></p> 
    <br /> 
    <form name="StopTM" action="#"> 
     <input type="hidden" name="action" value="Stop"/> 
     <input type="submit" value="Stop"/> 
    </form> 
</body> 
</html> 

啓動()和stop()是由一個起點和一個簡單的JSP頁面上的停止按鈕調用。

對我來說,問題是計時器仍爲空,因爲Start()方法中的修改沒有考慮到。 有人可以幫助我嗎? 如果您需要了解更多信息,請向我

+0

顯示堆棧跟蹤 – PSR 2013-04-09 09:25:50

+1

你確定start()在stop()之前調用?放一些調試語句。 – 2013-04-09 09:26:55

+0

是的,沒有任何東西出現在Tomcat的日誌文件中 – 2013-04-09 09:54:41

回答

0

如果您從JSP中調用此項,產生新線程的TestXMLSQLTimerLocal實例以及Timer在用戶按下停止按鈕時不可用。

您需要將TestXMLSQLTimerLocal的實例添加到會話中,或者更優選地將applicationContext添加到會話中。在針對此實例執行操作時,始終將其從會話中拉出。

TestXMLSQLTimerLocal添加實例到會話:

//From Servlet 
request.getSession().addAttribute("timer", new TestXMLSQLTimerLocal()); 

要添加的實例應用範圍,你將需要使用,一個ServletContextListener

而且代碼會拋出NPE錯誤,因爲實例Timer永遠不會被創建。

+0

如何將TestXMLSQLTimerLocal的實例添加到會話中? – 2013-04-09 10:00:35

+0

@ Jeremy.Vdb查看更新 – 2013-04-09 10:12:36

+0

感謝您的回答,但我不太瞭解ServletContextListener的目的(我不是JSP專家,只是一個小新手) – 2013-04-09 10:16:23

1

啓動計時器在你的構造不啓動方法:

public class TestXMLSQLTimerLocal 
{ 
public Timer timer;  

public TestXMLSQLTimerLocal(){ 
    this.timer = new Timer(); 
} 

public void start() 
{ 
    TimerTask task = new TimerTask() 
    { 
     public void run() 
     { 
     //Some code 
     } 
    }; 

    timer.scheduleAtFixedRate(task, 0, 60000); 
} 
public void stop() { 
    this.timer.cancel(); 
} 
} 
+0

您現在有2個構造函數,它們的參數爲零,所以這不會編譯 – maloney 2013-04-09 09:28:40

+0

upps。沒有看到那個抱歉。 – 2013-04-09 09:29:17

1

你需要確保你的啓動命令被停止命令之前調用。另外,把你的this.timer = new Timer();加入到你的類的構造函數中。

+0

我將它添加到構造函數中。我沒有空指針異常,但計時器不會被取消。我確定首先調用啓動方法,因爲我只有一個人可以按下按鈕 – 2013-04-09 09:33:42

+0

聽起來就像你試圖從啓動的那個對象中取消一個'timer'對象的不同實例。您將需要調試此項並檢查對象並查看實際正在進行的操作。否則,我們只是在猜測,而且很難幫助你。 – maloney 2013-04-09 09:40:09

+0

在我的JSP頁面中,如果按下按鈕,頁面將刷新。我認爲錯誤在那裏,因爲如果頁面被刷新,它會再次讀取代碼,這是正確的?但是,如果我在JSP代碼中調用了我的java類的實例,他是否「閱讀」了代碼或僅在我調用此類的方法時纔讀取代碼? – 2013-04-09 09:49:04

0

我找到了解決方案,這要歸功於凱文Bowersok

我分裂啓動和停止按鈕在兩頁,我通過會話送我TestXMLSQLTimerLocal對象。

要通過會話發送的對象:

session.putValue("TM",TM); 

要在其他網頁獲取的價值:您的幫助傢伙

TestXMLSQLTimerLocal TM = (TestXMLSQLTimerLocal) session.getValue("TM"); 

感謝