自己做一个微型静态Web服务器
这一篇简单粗暴一点,先上干货,看代码注释
JDK版本:1.8
实现自定义错误页、404页。
package com.hawkon;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
public class MyServer {
public static String HOME_DIR = "d:/home"; //定义服务器默认的文件夹在哪里
public static String NOT_FOUND_FILE = "d:/home/404.html"; //定义404错误页
public static String ERR_FILE = "d:/home/err.html"; //定义500错误页
public static String DEFAULT_FILE = "/index.html"; //定义默认页面
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8009); //定义端口
while (true) { //循环是不断的接受新的请求
Socket socket = serverSocket.accept(); //当服务器运行起来没有请求的时候会在这里等待
InputStream is = socket.getInputStream(); //创建一个输入流
InputStreamReader sr = new InputStreamReader(is); //过渡代码主要是为下一行创建对象
BufferedReader br = new BufferedReader(sr); //创建BufferedReader对象,在本文中采用一行一行的读的方式,比较方便。
try {
String request = "";
request = br.readLine(); //只读取了第一行,后面报头本文暂时没用。
System.out.println("request:");
System.out.println(request); //输出一下请求的报头
String[] arr = request.split(" "); //拆分出第一行的三部分内容
do { //循环是为了把剩下的请求内容读完,否则会产生异常
request=br.readLine();
System.out.println(request); //把全部报头都输出
}while(!request.equals(""));
if (arr.length != 3 || !arr[0].equals("GET")) { //如果不是GET请求,拆分出的第一行也不是三部分内容直接返回错误页
outPutFile(ERR_FILE, socket.getOutputStream(), 500);
} else {
String path = arr[1]; //取出请求的资源路径
if(path.equals("/")) //如果请求的内容没有指定文件,则返回默认的页面
path=DEFAULT_FILE;
if (Files.exists(Paths.get(HOME_DIR + path))) { //判断文件是否存在 ,如果不存在,返回404页面
outPutFile(HOME_DIR + path, socket.getOutputStream(), 200);
} else { //如果文件不存在,返回404页面
outPutFile(NOT_FOUND_FILE, socket.getOutputStream(), 404);
}
}
} catch (Exception ex) {
ex.printStackTrace(); //输出异常信息
} finally {
br.close();
sr.close();
is.close();
}
}
}
public static void outPutFile(String fileName, OutputStream os, int status) throws IOException {
System.out.println("response:");
System.out.println(fileName);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("HTTP/1.1 " + status + " OK\r\n"); //输出状态码
stringBuilder.append("Date: " + (new Date()).toString() + "\r\n");
stringBuilder.append("Server: MyServer 0.0.1\r\n"); //代表服务器的软件名称
stringBuilder.append("X-Powered-By: Hawkon\r\n"); //这行可以换成你的英文名,看起来会有点diao
stringBuilder.append("Keep-Alive: timeout=5, max=100\r\n");
stringBuilder.append("Connection: Keep-Alive\r\n");
stringBuilder.append("Content-Type: text/html;charset=utf-8\r\n"); //字符串编码
stringBuilder.append("\r\n");//多输出一个空行,用来分割报头和报体,HTTP协议要求
FileInputStream fis = new FileInputStream(fileName);
byte[] bytes = new byte[1024];
int len;
os.write(stringBuilder.toString().getBytes("UTF-8")); //输出响应报头
while ((len = fis.read(bytes)) != -1) { //输出文件内容
os.write(bytes, 0, len);
}
os.flush();
os.close();
fis.close();
}
}
下图是请求响应的报头信息。
浏览器运行的情况