大飞带你深入理解Tomcat(六)
作者:叩丁狼教育王一飞,高级讲师。转载请注明出处。接上篇,代码已经能处理简单的请求,但走读一下代码,会发现这些代码非常粗糙,可改动的地方非常多,本篇先对HttpServlet进行优化
上上篇中HttpServer类担当2个责任,
1:负责接收客户端发起的请求
2:解析并响应请求。
按照单一类设计原则应该给予拆分,参考tomcat源码,HttpServer类可以分为HttpConnector类和HttpProcessor类,前者仅负责接收各类请求,后者解析并响应请求。同时添加一个启动类Boostrap
新增类:HttpConnector
/**
* 负责监听端口,接收请求信息,原先HttpServer类拆分而成
*/
public class HttpConnector implements Runnable {// 停止记号
private boolean stopped;
// 处理
private String scheme = "http";
public String getScheme() {
return scheme;
}public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8080, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}while (!stopped) {
Socket socket = null;
try {socket = serverSocket.accept();
} catch (Exception e) {
continue;
}
//处理请求
HttpProcessor processor = new HttpProcessor(this);
processor.process(socket);
}
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
}
说明:类实现了runable接口, 其目的非常简单,后续对项目升级时使用, 比如并发请求时,使用线程的方式处理。
新增类:HttpProcessor
/**
* 负责解析请求信息,调用StaticResouceProcessor跟ServletProcessor处理响应 ,原先HttpServer类拆分而成
*/public class HttpProcessor {private HttpConnector connector;
private HttpRequest request;
private HttpResponse response;
private HttpRequestLine requestLine = new HttpRequestLine();
public HttpProcessor(HttpConnector connector) {
this.connector = connector;
}// 响应请求
public void process(Socket socket) {SocketInputStream input = null;
OutputStream output = null;
try {
input = new SocketInputStream(socket.getInputStream(), 2048);
output = socket.getOutputStream();
request = new HttpRequest(input);
response = new HttpResponse(output);
response.setRequest(request);
response.setHeader("Server", "Pyrmont Servlet Container");
parseRequest(input, output);
parseHeaders(input);
// 响应请求socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void parseRequest(SocketInputStream input)throws IOException {
//读取请求数据,封装成reauestLine对象
input.readRequestLine(requestLine);
String method =
new String(requestLine.method, 0, requestLine.methodEnd);
String protocol = new String(requestLine.protocol, 0, requestLine.protocolEnd);
if (method.length() < 1 || requestLine.uriEnd < 1) {
throw new RuntimeException("解析请求出错");
}
request.setMethod(method);
request.setProtocol(protocol);
//对uri进行拆分,分uri + 查询参数
String uri = null;
int question = requestLine.indexOf("?");
if (question >= 0) {
request.setQueryString(new String(requestLine.uri, question + 1,
requestLine.uriEnd - question - 1));
uri = new String(requestLine.uri, 0, question);
}
else {
request.setQueryString(null);
uri = new String(requestLine.uri, 0, requestLine.uriEnd);
}request.setRequestURI(uri);
System.out.println("method:" + request.getMethod());
System.out.println("protocol:" + request.getProtocol());
System.out.println("uri:" + request.getRequestURI());
System.out.println("queryString:" + request.getQueryString());
}/**
* 解析请求头信息
*
* @param input
*/
private void parseHeaders(SocketInputStream input) throws IOException {
while (true) {
HttpHeader header = new HttpHeader();
input.readHeader(header);
if (header.nameEnd == 0) {
if (header.valueEnd == 0) {
return;
} else {
throw new RuntimeException("解析请求头报错");
}
}String name = new String(header.name, 0, header.nameEnd);
String value = https://www.it610.com/article/new String(header.value, 0, header.valueEnd);
request.addHeader(name, value);
if (name.equals("content-length")) {
int n = -1;
try {
n = Integer.parseInt(value);
} catch (Exception e) {
throw new RuntimeException("解析请求头报错");
}
request.setContentLength(n);
} else if (name.equals("content-type")) {
request.setContentType(value);
}
}
}
}
【大飞带你深入理解Tomcat(六)】新增类:Boostrap
用于启动tomcat
public final class Bootstrap {
public static void main(String[] args) {
// 服务器启动
HttpConnector connector = new HttpConnector();
connector.start();
}
}
文章图片
WechatIMG9.jpeg
推荐阅读
- 深入理解Go之generate
- 【1057快报】深入机关,走下田间,交通普法,共创文明
- 不废话,代码实践带你掌握|不废话,代码实践带你掌握 强缓存、协商缓存!
- 生发知识,带你深入了解
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- 深入浅出谈一下有关分布式消息技术(Kafka)
- 带你了解类型系统以及flow和typescript的基本使用
- 带你来看花
- 5|5 个 PPT 常用快捷键带你从此走向高效
- mysql|一文深入理解mysql