初学javaEE,对Tomcat的认识也一直是一个Web容器,今天先猜猜它是怎么工作的
一、自定义的Web容器
根据servlet学习,推测Web容器功能应该有:
- 建立SeverSocket,等待Socket连接
- 给servlet提供Request、Response对象
- 执行servlet GET、POST方法
- 向socket发送响应信息
package com.cooooode.main;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Container {
private ServerSocket server;
Container(){
System.out.println("创建Container对象");
}
Container(int port) throws IOException {
this();
this.server=new ServerSocket(port);//1建立SeverSocket
}
public void start() throws IOException {
System.out.println("启动容器");
while(true) {
Socket client = server.accept();//等待Socket连接
HttpRequest httpRequest = getHttpRequest(client);//获取Request对象
HttpResponse httpResponse = getHttpResponse(client);//获取Response对象
String method=httpRequest.getRequestMethod();
Servlet servlet=new Servlet();
//2,3 提供Request、Response对象 执行servlet GET、POST方法
if(method.toUpperCase().equals("GET"))
servlet.get(httpRequest,httpResponse);
else
servlet.post(httpRequest,httpResponse);
httpResponse.push();//4. 向socket发送响应信息
}
}
public HttpRequest getHttpRequest(Socket client) throws IOException {
return new HttpRequest(client);
}
public HttpResponse getHttpResponse(Socket client) {
return new HttpResponse(client);
}
public static void main(String[] args) throws IOException {
new Container(8000).start();
}
}
二、自定义Request
便宜行事,只写了两个方法
- 获取请求头信息
- 获取请求方法(GET/POST)
package com.cooooode.main;
import java.io.IOException;
import java.net.Socket;
public class HttpRequest {
private Socket client;
private String headinfo;
HttpRequest(){
System.out.println("创建HttpRequest对象");
}
HttpRequest(Socket client) throws IOException {
this();
this.client=client;
byte[] bytes = new byte[20480];
int len=client.getInputStream().read(bytes);
headinfo=new String(bytes,0,len);
}
// 1. 获取请求头信息
public String getHeadMessage() throws IOException {
return headinfo;
}
// 2. 获取请求方法(GET/POST)
public String getRequestMethod() throws IOException {
return headinfo.split(" ")[0];
}
}
三、自定义Response
定义了两个主要方法
- 将servlet传递的响应内容添加到响应输出中
- 推送响应信息
package com.cooooode.main;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;
public class HttpResponse {
private Socket client;
private StringBuffer response=new StringBuffer();
private StringBuffer headinfo=new StringBuffer();
public static final String BLANK=" ";
public static final String CRLF="\r\n";
private BufferedWriter bw;
private int len;
private String charset="utf-8";
private String contextType="text/html";
private int code=200;
HttpResponse(){
System.out.println("创建HttpResponse对象");
}
HttpResponse(Socket client){
this();
this.client=client;
}
public void setCode(int code){
this.code=code;
}
public void setCharset(String charset){
this.charset=charset;
}
public void setContextType(String contextType){
this.contextType=contextType;
}
// 1. 将servlet传递的响应内容添加到响应输出中
public StringBuffer println(String context){
len+=(context+CRLF).getBytes().length;
return response.append(context).append(CRLF);
}
// 1. 将servlet传递的响应内容添加到响应输出中
public StringBuffer print(String context){
len+=context.getBytes().length;
return response.append(context);
}
// 2. 推送响应信息
public void push() throws IOException {
System.out.println(client);
bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
headinfo.append("HTTP/1.1").append(BLANK).append(code).append(BLANK);
switch (code) {
case 200:
headinfo.append("OK");
break;
case 404:
headinfo.append("NOT FOUND");
break;
case 505:
headinfo.append("SERVER ERROR");
break;
}
headinfo.append(CRLF);
headinfo.append("Content-Type:" + contextType).append(CRLF);
headinfo.append("Content-Length:" + len).append(CRLF);
headinfo.append("Date:" + new Date()).append(CRLF);
headinfo.append(CRLF);
headinfo.append(response);
bw.write(headinfo.toString());
bw.flush();
bw.close();
}
}
四、自定义servlet
package com.cooooode.main;
import java.io.IOException;
public class Servlet{
public void get(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException {
System.out.println(httpRequest.getHeadMessage());
httpResponse.println("<h1>Cooooode HttpServer</h1>");
httpResponse.println("<b>2019 03 24</b>");
}
public void post(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException {
this.get(httpRequest,httpResponse);
}
}
执行容器main方法,一个简陋的javaWeb应用就启动了