V2版本我们需要支持请求参数解析以及简单的HTML页面渲染功能。
BinCatServerV2实现代码:
package com.anbai.sec.server;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.net.URLDecoder;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.logging.Logger;/*** ServerSocket Http 服务器示例*/public class BinCatServerV2 {private static final Logger LOG = Logger.getLogger("info");public static void main(String[] args) {try {// 设置服务监听端口int port = 8080;// 设置服务名称String serverName = "BinCat-0.0.2";// 创建ServerSocket,监听本地端口ServerSocket ss = new ServerSocket(port);LOG.info(serverName + " 启动成功,监听端口: " + port);while (true) {// 等待客户端连接Socket socket = ss.accept();try {// 获取Socket输入流对象InputStream in = socket.getInputStream();// 获取Socket输出流对象OutputStream out = socket.getOutputStream();// 创建数据输出流对象DataInputStream dis = new DataInputStream(in);// 从Socket中读取一行数据,读取请求的URLString str = dis.readLine();if (str == null) {socket.close();continue;}// 切割请求Http协议信息String[] strs = str.split("\\s+");// 解析Http请求方法类型String method = strs[0];// 解析Http请求URL地址String url = strs[1];// 初始化Http请求URL地址String requestURL = url;// 初始化Http请求的QueryStringString queryString;// 解析Http请求版本信息String httpVersion = strs[2];// 创建Header对象Map<String, String> header = new ConcurrentHashMap<String, String>();// 初始化请求参数数组Map<String, String> parameterMap = new ConcurrentHashMap<String, String>();// 解析GET请求参数if (url.contains("?")) {String[] parameterStrs = url.split("\\?");requestURL = parameterStrs[0];queryString = parameterStrs[1];// 按"&"切割GET请求的参数String[] parameters = queryString.split("&");// 解析GET请求参数for (String parameter : parameters) {String[] tmp = parameter.split("=", -1);if (tmp.length == 2) {parameterMap.put(tmp[0], URLDecoder.decode(tmp[1]));}}}// 解析请求头信息while (true) {// 按行读取Header头信息String line = dis.readLine();// 当读取到空行时停止解析Headerif ("".equals(line)) {break;}// 切割Header的Key/ValueString[] headers = line.split(":\\s*", -1);header.put(headers[0], headers[1]);}// 输出服务器返回信息StringBuffer msg = new StringBuffer();// 处理Http请求,当浏览器请求主页时返回服务器信息if ("/".equals(requestURL)) {out.write("HTTP/1.1 200 OK\n".getBytes());// 根据Http请求类型处理不同的请求if ("GET".equalsIgnoreCase(method)) {// 输出服务器处理结果msg.append("<html>\n" +"<head>\n" +" <title>Login Test</title>\n" +"</head>\n" +"<body>\n" +"<div style=\"margin: 30px;\">\n" +" <form action=\"/\" method=\"POST\">\n" +" Username:<input type=\"text\" name=\"username\" value=\"admin\"/><br/>\n" +" Password:<input type=\"text\" name=\"password\" value=\"'=0#\"/><br/>\n" +" <input type=\"submit\" value=\"Login\"/>\n" +" </form>\n" +"</div>\n" +"</body>\n" +"</html>");} else if ("POST".equalsIgnoreCase(method)) {String contentType = header.get("Content-Type");// 解析POST请求参数if ("application/x-www-form-urlencoded".equalsIgnoreCase(contentType)) {// 获取请求的主体长度int contentLength = Integer.parseInt(header.get("Content-Length"));// 创建一个和请求体一样大小的缓冲区byte[] bytes = new byte[contentLength];// 读取POST主体内容dis.read(bytes);// 解析POST请求内容String body = new String(bytes, "ISO8859-1");// 按"&"切割POST请求的参数String[] parameters = body.split("&");// 解析POST请求参数for (String parameter : parameters) {String[] tmp = parameter.split("=", -1);if (tmp.length == 2) {parameterMap.put(tmp[0], URLDecoder.decode(tmp[1]));}}// 定义SQL语句String sql = "select id,username,password from sys_user where username = '" +parameterMap.get("username") + "' and password = '" +parameterMap.get("password") + "'";msg.append("<font color='red'>JDBC 查询SQL:" + sql + "</font>\n");msg.append("<h3>请求头:</h3>\n");msg.append("<pre>\n");for (String key : header.keySet()) {msg.append(key + ": " + header.get(key) + "\n");}msg.append("<pre>\n");msg.append("<h3>请求参数:</h3>\n");// 循环遍历请求参数for (String key : parameterMap.keySet()) {msg.append(key + ": " + parameterMap.get(key) + "\n");}}}} else {out.write("HTTP/1.1 404 Not Found\n".getBytes());// 输出错误信息msg.append("404");}// 输出Web服务器信息out.write(("Server: " + serverName + "\n").getBytes());// 输出返回的消息类型out.write(("Content-Type: text/html; charset=UTF-8\n").getBytes());// 请求响应内容byte[] responseByte = msg.toString().getBytes();// 输出返回字节数out.write(("Content-Length: " + responseByte.length + "\n").getBytes());// 写入换行out.write("\n".getBytes());// 将读取到的数据写入到客户端Socketout.write(responseByte);in.close();out.close();} catch (IOException e) {LOG.info("处理客户端请求异常:" + e);} finally {socket.close();}}} catch (IOException e) {e.printStackTrace();}}}
