手写tomcat,实现http访问,解析get请求参数

项目结构如下

由于是简易实现,原理比较简单,

1.新建ServerSocket连接,监听服务端口

2.浏览器输入请求后获取inputStream,outputStream封装成简易的HttpRequest,HttpResponse

3.至于servlet mapping映射直接在ServletMappingConfig使用map集合存储

4.访问servlet类通过java反射机制访问

 

封装httprequest

package com.wying.tomcat;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * description: 输入流解析url和method封装成简易httprequest
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public class HttpRequest {
    private String url;
    private String method;
    private String paramStr;
    private Map<String,String> paramMap=new HashMap<>();

    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getMethod() {
        return method;
    }
    public void setMethod(String method) {
        this.method = method;
    }






    public HttpRequest(InputStream inputStream) throws IOException {


        String httpRequestStr ="";

        byte[] bytes=new byte[1024];
        int length =0;
        if((length=inputStream.read(bytes)) >0){
            httpRequestStr=new String(bytes,0,length);
        }
        System.out.println("HttpRequest inputStream:"+httpRequestStr);
        String httpHead = httpRequestStr.split("\n")[0];
        //解析出http请求的url 和method
        //GET /testServlet?name=123 HTTP/1.1
        method=httpHead.split("\\s")[0];
        String httpUrl=httpHead.split("\\s")[1];

        //解析get传参数据
       if(httpUrl.indexOf("?")>=0){
          String[] httpUrls= httpUrl.split("\\?");
           url=httpUrls[0];
           paramStr=httpUrls[1];
           setParams();
       }else{
           url=httpUrl;
       }
        System.out.println("HttpRequest url:"+url+" method:"+method);

    }
    //解析参数存入map
    private void setParams(){
        System.out.println("解析参数存入map  this.paramStr:"+this.paramStr);
        String[] params = this.paramStr.split("&");

        for (String param : params) {
            String[] keyValue = param.split("=");
            paramMap.put(keyValue[0], keyValue[1]);
        }
    }
    //获取参数
    public String getParamter(String paramName){
        return paramMap.get(paramName);
    }



}

封装httpresponse

package com.wying.tomcat;

import java.io.IOException;
import java.io.OutputStream;

/**
 * description:简单httpresponse 直接出出文本
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public class HttpResponse {
    private OutputStream outputStream;

    public HttpResponse(OutputStream outputStream){
        this.outputStream = outputStream;
    }

    public void write(String content)throws IOException {
        StringBuffer httpResponse = new StringBuffer();
        httpResponse.append("HTTP/1.1 200 OK\n")
                .append("Content-Type: text/html\n")
                .append("\r\n");

        httpResponse.append(content);
        outputStream.write(httpResponse.toString().getBytes());
        outputStream.close();
    }

}

写入url和对应的servlet类映射关系

package com.wying.tomcat;

/**
 * description:
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public class ServletMapping {
    private String servletName;
    private String url;
    private String clazz;

    public ServletMapping(String servletName, String url, String clazz){
        this.servletName=servletName;
        this.url=url;
        this.clazz=clazz;
    }

    public String getServletName() {
        return servletName;
    }
    public void setServletName(String servletName) {
        this.servletName = servletName;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getClazz() {
        return clazz;
    }
    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

}
package com.wying.tomcat;

import java.util.ArrayList;
import java.util.List;

/**
 * description:
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public class ServletMappingConfig {

    public static List<ServletMapping> servletMappingList =new ArrayList<>();
    //简单处理 tomcat是从web.xml读取
    static{
        servletMappingList.add(new ServletMapping("testServlet","/testServlet","com.wying.test.TestServlet"));

    }

}

 

HttpServlet基类

package com.wying.tomcat;

import java.io.IOException;

/**
 * description:
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public abstract class HttpServlet {
    public abstract void doGet(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException;
    public abstract void doPost(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException;
    public void service(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException{
        if(httpRequest.getMethod().equalsIgnoreCase("POST")){
            doPost(httpRequest,httpResponse);
        }else if(httpRequest.getMethod().equalsIgnoreCase("GET")){
            doGet(httpRequest,httpResponse);
        }
    }

}

 

启动类

package com.wying.tomcat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * description:tomcat启动类
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public class Catalina {
    private int port=8088;
    private Map<String,String> urlServletMap =new HashMap<String,String>();
    public Catalina(int port){
        this.port=port;
    }

    public void start() {
//        初始化URL与对应处理的servlet的关系
        initServletMapping();

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("tomcat start port:"+port);

            while (true) {
                System.out.println("开始监听请求....");
                //监听请求
                Socket socket = serverSocket.accept();
                System.out.println("收到请求.....");
                InputStream inputStream = socket.getInputStream();
                OutputStream outputStream = socket.getOutputStream();

                //封装httpRequest
                HttpRequest  httpRequest = new HttpRequest(inputStream);
                //封装httpResponse
                HttpResponse httpResponse = new HttpResponse(outputStream);
                System.out.println("request httpRequestUrl :"+httpRequest .getUrl());
                //分发器
                dispatch(httpRequest, httpResponse);
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != serverSocket) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
    //将url和对应的servlet类存入map
    private void initServletMapping(){
        for (ServletMapping servletMapping : ServletMappingConfig.servletMappingList) {
            urlServletMap.put(servletMapping.getUrl(), servletMapping.getClazz());
        }
    }
    public void dispatch(HttpRequest  httpRequest,HttpResponse httpResponse) throws IOException {
        //根据url找到servlet类
        if("/favicon.ico".equals(httpRequest.getUrl())){
            System.out.println("浏览器获取图标请求 暂时忽略");
            return;
        }
        String clazz =urlServletMap.get( httpRequest.getUrl());
        if(clazz==null){
            httpResponse.write(" error url:"+httpRequest.getUrl()+" not match Servlet");
            return;
        }

        try{
            //通过反射机制创建对应的servlet对象
            Class<HttpServlet> httpServletClass =(Class<HttpServlet>) Class.forName(clazz);
            HttpServlet  httpServlet=  httpServletClass.newInstance();

            httpServlet.service(httpRequest,httpResponse);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }catch (InstantiationException e){
            e.printStackTrace();
        }catch (IllegalAccessException e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        Catalina catalina= new Catalina(8088);
        catalina.start();
    }

}

 

TestServlet

package com.wying.test;

import com.wying.tomcat.HttpRequest;
import com.wying.tomcat.HttpResponse;
import com.wying.tomcat.HttpServlet;

import java.io.IOException;

/**
 * description:
 * date: 2020/7/14
 * author: gaom
 * version: 1.0
 */
public class TestServlet extends HttpServlet {
    @Override
    public void doGet(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException {
        System.out.println("TestServlet doGet............;..");
        String name= httpRequest.getParamter("name");
        httpResponse.write(" <html><body><h1>TestServlet  success!!!! name:"+name+"</h1></body></html>");

    }

    @Override
    public void doPost(HttpRequest httpRequest, HttpResponse httpResponse) {
        System.out.println("TestServlet doPost..............");

    }
}

 

浏览器访问效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值