模拟获取请求协议和返回响应协议(完结版)

模拟获取请求协议和返回响应协议(完结版)

package cn.com.serverlet02;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.*;

//封装请求协议:封装请求参数为Map
public class Request2 {
    //协议信息
    private String requestInfo;
    //请求方式
    private String method;
    //请求的url
    private String url;
    //请求的参数
    private String par;
    //存储参数
    private Map<String,List<String>> pMap;
    private final String CRLF = "\n";
    //封装请求协议 获取method url 以及请求参数
    public Request2(Socket client) throws IOException {
        this(client.getInputStream());
    }

    public Request2(InputStream is) {
        pMap = new HashMap<>();
        byte[] datas = new byte[1024*1024];
        int len ;
        try {
            len = is.read(datas);
            this.requestInfo = new String(datas,0,len);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        //分解字符串
        parseRequestInfo();
    }
    private void parseRequestInfo() {
        System.out.println("-------分解-------");
        System.out.println(requestInfo);
        System.out.println("---1,获取请求方式:开头到第一个/---");
        this.method = this.requestInfo.substring
                (0,this.requestInfo.indexOf("/")).toLowerCase();//转小写
        this.method = this.method.trim(); //去除前后空格
        System.out.println("---2,获取请求的url:第一个/到HTTP/");
        System.out.println("---可能包含请求参数?前面的为url---");
        //1 获取第一个/的位置
        int startIdx = this.requestInfo.indexOf("/")+1;
        //2 获取HTTP/的位置
        int endIdx = this.requestInfo.indexOf("HTTP/");
        //3 分割字符串
        this.url = this.requestInfo.substring(startIdx,endIdx);
        //4 获取?的位置
        int queryidx = this.url.indexOf("?");
        if (queryidx >= 0) {//表示存在请求参数
            String[] urlArray = this.url.split("\\?");
            this.url = urlArray[0];
            par = urlArray[1];
        }
        System.out.println(this.url);
        System.out.println("---3,获取url后面的请求参数:如果是get,已经获取;如果是post,可能在请求体中---");

        if (method.equals("post")) {
            String qStr = this.requestInfo.substring(this.requestInfo.lastIndexOf(CRLF)).trim();
            if (par == null) {
                par= qStr;
            }else {
                par += "&"+qStr;
            }
        }
        par = par == null ? "": par;
        System.out.println(method+"-->"+url+"-->"+par);
        //转成map fav=1&fav=2&name=yuxiaohao&age=18&others=
        convertMap();
    }
    //处理请求参数为Map
    private void convertMap() {
        //1 分割字符串 按 & 分割
        String[] keyValues = this.par.split("&");
        for (String par1: keyValues) {
            //2 再次分割字符串 按 = 分割
            String[] kv = par1.split("=");
            kv = Arrays.copyOf(kv,2);
            //获取key和value
            String key = kv[0];
            String value = kv[1] == null ? null : decode(kv[1],"utf-8");
            //存储到map中
            if (!pMap.containsKey(key)) {//表示第一次
                pMap.put(key,new ArrayList<>());
            }
            pMap.get(key).add(value);
        }
    }
    //处理中文(post)
    private String decode(String value,String enc) {
        try {
            return java.net.URLDecoder.decode(value,enc);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
    //通过(表单)name获取对应的多个值
    public String[] getParameterValues(String key) {
        List<String> list = this.pMap.get(key);
        if (list == null || list.size() < 1) {
            return null;
        }
        return list.toArray(new String[0]);
    }
    //通过name获取对应的一个值
    public String getParameter(String key) {
        String[] values =getParameterValues(key);
        return values == null ? null : values[0];
    }

    public String getMethod() {
        return method;
    }

    public String getUrl() {
        return url;
    }

    public String getPar() {
        return par;
    }

}

测试用例

package cn.com.serverlet02;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server05 {
    //封装请求信息中的参数转成了map
    private ServerSocket serverSocket ;
    public static void main(String[] args) {
        Server05 server = new Server05();
        server.start();
    }
    //启动服务
    public void start() {
        try {
            serverSocket =  new ServerSocket(9999);
            receive();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("服务器启动失败....");
        }
    }
    //接受连接处理
    public void receive() {
        try {
            Socket client = serverSocket.accept();
            System.out.println("一个客户端建立了连接....");
            //获取请求协议
            Request2 request2 = new Request2(client);

            Response response = new Response(client);
            //关注了内容
            response.print("<html>");
            response.print("<head>");
            response.print("<title>");
            response.print("服务器响应成功");
            response.print("</title>");
            response.print("</head>");
            response.print("<body>");
            response.print("shsxt server终于回来了。。。。"+request2.getParameter("uname"));
            response.print("</body>");
            response.print("</html>");
            //关注了状态码
            response.pushToBrowser(200);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("客户端错误");
        }
    }
    //停止服务
    public void stop() {

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值