javaWeb--手写Servlet容器--增加cookie&session版

主类:

public class Catalina {

    static {

        try {
            Container.WEB_CONFIG.load(Catalina.class.getClassLoader().getResourceAsStream("web.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) throws Exception{
        ServerSocket server = new ServerSocket();
        server.bind(new InetSocketAddress(7777));

        while (true){
            Socket accept = server.accept();

            //★获得请求:
            StringBuilder sb = new StringBuilder();
            InputStream in = accept.getInputStream();
            int len;
            byte[] buf = new byte[512];
            while ((len = in.read(buf)) != -1) {
                sb.append(new String(buf, 0, len));
                if (len < buf.length) {
                    accept.shutdownInput();
                }
            }
            // 把请求封装成request对象  构建一个请求对象
            Request request = Request.buildRequest(sb.toString());
            request.setRemoteHost(accept.getInetAddress().getHostAddress());
            String url = request.getUrl();
            if("/favicon.ico".equals(url)){
                continue;
            }

            //先去容器里找,通过请求的url获取一个servlet,如果有则返回
            Servlet servlet = Container.SERVLET_CONTAINER.get(url);
            if(servlet==null){
         ★★★//若容器里没有,去★★★配置文件★★★中找
         ★★//url是个变量,对应着配置文件中各种servlet。
                String fullClassName = Container.WEB_CONFIG.getProperty(url);
                if(!"".equals(fullClassName) && fullClassName!=null){
                    servlet = (Servlet)Class.forName(fullClassName).newInstance();

                }else {
                    servlet = new IndexServlet();
                }
                Container.SERVLET_CONTAINER.put(url,servlet);

            }
            //构建一个响应

            Response response = new Response();
            response.setOs(accept.getOutputStream());
if(request.getHeaders().get("cookie")==null || !request.getHeaders().get("cookie").contains("jsessionid")) {
            String jsessionid = UUID.randomUUID().toString();
            Container.SESSIONS.put(jsessionid,new HashMap<>(8));
            response.addHeader("set-cookie","jsessionid="+jsessionid);
            }
//          把请求和响应交给servlet处理
            servlet.service(request,response);
        }
    }
}

容器:

public class Container {
    public final static Properties WEB_CONFIG=new Properties(); //存配置信息
    public final static HashMap<String,Servlet> SERVLET_CONTAINER =new HashMap<>(8);
public final static Map<String, Map<String,Object>> SESSIONS =new HashMap<>(8);

}

Servlet接口:

public interface Servlet {


    void init();

    void service(Request request,Response response);

    void destroy();
}

Request:

public class Request {

    private String type;
    private String url;
    private String protocol;

    private String contentType;
    private String remoteHost;

    private Map<String,String> headers = new HashMap<>(8);

    private Map<String,String> attributes = new HashMap<>(8);

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    public Map<String, String> getAttributes() {
        return attributes;
    }

    public void setAttributes(Map<String, String> attributes) {
        this.attributes = attributes;
    }

    public String getRemoteHost() {
        return remoteHost;
    }

    public void setRemoteHost(String remoteHost) {
        this.remoteHost = remoteHost;
    }

    @Override
    public String toString() {
        return "Request{" +
                "type='" + type + '\'' +
                ", url='" + url + '\'' +
                ", protocol='" + protocol + '\'' +
                ", contentType='" + contentType + '\'' +
                ", headers=" + headers +
                ", attributes=" + attributes +
                '}';
    }

    // 通过请求的报文字符串构建一个请求对象
    public static Request buildRequest(String requestStr){
        Request request = new Request();
        String[] split = requestStr.split("\r\n\r\n");
        // 请求行
        String[] lineAndHeader = split[0].split("\r\n");
        String[] lines = lineAndHeader[0].split(" ");
        request.setType(lines[0]);
        request.setUrl(lines[1]);
        request.setProtocol(lines[2]);
        // 遍历,获取请求头
        for (int i = 1; i < lineAndHeader.length; i++) {
            String[] header = lineAndHeader[i].split(": ");
            request.getHeaders().put(header[0].trim().toLowerCase(),header[1].trim());
        }

        request.setContentType(request.getHeaders().get("content-type"));

        // 处理请求体
        if (split.length == 2){
            // 可以自己使用postman模拟一个post请求进行分割和存储
        }

        return request;
    }
}

Response:

public class Response {

    private String protocol = "HTTP/1.1";
    private Integer code = 200;
    private String msg = "OK";
    private String ContentType = "text/html;charset=utf-8";
    private String ContentLength;
    private Map<String,String > headers = new HashMap(){{
        put("content-type",ContentType);
    }};
    private String data;
    private OutputStream os;


    public Response(){}

    public Response(String protocol, Integer code, String msg) {
        this.protocol = protocol;
        this.code = code;
        this.msg = msg;
    }


    /**
     * 构建响应
     * @return
     */
    public String buildResponse(){
        StringBuilder sb = new StringBuilder();
        sb.append(this.getProtocol()).append(" ")
                .append(this.getCode()).append(" ")
                .append(this.getMsg()).append("\r\n");
        for (Map.Entry<String,String> entry : this.getHeaders().entrySet()){
            sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
        }
        sb.append("\r\n").append(this.getData());
        return sb.toString();
    }

    /**
     * 输出响应
     * @param
     */
    public void write(){
        try {
            os.write(buildResponse().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public void write(String content){
        this.setData(content);
        this.write();


    }

    /**
     * 加一个响应头
     * @param key
     * @param value
     */
    public void addHeader(String key,String value){
        this.getHeaders().put(key,value);
    }

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
        this.setContentLength(data.getBytes().length+"");
    }

    public OutputStream getOs() {
        return os;
    }

    public void setOs(OutputStream os) {
        this.os = os;
    }

    public String getContentType() {
        return this.getHeaders().get("content-type");
    }

    public void setContentType(String contentType) {
        this.getHeaders().put("content-type",contentType);
    }

    public String getContentLength() {
        return  this.getHeaders().get("content-length");
    }

    public void setContentLength(String contentLength) {
        this.getHeaders().put("content-length",this.data.getBytes().length + "");
    }
}

配置文件web.properties:

/index=com.itnls.Tomcat.servlet.IndexServlet
/home=com.itnls.Tomcat.servlet.HomeServlet
/order=com.itnls.Tomcat.servlet.OrderServlet
/user=com.itnls.Tomcat.servlet.UserServlet

HttpUtils:

public class HttpUtils {


    // 使用流获得页面的字符串
    public static String getPage(String url){
        StringBuilder sb = new StringBuilder();
        try {
            if ("".equals(url) || "/".equals(url) || url == null){
                url = "index.html";
            }
            // 寻找绝对的父路劲
            String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
            path = path.substring(0,path.lastIndexOf("/")) + "/pages/";
            url = path + url;
            boolean exists = new File(url).exists();
            if (!exists){
                url = path +"404.html";
            }

            InputStream resource = new FileInputStream(url);
            byte[] buf = new byte[1024];
            int len;
            while ((len = resource.read(buf)) != -1){
                sb.append(new String(buf,0,len));
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return sb.toString();
    }

}

GenericServlet抽离冗余方法:

/**
 * 抽离冗余代码,新建servlet的时候就不必再实现一遍两个方法了
 */

public abstract class GenericServlet implements Servlet {

    @Override
    public void init() {

    }

    @Override
    public void destroy() {

    }
}

OrderServlet继承GenericServlet:

public class OrderServlet extends GenericServlet {
    @Override
    public void service(Request request, Response response) {

    }
}

HttpServlet继承genericservlet:

public class HttpServlet extends GenericServlet {
    @Override
    public void service(Request request, Response response) {
        if("GET".equals(request.getType())){
            this.doGet(request,response);
        }else if("POST".equals(request.getType())){
            this.doPost(request,response);
        }
    }

    public void doGet(Request request, Response response){

    }

    public void doPost(Request request, Response response){

    }
}

UserServlet继承HttpServlet:

public class UserServlet extends HttpServlet {
    @Override
    public void doGet(Request request, Response response) {
        response.write("<h1>hahaha,user!</h1>");
    }
}

IndexServlet实现Servlet接口(有cookie):

public class IndexServlet implements Servlet {

    //让init在创建的时候就开始执行一次
    public IndexServlet(){
        init();
    }

    /**
     * init只会调用一次
     */
    @Override
    public void init() {

    }

    @Override
    public void service(Request request, Response response) {
     String cookie = request.getHeaders().get("cookie");
        if(cookie==null){
            response.write("<h1>login please!!</h1>");
        }else{
            String sessionId = cookie.split("=")[1];
            Map<String, Object> session = Container.SESSIONS.get(sessionId);
            session.put("user","zhangsan");
            response.write("<h1>登陆成功!</h1>");
        }

    }

    @Override
    public void destroy() {

    }
}

HomeServlet实现Servlet接口(有cookie):

public class HomeServlet implements Servlet {

    public static final List<String> BLACK_NAMES =new ArrayList(){{
        add("192.168.67.66");
    }};

    public HomeServlet(){
        init();
    }
    @Override
    public void init() {

    }

    @Override
    public void service(Request request, Response response) {
       String cookie = request.getHeaders().get("cookie");
        if(cookie==null){
            response.write("<h1>login please!!</h1>");
        }else{
            String sessionId = cookie.split("=")[1];
            Map<String, Object> session = Container.SESSIONS.get(sessionId);
            if(session==null || session.get("user")==null){
                response.write("<h1>未登录</h1>");
            }else{
                response.write("<h1>你好"+ session.get("user") +"</h1>");
            }
        }
    }

    @Override
    public void destroy() {

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值