简单处理

// 客户端和服务器的通信,说到底就是两个数据的传输,
// 客户端发送inputStream给服务器,服务器回复
// outputStream给客户端。
public class TomcatServerV1 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {//一直监听,直到受到停止的命令
Socket socket = null;
try {
socket = serverSocket.accept();//如果没有请求,会一直hold在这里等待,有客户端请求的时候才会继续往下执行
// log
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取输入流(请求)
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = bufferedReader.readLine()) != null && !line.equals("")) {//得到请求的内容,注意这里作两个判断非空和""都要,只判断null会有问题
stringBuilder.append(line).append("<br>");
}
String result = stringBuilder.toString();
System.out.println(result);
// echo
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);//这里第二个参数表示自动刷新缓存
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type:text/html;charset=utf-8");
printWriter.println(); printWriter.println("<h5>你刚才发送的请求数据是:<br>");
printWriter.write(result);//将日志输出到浏览器
printWriter.println("</h5>");
// release
printWriter.close();
bufferedReader.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

每个请求一个线程

class RequestHandler implements Runnable{
private Socket socket; public RequestHandler(Socket socket) {
this.socket = socket;
} @Override
public void run() {
// log
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取输入流(请求)
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = bufferedReader.readLine()) != null && !line.equals("")) {
stringBuilder.append(line).append("<br>");
}
String result = stringBuilder.toString();
System.out.println(result);
// echo
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);//这里第二个参数表示自动刷新缓存
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type:text/html;charset=utf-8");
printWriter.println(); printWriter.println("<h5>你刚才发送的请求数据是:<br>");
printWriter.write(result);//将日志输出到浏览器
printWriter.println("</h5>");
// release
printWriter.close();
bufferedReader.close();
socket.close();
}catch (Exception e) {
e.printStackTrace();
}
}
} public class TomcatServerV2 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {//一直监听,直到受到停止的命令
Socket socket = null;
socket = serverSocket.accept();//如果没有请求,会一直hold在这里等待,有客户端请求的时候才会继续往下执行
RequestHandler requestHandler = new RequestHandler(socket);
new Thread(requestHandler).start();
}
}
}

模拟tomcat

正如前面的博客:Servlet笔记中记录:

首先建一个MyServlet接口,然后创建一个抽象类MyHttpServlet继承接口,最后建一个UserServlet实现具体的doGet,doPost等方法。

pom依赖添加servletdom4j。DOM4J是dom4j.org出品的一个开源XML解析包。

项目目录:

原理图:

Request.java

package cn.orzlinux.Bean.mytomcat.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; public class Request {
// 如/usr
private String uri;
// 请求方法
private String method;
public Request(InputStream inputStream) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader((inputStream)));
//取HTTP请求响应的第一行,GET /user HTTP/1.1,按空格隔开
String[] data = reader.readLine().split(" ");
this.uri = data[1];
this.method = data[0];
} catch (IOException e) {
e.printStackTrace();
}
} public String getUri() {
return uri;
} public void setUri(String uri) {
this.uri = uri;
} public String getMethod() {
return method;
} public void setMethod(String method) {
this.method = method;
}
}

response

package cn.orzlinux.Bean.mytomcat.http;

import java.io.OutputStream;

public class Response {
public OutputStream outputStream; public static final String responsebody="HTTP/1.1 200+\r\n"+"Content-Type:text/html+\r\n"
+"\r\n";
public Response(OutputStream outputStream){
this.outputStream=outputStream;
}
}

MyServlet

package cn.orzlinux.Bean.mytomcat.servlet;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response; public interface MyServlet {
void init() throws Exception;
void service(Request request, Response response) throws Exception;
void destroy();
}

MyHttpServlet

package cn.orzlinux.Bean.mytomcat.servlet;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response; public abstract class MyHttpServlet implements MyServlet {
public void init() throws Exception { } public void service(Request request, Response response) throws Exception {
if("get".equalsIgnoreCase(request.getMethod())) {
this.doGet(request,response);
} else {
this.doPost(request,response);
}
} public abstract void doGet(Request request,Response response); public abstract void doPost(Request request,Response response); public void destroy() { }
}

userServlet

package cn.orzlinux.Bean.mytomcat.servlet;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response; import java.io.IOException;
import java.io.OutputStream; public class UserServlet extends MyHttpServlet {
public void doGet(Request request, Response response) {
System.out.println("doget");
this.doPost(request,response);
} public void doPost(Request request, Response response){
OutputStream outputStream = response.outputStream;
String result = Response.responsebody+"user handle successful";
try {
outputStream.write(result.getBytes());
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
} }
}

RequestHandler

package cn.orzlinux.Bean.mytomcat.socket;

import cn.orzlinux.Bean.mytomcat.http.Request;
import cn.orzlinux.Bean.mytomcat.http.Response;
import cn.orzlinux.Bean.mytomcat.servlet.MyHttpServlet; import java.io.*;
import java.net.Socket; public class RequestHandler implements Runnable{
private Socket socket; public RequestHandler(Socket socket) {
this.socket = socket;
} public void run() {
// log
try {
Request request = new Request(socket.getInputStream());
Response response = new Response(socket.getOutputStream());
String uri = request.getUri();
System.out.println(uri); String servletName = TomcatServerV3.urlmapping.get(uri);
MyHttpServlet servlet = TomcatServerV3.servletMapping.get(servletName); if(servlet!=null) {
servlet.service(request,response);
}else{
String resp=Response.responsebody+"can not find servlet";
OutputStream outputStream=socket.getOutputStream();
System.out.println(resp);
outputStream.write(resp.getBytes());
outputStream.flush();
outputStream.close();
}
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}

TomcatServerV3

package cn.orzlinux.Bean.mytomcat.socket;

import cn.orzlinux.Bean.mytomcat.servlet.MyHttpServlet;
import cn.orzlinux.Bean.mytomcat.socket.RequestHandler;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List; public class TomcatServerV3 {
public static final int port = 8080;
// 定义mytomcat.xml中的两个映射
public static final HashMap<string, myhttpservlet=""> servletMapping = new HashMap<string, myhttpservlet="">(); public static final HashMap<string,string> urlmapping=new HashMap<string, string="">(); public static void main(String[] args) throws IOException {
TomcatServerV3 tomcatServerV3 = new TomcatServerV3();
tomcatServerV3.init();
tomcatServerV3.run(); } // 初始化,加载xml里面的servlet信息
private void init() {
try {
String path = TomcatServerV3.class.getResource("/").getPath();
SAXReader reader = new SAXReader();
Document document = reader.read(new File(path+"mytomcat.xml")); Element rootelement = document.getRootElement();
List<element> elements = rootelement.elements();
for(Element element:elements) {
if ("servlet".equalsIgnoreCase(element.getName())){
Element servletname=element.element("servlet-name");
Element servletclass=element.element("servlet-class");
System.out.println(servletname.getText()+"==>"+servletclass.getText());
//需要注意的是servletMapping映射的第二个参数,要通过反射的方式进行实例化
servletMapping.put(servletname.getText(),
(MyHttpServlet) Class.forName(servletclass.getText().trim()).newInstance());
}else if ("servlet-mapping".equalsIgnoreCase(element.getName())){
Element servletname=element.element("servlet-name");
Element urlpattern=element.element("url-pattern");
System.out.println(servletname.getText()+"==>"+urlpattern.getText());
urlmapping.put(urlpattern.getText(),servletname.getText());
}
} }catch (Exception e) {
e.printStackTrace();
}
} private void run() {
ServerSocket serverSocket= null;
try {
serverSocket = new ServerSocket(port);
System.out.println("====服务启动====");
while(!serverSocket.isClosed()){
Socket socket=serverSocket.accept();
RequestHandler requestHandler=new RequestHandler(socket);
new Thread(requestHandler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

输出

userServlet==>cn.orzlinux.Bean.mytomcat.servlet.UserServlet
userServlet==>/user
====服务启动====
/
HTTP/1.1 200+
Content-Type:text/html+ can not find servlet
/user
doget

最后再回顾一下原理图:

参考

java基于Socket实现的一个简单的HTTP服务器

从零开始手写Tomcat,一文彻底搞懂Tomcat运行流程(附源码)

本文同步发布于orzlinux.cn

最新文章

  1. MyEclipse中屏蔽js检验
  2. C++ note
  3. jquery ajax json简单的分页,模拟数据,没有封装,只显示原理
  4. MyEclipse开发Web项目发布到Tomcat下的Root目录
  5. Java程序员25个必备的Eclipse插件
  6. Chapter 1 Securing Your Server and Network(6):为SQL Server访问配置防火墙
  7. C# 语言规范_版本5.0 (第6章 转换)
  8. Java语法基础总结
  9. (21)IO流之对象的序列化和反序列化流ObjectOutputStream和ObjectInputStream
  10. JavaScript中错误正确处理方式,你用对了吗?
  11. visualSVN 版本控制
  12. Redis与数据库同步问题
  13. python os 模块
  14. Weblogic 12c 集群环境搭建
  15. 如何看MySql执行计划explain(或desc)
  16. c/c++ 继承与多态 文本查询的小例子(非智能指针版本)
  17. CorelDRAW中如何分布对象
  18. .Net应该学什么怎么学(一)
  19. Java中 Auto-boxing/unboxing
  20. IntelliJ IDEA 详细图解最常用的配置 ,适合新人,解决eclipse转idea的烦恼

热门文章

  1. WPF---依赖属性(二)
  2. Linkerd 2.10(Step by Step)—3. 自动轮换控制平面 TLS &amp;Webhook TLS 凭证
  3. 五分钟搞定Docker安装ElasticSearch
  4. 源码解析.Net中DependencyInjection的实现
  5. python tif转jpg
  6. NOIP模拟13「工业题&#183;卡常题&#183;玄学题」
  7. 基本ServletWEB项目
  8. MongoDB(6)- BSON 数据类型
  9. vs code使用git---http方式
  10. 任由文字肆意流淌,更自由的开源 Markdown 编辑器