V2版本我们需要支持请求参数解析以及简单的HTML页面渲染功能。
    BinCatServerV2实现代码:

    1. package com.anbai.sec.server;
    2. import java.io.*;
    3. import java.net.ServerSocket;
    4. import java.net.Socket;
    5. import java.net.URLDecoder;
    6. import java.util.Map;
    7. import java.util.concurrent.ConcurrentHashMap;
    8. import java.util.logging.Logger;
    9. /**
    10. * ServerSocket Http 服务器示例
    11. */
    12. public class BinCatServerV2 {
    13. private static final Logger LOG = Logger.getLogger("info");
    14. public static void main(String[] args) {
    15. try {
    16. // 设置服务监听端口
    17. int port = 8080;
    18. // 设置服务名称
    19. String serverName = "BinCat-0.0.2";
    20. // 创建ServerSocket,监听本地端口
    21. ServerSocket ss = new ServerSocket(port);
    22. LOG.info(serverName + " 启动成功,监听端口: " + port);
    23. while (true) {
    24. // 等待客户端连接
    25. Socket socket = ss.accept();
    26. try {
    27. // 获取Socket输入流对象
    28. InputStream in = socket.getInputStream();
    29. // 获取Socket输出流对象
    30. OutputStream out = socket.getOutputStream();
    31. // 创建数据输出流对象
    32. DataInputStream dis = new DataInputStream(in);
    33. // 从Socket中读取一行数据,读取请求的URL
    34. String str = dis.readLine();
    35. if (str == null) {
    36. socket.close();
    37. continue;
    38. }
    39. // 切割请求Http协议信息
    40. String[] strs = str.split("\\s+");
    41. // 解析Http请求方法类型
    42. String method = strs[0];
    43. // 解析Http请求URL地址
    44. String url = strs[1];
    45. // 初始化Http请求URL地址
    46. String requestURL = url;
    47. // 初始化Http请求的QueryString
    48. String queryString;
    49. // 解析Http请求版本信息
    50. String httpVersion = strs[2];
    51. // 创建Header对象
    52. Map<String, String> header = new ConcurrentHashMap<String, String>();
    53. // 初始化请求参数数组
    54. Map<String, String> parameterMap = new ConcurrentHashMap<String, String>();
    55. // 解析GET请求参数
    56. if (url.contains("?")) {
    57. String[] parameterStrs = url.split("\\?");
    58. requestURL = parameterStrs[0];
    59. queryString = parameterStrs[1];
    60. // 按"&"切割GET请求的参数
    61. String[] parameters = queryString.split("&");
    62. // 解析GET请求参数
    63. for (String parameter : parameters) {
    64. String[] tmp = parameter.split("=", -1);
    65. if (tmp.length == 2) {
    66. parameterMap.put(tmp[0], URLDecoder.decode(tmp[1]));
    67. }
    68. }
    69. }
    70. // 解析请求头信息
    71. while (true) {
    72. // 按行读取Header头信息
    73. String line = dis.readLine();
    74. // 当读取到空行时停止解析Header
    75. if ("".equals(line)) {
    76. break;
    77. }
    78. // 切割Header的Key/Value
    79. String[] headers = line.split(":\\s*", -1);
    80. header.put(headers[0], headers[1]);
    81. }
    82. // 输出服务器返回信息
    83. StringBuffer msg = new StringBuffer();
    84. // 处理Http请求,当浏览器请求主页时返回服务器信息
    85. if ("/".equals(requestURL)) {
    86. out.write("HTTP/1.1 200 OK\n".getBytes());
    87. // 根据Http请求类型处理不同的请求
    88. if ("GET".equalsIgnoreCase(method)) {
    89. // 输出服务器处理结果
    90. msg.append("<html>\n" +
    91. "<head>\n" +
    92. " <title>Login Test</title>\n" +
    93. "</head>\n" +
    94. "<body>\n" +
    95. "<div style=\"margin: 30px;\">\n" +
    96. " <form action=\"/\" method=\"POST\">\n" +
    97. " Username:<input type=\"text\" name=\"username\" value=\"admin\"/><br/>\n" +
    98. " Password:<input type=\"text\" name=\"password\" value=\"'=0#\"/><br/>\n" +
    99. " <input type=\"submit\" value=\"Login\"/>\n" +
    100. " </form>\n" +
    101. "</div>\n" +
    102. "</body>\n" +
    103. "</html>");
    104. } else if ("POST".equalsIgnoreCase(method)) {
    105. String contentType = header.get("Content-Type");
    106. // 解析POST请求参数
    107. if ("application/x-www-form-urlencoded".equalsIgnoreCase(contentType)) {
    108. // 获取请求的主体长度
    109. int contentLength = Integer.parseInt(header.get("Content-Length"));
    110. // 创建一个和请求体一样大小的缓冲区
    111. byte[] bytes = new byte[contentLength];
    112. // 读取POST主体内容
    113. dis.read(bytes);
    114. // 解析POST请求内容
    115. String body = new String(bytes, "ISO8859-1");
    116. // 按"&"切割POST请求的参数
    117. String[] parameters = body.split("&");
    118. // 解析POST请求参数
    119. for (String parameter : parameters) {
    120. String[] tmp = parameter.split("=", -1);
    121. if (tmp.length == 2) {
    122. parameterMap.put(tmp[0], URLDecoder.decode(tmp[1]));
    123. }
    124. }
    125. // 定义SQL语句
    126. String sql = "select id,username,password from sys_user where username = '" +
    127. parameterMap.get("username") + "' and password = '" +
    128. parameterMap.get("password") + "'";
    129. msg.append("<font color='red'>JDBC 查询SQL:" + sql + "</font>\n");
    130. msg.append("<h3>请求头:</h3>\n");
    131. msg.append("<pre>\n");
    132. for (String key : header.keySet()) {
    133. msg.append(key + ": " + header.get(key) + "\n");
    134. }
    135. msg.append("<pre>\n");
    136. msg.append("<h3>请求参数:</h3>\n");
    137. // 循环遍历请求参数
    138. for (String key : parameterMap.keySet()) {
    139. msg.append(key + ": " + parameterMap.get(key) + "\n");
    140. }
    141. }
    142. }
    143. } else {
    144. out.write("HTTP/1.1 404 Not Found\n".getBytes());
    145. // 输出错误信息
    146. msg.append("404");
    147. }
    148. // 输出Web服务器信息
    149. out.write(("Server: " + serverName + "\n").getBytes());
    150. // 输出返回的消息类型
    151. out.write(("Content-Type: text/html; charset=UTF-8\n").getBytes());
    152. // 请求响应内容
    153. byte[] responseByte = msg.toString().getBytes();
    154. // 输出返回字节数
    155. out.write(("Content-Length: " + responseByte.length + "\n").getBytes());
    156. // 写入换行
    157. out.write("\n".getBytes());
    158. // 将读取到的数据写入到客户端Socket
    159. out.write(responseByte);
    160. in.close();
    161. out.close();
    162. } catch (IOException e) {
    163. LOG.info("处理客户端请求异常:" + e);
    164. } finally {
    165. socket.close();
    166. }
    167. }
    168. } catch (IOException e) {
    169. e.printStackTrace();
    170. }
    171. }
    172. }