使用RESTer插件可以模拟post和get请求:
将得到请求协议与返回响应协议封装:
/*目标:使用ServerSocket建立与浏览器连接,获得请求协议*/
public class Server01 {
private ServerSocket serverSocket;
public static void main(String[] args) {
Server01 s = new Server01();
s.start();
}
public void start() {
try {
serverSocket = new ServerSocket(8888);
receive();//建立连接
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
public void receive() {
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
Request r1=new Request(client);
// System.out.println("===============================");
// System.out.println( r1.getParameterSingleValues("name1"));
Response r2 = new Response(client);//文件正文
r2.print("<html>");
r2.print("<head>");
r2.print("<title>");
r2.print("服务器响应成功");
r2.print("</title>");
r2.print("</head>");
r2.print("<body>");
r2.print("requerst name1:"+r1.getParameterSingleValues("name1"));
r2.print("</body>");
r2.print("</html>");
r2.pushToBrowser(200);
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端连接失败");
}
}
}
封装响应协议:
public class Response {
private BufferedWriter bw;
private StringBuilder headInfo;
private final String BLANK=" ";//空行
private final String CRLF="\r\n";//跳到下一行的头
private long size=0;//协议正文大小
private StringBuilder content;//协议正文
private Response(){
headInfo=new StringBuilder();
content=new StringBuilder();
}
public Response(Socket client) {
this();//重载无参构造函数
try {
bw=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void createHeadInfo(int code){//构造响应协议头
//响应协议的状态行:HTTP/1.1 200 OK
headInfo.append("HTTP/1.1").append(BLANK);
headInfo.append(code).append(BLANK);
switch (code){
case 200: headInfo.append("OK").append(CRLF);
break;
case 404: headInfo.append("NOT FOUND").append(CRLF);
break;
case 505: headInfo.append("SERVER ERROR").append(CRLF);
break;
}
//响应头(最后一行有空行)
headInfo.append("Date:").append(new Date()).append(CRLF);
headInfo.append("Server:").append("WebServer02/0.0.1;charset=UTF8").append(CRLF);
headInfo.append("Content-type:text/html").append(CRLF);
headInfo.append("Content-length:").append(size).append(CRLF);
headInfo.append(CRLF);//与正文直接有个空行
}
public Response print(String info){//传入响应协议正文,流操作,返回自身则可以 print.print反复依次调用
content.append(info);
size+=info.getBytes().length;//必须获得字节的长度,而不是字符的长度
return this;//返回本身实例
}
public Response println(String info){//换行的传入正文操作
content.append(info).append(CRLF);
size+=(info+CRLF).getBytes().length;
return this;//返回本身实例
}
public void pushToBrowser(int code) throws IOException {
createHeadInfo(code);//传入状态码,生产响应协议头
bw.append(headInfo);//Writer内的方法
bw.append(content);
bw.flush();
}
}
封装请求协议:
(新增了对请求参数的分析方法)
/*获取 方法(GET/POST等),URL以及请求参数*/
public class Request {
private String requestinfo;
private String method;//方法
private String Url;
private String queryStr;//请求参数
private Map<String, List<String>> parameterMap;//封装请求参数,因为可能一个key值要有不同的value值,所有value是个容器
public Request(InputStream is){
parameterMap=new HashMap<String, List<String>>();
byte[] datas = new byte[1024 * 10 * 10];
try {
is.read(datas);
this.requestinfo = new String(datas, 0, datas.length);
System.out.println(requestinfo);
} catch (IOException e) {
e.printStackTrace();
}
}
public Request(Socket client) throws IOException {
this(client.getInputStream());//构造器相互调用,http协议的底层协议是tcp,所有可以得到浏览器的http协议
parseRequest();
}
private void parseRequest(){
System.out.println("获取请求方式-----------------------------");
int idx1=requestinfo.indexOf("/");
this.method=requestinfo.substring(0,idx1).trim();
System.out.println(method);
System.out.println("获取请求URL-----------------------------");
int idx2=requestinfo.indexOf("HTTP");
int idx3=requestinfo.indexOf("?");
if(idx3>0){
Url=requestinfo.substring(idx1+1,idx3);}else {Url=requestinfo.substring(idx1+1,idx2);}
System.out.println(Url);
System.out.println("获取请求参数-----------------------------");
if(idx3>0){
queryStr=requestinfo.substring(idx3+1,idx2).trim();}else{queryStr=null;}
if(method.equals("POST")){
queryStr=requestinfo.substring(requestinfo.lastIndexOf("\r\n")).trim();
}
System.out.println(queryStr);
if(queryStr!=null) convertMap();
}
private void convertMap(){//处理请求参数,将其转换为Map
//请求参数格式:name1=curry&name2=Ayesha
String[] keyValues=this.queryStr.split("&");//以&符号分割为name1=curry
for(String kv:keyValues){//以=号分割出key与value
String kv1[]=kv.split("=");
String key=kv1[0];//等号前面为key
String value=kv1[1];//等号后为value
//System.out.println(key+"----"+value);
if(!parameterMap.containsKey(key)){
parameterMap.put(key,new ArrayList<String>());//第一次出现当前key值
}
parameterMap.get(key).add(value);//get(key)得到容器v,往里面添值
}
}
public String[] getParameterValues(String key){
List<String> list=parameterMap.get(key);
if(list==null){return null;}
return list.toArray(new String[0]);
}
public String getParameterSingleValues(String key){
String[] s=getParameterValues(key);
return s==null?null:s[0];
}
}