(四)——Request
1 package my.tomcat2; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.UnsupportedEncodingException; 7 import java.net.Socket; 8 import java.net.URLDecoder; 9 import java.util.ArrayList; 10 import java.util.HashMap; 11 import java.util.List; 12 import java.util.Map; 13 14 /** 15 * 用来接收客户端发来的头信息,并且解析头信息的第一句,也就是 method 是 Get 还是 POST, URL, param(参数) 16 */ 17 public class Request { 18 private static final String CRLF = "\r\n"; 19 //将参数存入 Map 中去,因为有可能会有要读取 CheckBox 复选框的参数值,他们属于同一个 name,所以要将他们存入到一个 List 中去 20 private Map<String, List<String>> paramMap; 21 //读取客户端的 头信息 22 private BufferedReader bw; 23 //将读取到的头信息append到一个StringBuilder中 24 private StringBuilder requestInfo; 25 //URL 26 private String url; 27 //Get 或者 POST 28 private String method; 29 //参数 30 private String param = ""; 31 32 //初始化 字段 33 public Request() { 34 paramMap = new HashMap<>(); 35 } 36 37 public Request(Socket client) { 38 try { 39 paramMap = new HashMap<>(); 40 bw = new BufferedReader(new InputStreamReader(client.getInputStream())); 41 requestInfo = new StringBuilder(); 42 String msg; 43 //这里有两个问题,线程是会循环的,所以会读到什么还请自己动手 BUG 一番,第一次循环最后会读到“”,第二次会首先读到 null 44 String hi = bw.readLine(); 45 while (hi != null && !((msg = hi).equals(""))) { 46 hi = bw.readLine(); 47 requestInfo.append(msg).append(CRLF); 48 } 49 } catch (IOException e) { 50 CloseUtil.closeSocket(client); 51 } 52 //将读到的 头信息 解析 53 if(!(requestInfo.toString().equals(""))) { 54 parseRequestInfo(requestInfo.toString()); 55 } 56 } 57 58 //将所有 substring()获得的字符串调用 trim(),去掉空白字符,不然会出问题 59 public void parseRequestInfo(String info) { 60 String firstInfo = info.substring(0, info.indexOf(CRLF)).trim(); 61 method = firstInfo.substring(0, firstInfo.indexOf("/")).trim(); 62 String shortInfo = firstInfo.substring(firstInfo.indexOf("/"), firstInfo.indexOf("HTTP/")).trim(); 63 64 if (method.equalsIgnoreCase("get")) { 65 if (shortInfo.contains("?")) { 66 String[] str = shortInfo.split("[?]"); 67 this.url = str[0]; 68 this.param = str[1]; 69 } else { 70 this.url = shortInfo; 71 } 72 } else if (method.equalsIgnoreCase("post")) { 73 this.url = shortInfo; 74 this.param = info.substring(info.lastIndexOf(CRLF)).trim(); 75 } 76 77 if (param.equals("")) { 78 return; 79 } 80 parseParam(param); 81 } 82 83 //解析 参数 84 public void parseParam(String param) { 85 String[] values = param.split("&"); 86 String[][] pair = new String[values.length][2]; 87 88 for (int i = 0; i < pair.length; i++) { 89 String[] str = values[i].split("="); 90 for (int j = 0; j < 2; j++) { 91 if (1 == str.length) { 92 pair[i][j] = str[j]; 93 pair[i][j + 1] = null; 94 break; 95 } else { 96 pair[i][j] = str[j]; 97 } 98 } 99 } 100 101 storeParam(pair); 102 } 103 104 //将解析完的参数,存入到 Map 中去 105 public void storeParam(String[][] pair) { 106 for (int i = 0; i < pair.length; i++) { 107 if (paramMap.containsKey(pair[i][0])) { 108 paramMap.get(pair[i][0]).add(decode(pair[i][1], "utf8")); 109 }else{ 110 paramMap.put(pair[i][0], new ArrayList<>()); 111 paramMap.get(pair[i][0]).add(decode(pair[i][1], "utf8")); 112 } 113 } 114 } 115 116 //获取多个参数,例如复选框之类的 117 public String[] getParams(String key){ 118 if(paramMap.containsKey(key)){ 119 return paramMap.get(key).toArray(new String[0]); 120 }else { 121 return null; 122 } 123 } 124 125 //这个是我用来在页面上显示复选框的多个属性值的,暂且搁浅 126 public String splitParams(String key){ 127 String[] str = getParams(key); 128 StringBuilder sb = new StringBuilder(); 129 for(String temp : str){ 130 sb.append(temp); 131 } 132 return sb.toString(); 133 } 134 //这里如果是没有get参数的话,是会返回null, getParams(key)[0] 也就是 null[0],当然会报错。应该是getParams(key),这个问题缠绕了我一些时间。。。 135 public String getParam(String key){ 136 // return getParams(key)[0] == null ? "null" : getParams(key)[0]; 137 return getParams(key) == null ? "null" : getParams(key)[0]; 138 } 139 140 //解决中文参数,如果没有这个方法的话,你的参数值为中文的话,在页面上显示的是乱码 141 public String decode(String value, String code) { 142 try { 143 return URLDecoder.decode(value, code); 144 } catch (UnsupportedEncodingException e) { 145 e.printStackTrace(); 146 } 147 return null; 148 } 149 150 //获取URL 151 public String getUrl(){ 152 return this.url; 153 } 154 }