<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          基于netty手寫Tomcat

          共 10685字,需瀏覽 22分鐘

           ·

          2020-10-04 11:00

          作者:MovW

          原文:http://suo.im/5Ar7t8

          netty 簡介

          Netty一個(gè)基于NIO的客戶、服務(wù)器端的編程框架

          1.環(huán)境準(zhǔn)備

          maven依賴

          ??
          ????????????io.netty
          ????????????netty-all
          ????????????4.1.42.Final
          ??

          12345

          RequestMethodEnum 請(qǐng)求方式

          public?enum?RequestMethodEnum?{
          ??GET("GET"),
          ??POST("POST");
          ??public?String?code;
          ??RequestMethodEnum(String?code)?{
          ????this.code=code;
          ??}}12345678

          ParentServlet 父類servlet

          public?abstract?class?ParentServlet?{
          ??public?void?service(ParentRequest?request,?ParentResponse?response)?throws?Exception?{
          ????//service 方法決定調(diào)用doGet、doPost;
          ????if?(RequestMethodEnum.GET.code.equalsIgnoreCase(request.getMethod()))?{
          ??????doGet(request,?response);
          ????}?else?{
          ??????doPost(request,?response);
          ????}
          ??}
          ??protected?abstract?void?doPost(ParentRequest?request,?ParentResponse?response)?throws?Exception;
          ??protected?abstract?void?doGet(ParentRequest?request,?ParentResponse?response)?throws?Exception;
          }
          12345678910111213141516
          1. FirstServlet
          public?class?FirstServlet?extends?ParentServlet?{
          ??@Override
          ??protected?void?doPost(ParentRequest?request,?ParentResponse?response)?throws?Exception?{
          ????response.write("This?is?the?first");
          ??}??@Override
          ??protected?void?doGet(ParentRequest?request,?ParentResponse?response)?throws?Exception?{
          ????this.doPost(request,response);
          ??}}1234567891011
          1. SecondServlet
          public?class?SecondServlet?extends?ParentServlet?{
          ??@Override
          ??protected?void?doPost(ParentRequest?request,?ParentResponse?response)?throws?Exception?{
          ????response.write("this?is?the?second");
          ??}??@Override
          ??protected?void?doGet(ParentRequest?request,?ParentResponse?response)?throws?Exception?{
          ????this.doPost(request,response);
          ??}}1234567891011
          1. ParentRequest
          public?class?ParentRequest?{
          ??private?String?method;
          ??private?String?url;
          ??public?String?getUrl()?{
          ????return?url;
          ??}??public?String?getMethod()?{
          ????return?method;
          ??}}1234567891011121314
          1. ParentResponse
          public?class?ParentResponse?{
          ??private?OutputStream?out;
          ??public?ParentResponse?(OutputStream?out)?{
          ????this.out?=?out;
          ??}??public?void?write(String?s)?throws?Exception{
          ????//輸出也要遵循HTTP
          ????//狀態(tài)碼為200
          ????StringBuilder?sb?=?new?StringBuilder();
          ????sb.append("HTTP/1.1?200?OK?\n")
          ??????.append("Content-Type:?text/html;\n")
          ??????.append("\r\n")
          ??????.append(s);
          ????out.write(sb.toString().getBytes());
          ??}
          }
          1234567891011121314151617
          1. web.properties
          servlet.first.url=/first
          servlet.first.className=com.aiden.servlet.FirstServletservlet.second.url=/secondservlet.second.className=com.aiden.servlet.SecondServlet1234

          2.基于傳統(tǒng)I/O手寫Tomcat

          1. 修改ParentRequest
          public?class?ParentRequest?{
          ??private?String?method;
          ??private?String?url;
          ??public?ParentRequest(InputStream?in)?{
          ????try?{
          ??????String?content?=?"";
          ??????byte[]?buff?=?new?byte[1024];
          ??????int?len?=?0;
          ??????if?((len?=?in.read(buff))?>?0)?{
          ????????content?=?new?String(buff,0,len);
          ??????}??????String?line?=?content.split("\\n")[0];
          ??????String?[]?arr?=?line.split("\\s");
          ??????this.method?=?arr[0];
          ??????System.out.println(method);
          ??????this.url?=?arr[1].split("\\?")[0];
          ????}?catch?(IOException?e)?{
          ??????e.printStackTrace();????}??}??public?String?getUrl()?{
          ????return?url;
          ??}??public?String?getMethod()?{
          ????return?method;
          ??}}12345678910111213141516171819202122232425262728293031
          1. 編寫tomcatStart類
          public?class?TomcatStart?{
          ??private?int?port?=?8080;
          ??private?ServerSocket?server;
          ??private?Map?servletMapping?=?new?HashMap();
          ??private?Properties?webProperties?=?new?Properties();
          ??private?void?init()?{
          ????try?{
          ??????String?WEB_INF?=?this.getClass().getResource("/").getPath();
          ??????FileInputStream?fis?=?new?FileInputStream(WEB_INF?+?"web.properties");
          ??????webProperties.load(fis);??????for?(Object?k?:?webProperties.keySet())?{
          ????????String?key?=?k.toString();
          ????????if?(key.endsWith(".url"))?{
          ??????????String?servletName?=?key.replaceAll("\\.url$",?"");
          ??????????String?url?=?webProperties.getProperty(key);
          ??????????String?className?=?webProperties.getProperty(servletName?+?".className");
          ??????????//單實(shí)例??多線程
          ??????????ParentServlet?obj?=?(ParentServlet)?Class.forName(className).newInstance();
          ??????????servletMapping.put(url,?obj);
          ????????}
          ??????}
          ????}?catch?(Exception?e)?{
          ??????e.printStackTrace();
          ????}
          ??}
          ??public?void?start()?{
          ????//1.加載配置類,初始化servletMapping
          ????init();
          ????try?{
          ??????//2.綁定端口啟動(dòng)
          ??????server?=?new?ServerSocket(this.port);
          ??????System.out.println("Tomcat 已啟動(dòng),監(jiān)聽端口是:"?+?this.port);
          ??????//3.等待用戶請(qǐng)求,用一個(gè)死循環(huán)
          ??????while?(true)?{
          ????????Socket?client?=?server.accept();
          ????????//4.http?請(qǐng)求
          ????????process(client);
          ??????}
          ????}?catch?(IOException?e)?{
          ??????e.printStackTrace();
          ????}
          ??}
          ??private?void?process(Socket?client)?throws?IOException?{
          ????InputStream?is?=?null;
          ????OutputStream?os?=?null;
          ????try?{
          ??????is?=?client.getInputStream();
          ??????os?=?client.getOutputStream();
          ??????//5.Request(inputstream)?Response?(outputstream)
          ??????ParentRequest?request?=?new?ParentRequest(is);
          ??????ParentResponse?response?=?new?ParentResponse(os);
          ??????//6.從協(xié)議內(nèi)容中獲取url?映射相應(yīng)的servlet
          ??????String?url?=?request.getUrl();
          ??????if?(servletMapping.containsKey(url))?{
          ????????//7.調(diào)用實(shí)例化對(duì)象的service方法
          ????????servletMapping.get(url).service(request,?response);
          ??????}?else?{
          ????????response.write("404?-?Not?Found");
          ??????}
          ????}?catch?(Exception?e)?{
          ??????e.printStackTrace();
          ????}?finally?{
          ??????if?(os?!=?null)?{
          ????????os.flush();
          ????????os.close();
          ??????}
          ??????if?(is?!=?null)?{
          ????????is.close();
          ??????}
          ??????client.close();
          ????}
          ??}
          ??public?static?void?main(String[]?args)?{
          ????//啟動(dòng)
          ????new?TomcatStart().start();
          ??}
          }
          12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182

          3.基于netty手寫Tomcat

          1. 修改ParentRequest
          public?class?ParentRequest?{
          ??private?ChannelHandlerContext?ctx;
          ??private?HttpRequest?req;
          ??public?ParentRequest(ChannelHandlerContext?ctx,?HttpRequest?req)?{
          ????this.ctx?=?ctx;
          ????this.req?=?req;
          ??}??public?String?getUrl()?{
          ????return?req.uri();
          ??}??public?String?getMethod()?{
          ????return?req.method().name();
          ??}??public?Map>?getParameters()?{
          ????QueryStringDecoder?decoder?=?new?QueryStringDecoder(req.uri());
          ????return?decoder.parameters();
          ??}??public?String?getParameter(String?name)?{
          ????Map>?params?=?getParameters();
          ????List?param?=?params.get(name);
          ????if?(null?==?param)?{
          ??????return?null;
          ????}?else?{
          ??????return?param.get(0);
          ????}??}}123456789101112131415161718192021222324252627282930313233
          1. 修改ParentResponse
          public?class?ParentResponse?{
          ??//SocketChannel的封裝??private?ChannelHandlerContext?ctx;??private?HttpRequest?req;??public?ParentResponse(ChannelHandlerContext?ctx,?HttpRequest?req)?{????this.ctx?=?ctx;????this.req?=?req;??}??public?void?write(String?out)?throws?Exception?{
          ????try?{??????if?(out?==?null?||?out.length()?==?0)?{
          ????????return;
          ??????}??????//?設(shè)置?http協(xié)議及請(qǐng)求頭信息??????FullHttpResponse?response?=?new?DefaultFullHttpResponse(????????//?設(shè)置http版本為1.1
          ????????HttpVersion.HTTP_1_1,????????//?設(shè)置響應(yīng)狀態(tài)碼????????HttpResponseStatus.OK,????????//?將輸出值寫出?編碼為UTF-8
          ????????Unpooled.wrappedBuffer(out.getBytes("UTF-8")));
          ??????response.headers().set("Content-Type",?"text/html;");
          ??????ctx.write(response);
          ????}?finally?{??????ctx.flush();
          ??????ctx.close();
          ????}??}}12345678910111213141516171819202122232425262728293031323334
          1. 修改TomcatStart
          public?class?TomcatStart?{
          ??private?int?port?=?8080;
          ??private?Map?servletMapping?=?new?HashMap();
          ??private?Properties?webProperties?=?new?Properties();
          ??private?void?init()?{
          ????try?{
          ??????String?WEB_INF?=?this.getClass().getResource("/").getPath();
          ??????FileInputStream?fis?=?new?FileInputStream(WEB_INF?+?"web.properties");
          ??????webProperties.load(fis);??????for?(Object?k?:?webProperties.keySet())?{
          ????????String?key?=?k.toString();
          ????????if?(key.endsWith(".url"))?{
          ??????????String?servletName?=?key.replaceAll("\\.url$",?"");
          ??????????String?url?=?webProperties.getProperty(key);
          ??????????String?className?=?webProperties.getProperty(servletName?+?".className");
          ??????????//單實(shí)例??多線程
          ??????????ParentServlet?obj?=?(ParentServlet)?Class.forName(className).newInstance();
          ??????????servletMapping.put(url,?obj);
          ????????}
          ??????}
          ????}?catch?(Exception?e)?{
          ??????e.printStackTrace();
          ????}
          ??}
          ??public?void?start()?{
          ????//1.加載配置類,初始化servletMapping
          ????init();
          ????//?Netty??NIO?Reactor模型?Boss?Worker
          ????//Boss?線程
          ????EventLoopGroup?bossGroup?=?new?NioEventLoopGroup();
          ????//Work線程
          ????EventLoopGroup?workGroup?=?new?NioEventLoopGroup();
          ????ServerBootstrap?server?=?null;
          ????try?{
          ??????//創(chuàng)建對(duì)象
          ??????server?=?new?ServerBootstrap();
          ??????//配置參數(shù)
          ??????//鏈?zhǔn)骄幊?br>??????server.group(bossGroup,?workGroup)
          ????????//主線程處理類,
          ????????.channel(NioServerSocketChannel.class)
          ????????//子線程處理類
          ????????.childHandler(new?ChannelInitializer()?{
          ??????????@Override
          ??????????protected?void?initChannel(SocketChannel?client)?throws?Exception?{
          ????????????//無鎖化串行編程
          ????????????//netty對(duì)http的封裝?對(duì)順序有要求
          ????????????//httpResponseEncoder?編碼器
          ????????????client.pipeline().addLast(new?HttpResponseEncoder());
          ????????????//httprequestDecoder?解碼器
          ????????????client.pipeline().addLast(new?HttpRequestDecoder());
          ????????????//業(yè)務(wù)處理器
          ????????????client.pipeline().addLast(new?TomcatHandler());
          ??????????}
          ????????})
          ????????//主線程?線程最大數(shù)量128
          ????????.option(ChannelOption.SO_BACKLOG,?128)
          ????????//子線程配置?保存長連接
          ????????.childOption(ChannelOption.SO_KEEPALIVE,?true);
          ??????ChannelFuture?f?=?server.bind(port).sync();
          ??????System.out.println("Tomcat 已啟動(dòng),監(jiān)聽端口是:"?+?this.port);
          ??????f.channel().closeFuture().sync();
          ????}?catch?(Exception?e)?{
          ??????e.printStackTrace();
          ????}?finally?{
          ??????bossGroup.shutdownGracefully();
          ??????workGroup.shutdownGracefully();
          ????}
          ??}
          ??public?class?TomcatHandler?extends?ChannelInboundHandlerAdapter?{
          ????@Override
          ????public?void?channelRead(ChannelHandlerContext?ctx,?Object?msg)?throws?Exception?{
          ??????if?(msg?instanceof?HttpRequest)?{
          ????????System.out.println("hello?request");
          ????????HttpRequest?req?=?(HttpRequest)?msg;
          ????????ParentRequest?request?=?new?ParentRequest(ctx,?req);
          ????????ParentResponse?response?=?new?ParentResponse(ctx,?req);
          ????????String?url?=?request.getUrl();
          ????????if?(servletMapping.containsKey(url))?{
          ??????????//7.調(diào)用實(shí)例化對(duì)象的service方法
          ??????????servletMapping.get(url).service(request,?response);
          ????????}?else?{
          ??????????response.write("404?-?Not?Found");
          ????????}
          ??????}
          ????}
          ??}
          ??public?static?void?main(String[]?args)?{
          ????//啟動(dòng)
          ????new?TomcatStart().start();
          ??}
          }
          1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798

          4.訪問

          http://localhost:8080/first


          好文章,我在看

          瀏覽 45
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青青草人人操人人摸人人干 | 欧美三级欧美视频在线 | 中文字幕亚洲无码视频 | 国产亚洲色婷婷久久99精品 | 阴茎插入阴道内的欧美视频网站 |