手写一个tomcat服务器——version1.0
首先建一个Java工程,工程目录如下:
我们直接用现成的浏览器发送请求:localhost:8080/demo01.html
实现步骤分析
前期准备
1.我们要定义一个变量WEB_ROOT,存放服务端WebContent目录的绝对路径。
public static String WEB_ROOT=System.getProperty(“user.dir”)+"\"+“WebContent”;
2.定义静态变量url,用于存放客户端请求的静态页面名称。
private static String url="";
准备完成,操作步骤简述:
- 首先我们要创建一个ServerSocket,监听本机器的80端口,等待客户端的请求。
- 得到客户端对应的socket获取输入流和输出流对象
- 根据客户端输入流获取Http协议的请求信息,截取客户端要访问的资源名称,将这个资源赋值给一个提前定义好的静态变量url,用于存储本次请求静态页面名称。
- 使用客户端输出流发送静态资源:定义文件输入流,请求静态资源判断是否存在。存在,向客户端输出Http协议响应头/响应行,并读取静态资源内容输出到客户端;若不存在,返回404资源找不到信息。
package com.thj.tomcat1;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
public class TestServer {
//定义一个变量,存放服务端WebContent目录的绝对路径
public static String WEB_ROOT=System.getProperty("user.dir")+"\\"+"WebContent";
//定义静态变量,用于存放本次请求的静态页面名称
private static String url="";
public static void main(String[] args) throws Exception {
// System.out.println(WEB_ROOT);
//创建ServerSocket,监听本机器的80端口,等待来自客户端的请求
ServerSocket serverSocket=null;
Socket socket =null;
InputStream is =null;
OutputStream os =null;
try {
serverSocket= new ServerSocket(8080);
while (true) {
//获取到客户端对应的socket
socket = serverSocket.accept();
//获取输入流对象
is = socket.getInputStream();
//获取输出流对象
os = socket.getOutputStream();
//获取HTTP协议的请求部分,截取客户端要访问的资源名称,将这个资源赋值给url
parse(is);
//发送静态资源
sendStaticResource(os);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null!=is){
is.close();
is=null;
}
if (null!=os){
os.close();
os=null;
}
if (null!=socket){
socket.close();
socket=null;
}
}
}
//发送静态资源
private static void sendStaticResource(OutputStream os) throws Exception {
//定义一个字节数组,用于存放本次请求的静态资源demo01.html的内容
byte[] bytes=new byte[2048];
//定义一个文件输入流,用户获取静态资源demo01.html的内容
FileInputStream fis=null;
try {
File file= new File(WEB_ROOT,url);
//如果请求的静态资源存在
if (file.exists()){
//向客户端输出HTTP协议的响应头/响应行
os.write("HTTP/1.1 200 OK\n".getBytes());
os.write("Server:apache-Coyote/1.1\n".getBytes());
os.write("Content-Type:text/html;charset=utf-8\n".getBytes());
os.write("\n".getBytes());
fis=new FileInputStream(file);
int ch=fis.read(bytes);
while(ch!=-1){
//将读取到数组中的内容通过输出流发送到客户端
os.write(bytes,0,ch);
ch=fis.read(bytes);
}
}else {
os.write("HTTP/1.1 404 not found\n".getBytes());
os.write("Server:apache-Coyote/1.1\n".getBytes());
os.write("Content-Type:text/html;charset=utf-8\n".getBytes());
os.write("\n".getBytes());
String errorMessage="file not found";
os.write(errorMessage.getBytes());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis!=null){
fis.close();
fis=null;
}
}
}
//获取HTTP协议的请求部分,截取客户端要访问的资源名称,将这个资源赋值给url
private static void parse(InputStream is) throws IOException {
StringBuffer content= new StringBuffer(2048);
byte[] buffer= new byte[2048];
int i=-1;
i=is.read(buffer);
for (int j=0;j<i;j++){
content.append((char)buffer[j]);
}
//获取客户端的请求数据
System.out.println(content);
//截取客户端要求的资源路径demo01.html,赋值给url
parseUrl(content.toString());
}
//截取客户端要求的资源路径demo01.html,赋值给url
private static void parseUrl(String content) {
int index1,index2;
index1 = content.indexOf(" ");
if (index1!=-1){
index2=content.indexOf(" ",index1+1);
if (index2>index1){
url= content.substring(index1+2,index2);
}
}
System.out.println(url);
}
}