目标:将获取的参数封装成map结构
给request增加存储参数的map数据成员,将请求参数存储到容器中,并增加参数值支持中文的函数
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
* 封装请求协议:获取method uri以及请求参数
* 封装请求参数为map
*/
public class request {
//协议信息
private String requestInfo;
//请求方式
private String method;
//请求url
private String url;
//请求参数
private String queryString;
//存储参数map结构
private Map<String, List<String>> parameterMap;
private final String CRLF = "\r\n";
public request(InputStream is) {
parameterMap = new HashMap<String, List<String>>();
byte[] datas = new byte[1024*1024];
int len;
try {
len = is.read(datas); //*
requestInfo = new String(datas, 0, len);
//分解字符串
parseRequestInfo();
} catch (IOException e) {
e.printStackTrace();
}
}
public request(Socket client) throws IOException {
this(client.getInputStream()); //构造器相互调用,this在首行异常只能throw
}
private void parseRequestInfo() {
System.out.println(requestInfo);
//获取请求方式:从开头到空格/
method = requestInfo.substring(0, requestInfo.indexOf('/')).toLowerCase().trim(); //trim去除前后空格
System.out.println(method);
//获取url:第一个/到HTTP/
url = requestInfo.substring(requestInfo.indexOf('/')+1, requestInfo.indexOf("HTTP/"));
int queryIndex = url.indexOf('?');
if(queryIndex > 0) { //存在请求参数
String[] arr = url.split("\\?");
url = arr[0];
queryString = arr[1];
}
//get的话参数已获取完,post的参数可能在请求体中
if(null == queryString)
queryString = "";
if(method.equals("post")) {
String qString = this.requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
queryString += "&" + qString;
}
//封装参数
convertMap();
}
//处理中文
private String decode(String value, String enc) {
try {
return java.net.URLDecoder.decode(value, enc);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private void convertMap() {
//参数之间是&分隔的
String[] keySValues = queryString.split("&");
for(String queryStr : keySValues) {
String[] kv = queryStr.split("="); //可能存在没有值的情况
kv = Arrays.copyOf(kv, 2); //保证kv有两个元素
String valueString = kv[1] == null ? null : decode(kv[1], "utf-8");
if(!parameterMap.containsKey(kv[0])){
parameterMap.put(kv[0], new ArrayList<String>());
}
parameterMap.get(kv[0]).add(valueString);
}
}
public String[] getparameterMap(String key) {
List<String> values = parameterMap.get(key);
if(null == values || values.size()<1)
return null;
return values.toArray(new String[0]);
}
public String getMethod() {
return method;
}
public String getUrl() {
return url;
}
public String getQueryString() {
return queryString;
}
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 封装请求信息
*/
public class server03 {
private ServerSocket serverSocket;
public static void main(String[] args) {
server03 s1 = new server03();
s1.start();
}
//启动服务
public void start() {
try {
serverSocket = new ServerSocket(8888);
receive();
} catch (IOException e) {
e.printStackTrace();
System.out.println("启动服务失败");
}
}
//接受连接处理
public void receive() {
try {
Socket clientSocket = serverSocket.accept();
System.out.println("一个客户端建立了连接");
//获取请求协议(没有请求资源的情况下可以返回一个主页html)
request re = new request(clientSocket);
String[] values = re.getparameterMap("uname");
for(String str : values)
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
}
}
//停止服务
public void stop() {
}
}
在request中增加的map结构的键是key,值是list结构的值 1,解决了键值一对多的情况
存储一个键的多个值 ↩︎