最近,做一个项目,需要做一个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或者它们之间的启动顺序有特殊要求的时候,这个就很有作用了。