登录 之 服务端响应
2013-02-18 11:45
141 查看
新年第一篇
前面讲到的关于通讯机制的实现是客户端,现在将服务端响应的部分实现予以展示
为了提高数据库的连接性能,所以采用了连接池的设计:
定义连接池接口:ConnectionPoolInterface.java
实现连接代理:ConnectionHandler.java
最后实现连接池:ConnectionPool.java
前面讲到的关于通讯机制的实现是客户端,现在将服务端响应的部分实现予以展示
package com.net; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class NioServer { private ReadProperties rp = new ReadProperties(); private final String IP = rp.getProperty("ip"); private final int SERVERPORT = Integer.parseInt(rp .getProperty("socketport")); private final String ISACK = "ACK"; private final String ISNAK = "NAK!"; private final String SPLITSTR = rp.getProperty("split_string"); private ConnectionPool connpool=null; private Connection conn=null; private PreparedStatement pstmt=null; private ResultSet rs = null; private Hashtable<String,Integer> htMap=new Hashtable<String,Integer>(); // Selector selector;//选择器 // SelectionKey key;//key。 一个key代表一个Selector 在NIO通道上的注册,类似主键;// // 取得这个Key后就可以对Selector在通道上进行操作 private ByteBuffer echoBuffer = ByteBuffer.allocate(1024); // 通道数据缓冲区 public NioServer() { this.initHashTable(); } private void initHashTable(){ htMap.put("land", 1); htMap.put("register", 2); } public void BuildNioServer() throws IOException { // /////////////////////////////////////////////////////// // ///////先对服务端的ServerSocket进行注册,注册到Selector //// // /////////////////////////////////////////////////////// ServerSocketChannel ssc = ServerSocketChannel.open(); // 新建NIO通道 ssc.configureBlocking(false); // 使通道为非阻塞,false ServerSocket ss = ssc.socket(); // 创建基于NIO通道的socket连接 ss.bind(new InetSocketAddress(IP, SERVERPORT)); // 新建socket通道的端口 Selector selector = Selector.open(); // 获取一个选择器 ssc.register(selector, SelectionKey.OP_ACCEPT); // 将NIO通道绑定到选择器,当然绑定后分配的主键为skey // ////////////////////////////////////////////////////////////////// // //// 接收客户端的连接Socket,并将此Socket也接连注册到Selector //// // ///////////////////////////////////////////////////////////////// while (true) { int num = selector.selectNow(); // 获取通道内是否有选择器的关心事件 if (num < 1) continue; Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectedKeys.iterator();// 获取通道内关心事件的集合 while (it.hasNext()) { // 遍历每个事件 try { SelectionKey key = (SelectionKey) it.next(); // 有一个新联接接入事件,服务端事件 if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { // 接收这个新连接 ServerSocketChannel serverChanel = (ServerSocketChannel) key.channel(); // 从serverSocketChannel中创建出与客户端的连接 socketChannel SocketChannel sc = serverChanel.accept(); sc.configureBlocking(false); // 把新连接注册到选择器 sc.register(selector,SelectionKey.OP_READ); it.remove(); } else { // 读客户端数据的事件,此时有客户端发数据过来,客户端事件 if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { // 读取数据 SocketChannel sc = (SocketChannel) key.channel(); if (sc.read(echoBuffer) > 0) { echoBuffer.flip(); //System.out.println("limit:" + echoBuffer.limit()); byte[] content = new byte[echoBuffer.limit()]; echoBuffer.get(content); String result = new String(content); doPost(result, sc); } echoBuffer.clear(); it.remove(); } } } catch (Exception e) { e.printStackTrace(); } } } } public void doPost(String str, SocketChannel sc) { int firstIndex = str.indexOf(SPLITSTR); int secondIndex = str.lastIndexOf(SPLITSTR); String result = ""; if (firstIndex > 0) { String name = str.substring(0, firstIndex); String pswd = str.substring(firstIndex + SPLITSTR.length(), secondIndex); String respondStyle = str.substring(secondIndex + SPLITSTR.length()); if (name.length() != 0 && pswd.length() != 0 && respondStyle.length() != 0) { switch (this.htMap.get(respondStyle)) { case 1: // response of land if (validateLogOn(name, pswd)) { try { result = ISACK + SPLITSTR + this.getLogOnUserInfo().getString("SName"); } catch (SQLException e) { e.printStackTrace(); } } else result = ISNAK + SPLITSTR + "userName or passwd error"; break; case 2: // response of register if (validateUserExist(name)){ result = ISNAK + SPLITSTR + name + " has existed"; }else { if (registerUserInfo(name, pswd)){ result = ISACK + SPLITSTR + name; }else result = ISNAK + SPLITSTR + "regist " + name + " failed"; } break; default: System.out.println("No response to [" + respondStyle + "]."); System.exit(1); break; } } else { System.out.println("At least one value of [name,passwd,respondStyle] is null."); System.exit(1); } } else { System.out.println("Can not receive split string."); System.exit(1); } ByteBuffer bb = ByteBuffer.allocate(result.length() + 10); bb.put(result.getBytes()); bb.flip(); try { sc.write(bb); } catch (IOException e) { e.printStackTrace(); } bb.clear(); } private boolean validateLogOn(String name,String passwd){ connpool=ConnectionPool.getInstance(); conn=connpool.getConnection(); try { pstmt = conn.prepareStatement("select * from Student where SAccounts = ? and SPasswd = ?;"); pstmt.setString(1, name); pstmt.setString(2, passwd); rs = pstmt.executeQuery(); if(rs.next()){ return true; }else return false; } catch (SQLException e) { e.printStackTrace(); } finally { connpool.releaseConnection(conn); } return false; } private ResultSet getLogOnUserInfo(){ return this.rs; } private boolean validateUserExist(String name){ connpool=ConnectionPool.getInstance(); conn=connpool.getConnection(); try { pstmt = conn.prepareStatement("select * from Student where SAccounts = ?;"); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()){ return true; }else return false; } catch (SQLException e) { e.printStackTrace(); } finally { connpool.releaseConnection(conn); } return false; } private boolean registerUserInfo(String name,String passwd){ connpool=ConnectionPool.getInstance(); conn=connpool.getConnection(); try { pstmt = conn.prepareStatement("insert into Student(SID,SName,SAccounts,SPasswd) values(?,?,?,?);"); pstmt.setString(1, "id_"+name); pstmt.setString(2, "test_"+name); pstmt.setString(3, name); pstmt.setString(4, passwd); int rows=pstmt.executeUpdate(); if(rows != 0){ return true; }else { return false; } } catch (SQLException e) { e.printStackTrace(); } finally { connpool.releaseConnection(conn); } return false; } public static void main(String[] args) throws IOException { NioServer ns = new NioServer(); ns.BuildNioServer(); } }
为了提高数据库的连接性能,所以采用了连接池的设计:
定义连接池接口:ConnectionPoolInterface.java
package com.net; import java.sql.Connection; public interface ConnectionPoolInterface { public Connection getConnection(); public void releaseConnection(Connection con); }
实现连接代理:ConnectionHandler.java
package com.net; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; public class ConnectionHandler implements InvocationHandler { private Connection con; private ConnectionPool pool; public ConnectionHandler(ConnectionPool pool) { this.pool = pool; } public Connection bind(Connection con) { this.con = con; // Connection proxyCon = (Connection) Proxy.newProxyInstance(con // .getClass().getClassLoader(), con.getClass().getInterfaces(), // this); Connection proxyCon = (Connection) Proxy.newProxyInstance( Connection.class.getClassLoader(), new Class[] { Connection.class }, this); return proxyCon; } public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { // TODO Auto-generated method stub Object obj = null; if ("close".equals(arg1.getName())) { pool.releaseConnection(con); } else { obj = arg1.invoke(con, arg2); } return obj; } }
最后实现连接池:ConnectionPool.java
package com.net; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Vector; public class ConnectionPool implements ConnectionPoolInterface { private ReadProperties rp = new ReadProperties(); private static Vector<Connection> pool; private static int POOL_MAX_SIZE = 0; private static ConnectionPool conPool = null; private static String DRIVER_NAME = ""; private static String URL_BASE = ""; private static String DB_NAME = ""; private static String SERVER_IP = ""; private static int SERVER_PORT = 0; private static String DB_ADMIN_NAME = ""; private static String DB_ADMIN_PASSWD = ""; ConnectionPool() { POOL_MAX_SIZE = Integer.parseInt(rp.getProperty("pool_max_size")); DRIVER_NAME = rp.getProperty("driver_name"); URL_BASE = rp.getProperty("url_base"); DB_NAME = rp.getProperty("db_name"); SERVER_IP = rp.getProperty("server_ip"); SERVER_PORT = Integer.parseInt(rp.getProperty("server_port")); DB_ADMIN_NAME = rp.getProperty("db_admin_name"); DB_ADMIN_PASSWD = rp.getProperty("db_admin_passwd"); } public static ConnectionPool getInstance() { if (conPool == null) return new ConnectionPool(); else return conPool; } public synchronized Connection getConnection() { Connection con = null; try { if (pool == null) pool = new Vector<Connection>(); if (pool.isEmpty()) { con = ConnectionPool.createConnection(); } else { int index = pool.size() - 1; con = pool.get(index); pool.remove(pool.get(index)); } } catch (Exception e) { e.printStackTrace(); } ConnectionHandler ch = new ConnectionHandler(this); return ch.bind(con); } public synchronized void releaseConnection(Connection con) { if (pool.size() > POOL_MAX_SIZE) { try { if (con != null) { con.close(); } } catch (Exception e) { e.printStackTrace(); } } else { pool.add(con); } } private static Connection createConnection() { Connection con = null; try { Class.forName(DRIVER_NAME); con = DriverManager.getConnection(URL_BASE + "//" + SERVER_IP + ":" + SERVER_PORT + "/" + DB_NAME, DB_ADMIN_NAME, DB_ADMIN_PASSWD); } catch (ClassNotFoundException CNFex) { CNFex.printStackTrace(); } catch (SQLException SQLex) { SQLex.printStackTrace(); } return con; } }
相关文章推荐
- 封装高可复用的服务端响应对象和登录demo
- 我用HttpClient-MultipartEntity上传文字和图像 服务端没响应。
- .net登录时响应回车事件(按回车键登录)
- 服务端强行要求弹出客户端登录窗口自动登录方法
- 服务端收发登录注冊流程
- 客户端POST发送json数据给服务端,客户端端接收服务器端json数据响应
- javaWeb 简单注册登录(含数据库连接) -- (三) 实现用户注册请求的响应
- 利用LeanCloud移动服务端,简单的登录注册
- JAVA - 手机扫描二维码,页面响应(不是扫码登录)
- fiddler+proxifier修改本地程序响应任意登录
- Jquery Ajax 登录,服务端分别为 aspx,ashx,asmx
- 搭建一个Socket服务端响应多用户访问
- [精华][推荐]SSO CAS 单点登录服务端客户端学习
- 简单的node 服务端 响应get,返回json数据;
- 通过端口 8080 连接到主机 localhost 的 TCP/IP 连接失败。错误:“驱动程序收到意外的登录前响应。请验证连接属性,并检查 SQL Server 的实例正在主机上运行,且在此端口接受
- linux环境下不需要手工输入密码就能SSH登录到服务端B
- sso 单点登录cas使用(3): cas 4.2.7 服务端自定义登录样式
- windows登录ubuntu ssh服务端
- 小程序微信登录+服务端
- 移动端向服务端提交数据——实现简单登录