基于netty手写Tomcat

netty 简介Netty一个基于NIO的客户、服务器端的编程框架
1.环境准备maven依赖
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.42.Final</version></dependency>12345RequestMethodEnum 请求方式
public enum RequestMethodEnum {GET("GET"),POST("POST");public String code;RequestMethodEnum(String code) {this.code=code;}}12345678ParentServlet 父类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 {@Overrideprotected void doPost(ParentRequest request, ParentResponse response) throws Exception {response.write("This is the first");}@Overrideprotected void doGet(ParentRequest request, ParentResponse response) throws Exception {this.doPost(request,response);}}1234567891011
  1. SecondServlet
public class SecondServlet extends ParentServlet {@Overrideprotected void doPost(ParentRequest request, ParentResponse response) throws Exception {response.write("this is the second");}@Overrideprotected void doGet(ParentRequest request, ParentResponse response) throws Exception {this.doPost(request,response);}}1234567891011
  1. ParentRequest
【基于netty手写Tomcat】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//状态码为200StringBuilder 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=/firstservlet.first.className=com.aiden.servlet.FirstServletservlet.second.url=/secondservlet.second.className=com.aiden.servlet.SecondServlet12342.基于传统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.加载配置类 , 初始化servletMappinginit();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 映射相应的servletString 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


推荐阅读