用 servlet实现http长连接


为了实现服务端向客户端推送的模式,如果自己写的socket到时顺理成章的很容易实现。但是,甲方要我们用标准的http协议。当然,自己写http服务器倒是也没什么题,我开始也时这么想的,而且都设计好了分布计算和负载平衡的方式。但有人暂时还建议我们用中间件,他们的意见就像天气的脸,一会儿这样,一会儿那样。于是在这方面考虑,无奈和喜悦同时而生。无奈的是,直接应用中间件,成就感将大打折扣。喜悦的是,直接应用中间件,我的开发量几乎可以说就是实现商业逻辑,分布计算和负载平衡都可以配置中间件实现。

那么如果用中间件写http服务,来应付客户端的请求并实现推送模式呢。在开会的时候, 一个同事使我猛醒。他说他就直接写一个servlet,这就是标准的http服务。这时,我便想起了我曾写过用java中URL累实现的http客户端。不妨用之,这样服务端客户端就都有了试验的依据。其中我问及同事是否实现长连接,结果他说没有 (应该是没想到这点),但是我们知道,服务推送的模式每次都打开和关闭与客户端的连接必然很耗资源。而我们实现的系统就是具备长连接,而且很耗带宽的连接,不管是长连接还是短连接。如果每次数据传送都要建立连接,而且请求非常频繁的假推送模式效能很低的话,我们就可以试一试长连接推送的方式。

也许你会想,servlet的长连接怎么实现呢。不错,用while循环就可以了。平常我们用浏览器浏览网页,大都一次请求,然后得到结果,关闭连接。其实如果服务端用一个死循环,一直在发送数据,而且客户端没有关闭的话,连接是一直存在的。我们完全可以用这条连接实现服务推模式。当然,监听的客户端自己写一个很简单,如下:

Java代码   收藏代码
  1. package test;  
  2.   
  3. import java.io.InputStream;  
  4. import java.net.URL;  
  5.   
  6. public class LongConnectionClient {  
  7.       
  8.     public static void main(String args[]) {  
  9.         try {  
  10.               
  11.             //确定服务地址  
  12.             URL url = new URL("http://localhost:8080/HttpConnectionTest/LongConnectionTest");  
  13.             InputStream in=url.openStream();  
  14.             int n = -1;  
  15.             byte[] b = new byte[1024];  
  16.             //从服务端读取数据并打印  
  17.             while((n=in.read(b))!=-1)  
  18.             {  
  19.                 String s=new String(b,0,n, "UTF-8");  
  20.                 System.out.println(s);      
  21.             }  
  22.               
  23.         } catch (Exception e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.     }  
  27.   
  28. }  


服务端的代码也异常简单:

Java代码   收藏代码
  1. package test;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9.   
  10.  public class LongConnectionTest extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {  
  11.    static final long serialVersionUID = 1L;  
  12.      
  13.     public LongConnectionTest() {  
  14.         super();  
  15.     }         
  16.       
  17.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  18.         this.doPost(request, response);  
  19.     }     
  20.       
  21.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  22.   
  23.          response.setCharacterEncoding("UTF-8");  
  24.          response.setContentType("text/html");  
  25.           
  26.          PrintWriter pr = response.getWriter();  
  27.            
  28.          try {  
  29.              while(true) {  
  30.                  pr.print("有时候你不得不相信");  
  31.                  //flush的作用很重要,当你任务写给客户端的数据总够多的时候  
  32.                  //调用之,客户端方能读取到。  
  33.                  //否则,在数据长度达到上限或者连接关闭之前,客户端读不到数据  
  34.                  pr.flush();  
  35.                  Thread.sleep(500);  
  36.              }  
  37.          } catch(Exception e) {  
  38.              e.printStackTrace();  
  39.          }  
  40.           
  41.     }                 


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个示例代码,实现了使用Servlet连接MySQL数据库进行用户登录的功能: ```java import java.io.*; import java.sql.*; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; @WebServlet("/login") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // 加载MySQL JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); // 连接MySQL数据库 String url = "jdbc:mysql://localhost:3306/mydb"; String user = "root"; String pass = "123456"; conn = DriverManager.getConnection(url, user, pass); // 执行SQL查询语句 String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; stmt = conn.prepareStatement(sql); stmt.setString(1, username); stmt.setString(2, password); rs = stmt.executeQuery(); // 验证用户登录信息 if (rs.next()) { // 登录成功,跳转到欢迎页面 response.sendRedirect("welcome.jsp"); } else { // 登录失败,跳转回登录页面 response.sendRedirect("login.jsp?error=1"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭数据库连接 try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } ``` 这里假设MySQL数据库已经安装在本地,并且已经创建了一个名为“mydb”的数据库,其中包含一个名为“users”的表,用于存储用户的登录信息。在实际应用中,需要根据具体情况进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值