日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

netty 簡介

Netty一個基于NIO的客戶、服務器端的編程框架

1.環境準備

maven依賴

  <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.42.Final</version>
  </dependency>
12345

RequestMethodEnum 請求方式

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 方法決定調用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
    //狀態碼為200
    StringBuilder sb = new StringBuilder();
    sb.Append("HTTP/1.1 200 OK n")
      .append("Content-Type: text/html;n")
      .append("rn")
      .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.基于傳統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<String, ParentServlet> servletMapping = new HashMap<String, ParentServlet>();
  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");
          //單實例  多線程
          ParentServlet obj = (ParentServlet) Class.forName(className).newInstance();
          servletMapping.put(url, obj);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  public void start() {
    //1.加載配置類,初始化servletMapping
    init();
    try {
      //2.綁定端口啟動
      server = new ServerSocket(this.port);
      System.out.println("Tomcat 已啟動,監聽端口是:" + this.port);
      //3.等待用戶請求,用一個死循環
      while (true) {
        Socket client = server.accept();
        //4.http 請求
        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.從協議內容中獲取url 映射相應的servlet
      String url = request.getUrl();
      if (servletMapping.containsKey(url)) {
        //7.調用實例化對象的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) {
    //啟動
    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<String, List<String>> getParameters() {
    QueryStringDecoder decoder = new QueryStringDecoder(req.uri());
    return decoder.parameters();
  }  public String getParameter(String name) {
    Map<String, List<String>> params = getParameters();
    List<String> 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;
      }      // 設置 http協議及請求頭信息      FullHttpResponse response = new DefaultFullHttpResponse(        // 設置http版本為1.1
        HttpVersion.HTTP_1_1,        // 設置響應狀態碼        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<String, ParentServlet> servletMapping = new HashMap<String, ParentServlet>();
  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");
          //單實例  多線程
          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 {
      //創建對象
      server = new ServerBootstrap();
      //配置參數
      //鏈式編程
      server.group(bossGroup, workGroup)
        //主線程處理類,
        .channel(NIOServerSocketChannel.class)
        //子線程處理類
        .childHandler(new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(SocketChannel client) throws Exception {
            //無鎖化串行編程
            //netty對http的封裝 對順序有要求
            //httpResponseEncoder 編碼器
            client.pipeline().addLast(new HttpResponseEncoder());
            //httprequestDecoder 解碼器
            client.pipeline().addLast(new HttpRequestDecoder());
            //業務處理器
            client.pipeline().addLast(new TomcatHandler());
          }
        })
        //主線程 線程最大數量128
        .option(ChannelOption.SO_BACKLOG, 128)
        //子線程配置 保存長連接
        .childOption(ChannelOption.SO_KEEPALIVE, true);
      ChannelFuture f = server.bind(port).sync();
      System.out.println("Tomcat 已啟動,監聽端口是:" + 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.調用實例化對象的service方法
          servletMapping.get(url).service(request, response);
        } else {
          response.write("404 - Not Found");
        }
      }
    }
  }
  public static void main(String[] args) {
    //啟動
    new TomcatStart().start();
  }
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798

4.訪問

http://localhost:8080/first

基于netty手寫Tomcat

分享到:
標簽:netty
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定