最近,做一個項目,需要做一個web服務器,該服務器要與Android端和GPRS模塊互相通信。考慮Android端與服務器端用Http通信,GPRS模塊與服務器用Tcp通信。因此需要在Web服務器啟動的時候啟動加載一個線程負責Tcp端口的監聽。
search了一些方法,從中挑選了兩個在此記錄一下:
方法一:監聽(Listener)
我們創建一個監聽類,繼承自ServletContextListener,代碼如下:
1 package will; 2 3 4 import java.io.IOException; 5 6 import javax.servlet.ServletContextEvent; 7 import javax.servlet.ServletContextListener; 8 9 public class SocketListener implements ServletContextListener { 10 11 private MyThread myThread; 12 @Override 13 public void contextDestroyed(ServletContextEvent arg0) { 14 if (myThread!=null&&myThread.isInterrupted()) { 15 myThread.interrupt(); 16 } 17 18 } 19 20 @Override 21 public void contextInitialized(ServletContextEvent arg0) { 22 String str =null; 23 if (str==null&&myThread==null) { 24 myThread=new MyThread(); 25 myThread.start();//servlet上下文初始化時啟動socket 26 } 27 } 28 29 30 /* 31 * 自定義一個Class線程類繼承自線程類,重寫run()方法,用於從后台獲取處理數據 32 * 33 */ 34 class MyThread extends Thread{ 35 public void run() { 36 while (!this.isInterrupted()) {//線程未中斷執行循環 37 try { 38 Thread.sleep(2000);//每隔2000ms執行一次 39 40 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 45 //----------------------開始執行--------------------- 46 System.out.println("TIME:"+System.currentTimeMillis()); 47 48 Server ss=new Server(); 49 try { 50 ss.startWork(); 51 } catch (IOException e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } 55 } 56 } 57 } 58 59 }
需要在web.xml中添加配置如下:
1 <listener> 2 <listener-class>will.SocketListener</listener-class> 3 </listener>
方法二:使用Servlet,在項目啟動時啟動它。
我們創建一個Servlet,繼承HttpServlet,代碼如下:
1 package will; 2 import java.io.IOException; 3 import javax.servlet.ServletException; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import com.ite.common.Constants; 8 9 public class MyServlet extends HttpServlet{ 10 11 private static final long serialVersionUID = 1L; 12 private MyThread1 myThread1; 13 14 public MyServlet(){ 15 } 16 17 public void init(){ 18 String str = null; 19 if (str == null && myThread1 == null) { 20 myThread1 = new MyThread1(); 21 myThread1.start(); // servlet 上下文初始化時啟動 socket 22 } 23 } 24 25 public void doGet(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse) 26 throws ServletException, IOException{ 27 } 28 29 public void destory(){ 30 if (myThread1 != null && myThread1.isInterrupted()) { 31 myThread1.interrupt(); 32 } 33 } 34 } 35 36 /** 37 * 自定義一個 Class 線程類繼承自線程類,重寫 run() 方法,用於從后台獲取並處理數據 38 * 39 * @author will 40 * 41 */ 42 class MyThread1 extends Thread { 43 public void run() { 44 while (!this.isInterrupted()) {// 線程未中斷執行循環 45 try { 46 Thread.sleep(2000); 47 } catch (InterruptedException e) { 48 e.printStackTrace(); 49 } 50 51 // ------------------ 開始執行 --------------------------- 52 System.out.println("TIME:" + System.currentTimeMillis()); 53 } 54 } 55 }
在web.xml中的相應配置為:
1 <servlet> 2 <servlet-name>MyListener</servlet-name> 3 <servlet-class>will.MyServlet</servlet-class> 4 <load-on-startup>9</load-on-startup><!-- 數字越小,啟動的優先級越高,必須大於0 --> 5 </servlet> 6 <servlet-mapping> 7 <servlet-name>MyListener</servlet-name> 8 <url-pattern>/test</url-pattern> 9 </servlet-mapping>
Socket端口的監聽方法在這里就不寫了,大家直接在“-----------開始執行----------”后添加調用就可以了
其中,Listener的方式,該線程肯定是項目中首先啟動的,優先於任何一個Servlet。而Servlet的方式,可以設置與其它Servlet啟動的順序。如果有時候需要首先啟動一個Servlet或者它們之間的啟動順序有特殊要求的時候,這個就很有作用了。