【HTTP协议其实很简单】03.自己写一个微型静态Web服务器

自己做一个微型静态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();
    }
}


下图是请求响应的报头信息。

image

浏览器运行的情况
image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章