基于httpserver类实现的简易http服务器

发布于:2022-12-10 ⋅ 阅读:(759) ⋅ 点赞:(0)

基于 httpserver 类实现的简易 http 服务器

一、前言

利用 Java 的 com.sun.net 包下的 http 类,实现的简易 http 服务器。全部代码已上传至 GitHub,链接在文末。

主要功能为:
1、只处理 GET 方式和 POST 方式的请求,其他的返回 501 Not Implemented
2、GET:1)如果请求路径为一个存在的 HTML 文件,返回 200 OK 和该 HTML 文件的全部内容。(对子目录下的文件同样也要能返回);2)如果请求路径为一个文件夹,且该文件夹内有 index.html 文件,返回 200 OK 和 index.html 文件的全部内容;3)如果请求的文件不存在,或者请求的路径下无 index.html 文件,返回 404 Not Found
3、POST:1)构造一个 HTTP 请求,包含两个键值对:Name:姓名 和 ID:学号,提交给 /Post_show。服务器收到请求后返回 200 OK 且输出以 POST 方式发送的 Name 和 ID;2)其他情况如请求路径不为 Post_show 或键的名称不为 Name 和 ID,返回 404 Not Found
4、使用多线程处理,具体为线程池方式实现
5、支持长选项参数:1)–ip 设置服务器端的 IP 地址;2)–port 设置服务器端监听的端口号;3)–number-thread 线程数目。

二、功能展示

这里只贴 windows 环境下测试的结果了。

1、Idea 上运行

Run->Edit Configurations 设置参数

在这里插入图片描述

也可以不设置,默认值就是上图中的数

点击运行

在这里插入图片描述

这个“当前路径”设置的是:

private static final String WEB_ROOT = System.getProperty("user.dir")
            + File.separator + "webroot";

后文有解释。在 webroot 文件夹内存放了一些子文件夹和 HTML 文件等。

1.1、浏览器输入请求

浏览器中输入

127.0.0.1:8888/sub/02.jpg

便可请求到图片 D:\Study\Java\httpserver\webroot\sub\02.jpg

在这里插入图片描述

在这里插入图片描述

1.2、curl 命令请求

curl 现在是 win10 自带的了吧,不用安装直接能用。不过需要注意的是 windows 和 Linux 下的 curl 使用存在区别。

在这里插入图片描述

1.3、Postman 请求

Postman 是个很棒的工具!

在这里插入图片描述

2、命令行上 Java -jar 运行

参考 IDEA 打包 jar 包详尽流程打成 jar 包,放在 E 盘

在这里插入图片描述

此时将 webroot 和 httpserver.jar 放在同一目录下

在这里插入图片描述

请求方式和 1 中介绍过的类似

在这里插入图片描述

比较简单,看函数名称就知道在做啥。测试如下:

在这里插入图片描述

预览:

在这里插入图片描述

3.3、满足条件

private static void HandlePostRequest(HttpExchange httpExchange, String Name, String ID) throws Exception {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set("Content-Type", "text/html; charset=utf-8");
        OutputStream responseBody = httpExchange.getResponseBody();
        OutputStreamWriter writer = new OutputStreamWriter(responseBody, "UTF-8");
        String response = "<html><title>" + httpExchange.getRequestMethod() + "</title><body bgcolor=ffffff>" + CRLF +
                "Your Name: " + Name + CRLF +
                "ID: " + ID + CRLF +
                "<hr><em>HTTP Web Server</em>" + CRLF +
                "</body></html>";
        httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.getBytes("UTF-8").length);
        writer.write(response);
        writer.close();
        responseBody.close();
    }

和 3.2 差不多,就是返回内容有所更改

在这里插入图片描述

预览:

在这里插入图片描述

4、处理 Get 请求

4.1、判断何种方式请求

static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange httpExchange) throws IOException {
            String requestMethord = httpExchange.getRequestMethod();
            try {
                if (is404NotFound(httpExchange)) {
                    System.out.println(httpExchange.getRequestURI() + " does not exist!");
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (requestMethord.equalsIgnoreCase("GET")) {
                HandleGetRequest(httpExchange);
            } else if (requestMethord.equalsIgnoreCase("POST")) {
                //
            } else {
                Headers responseHeaders = httpExchange.getResponseHeaders();
                responseHeaders.set("Content-Type", "text/html;charset=utf-8");
                OutputStream responseBody = httpExchange.getResponseBody();
                OutputStreamWriter writer = new OutputStreamWriter(responseBody, "UTF-8");
                String response = "<html><title>501 Not Implemented</title><body bgcolor=ffffff>" + CRLF +
                        "Not Implemented" + CRLF +
                        "<p>Does not implement this methord: " + requestMethord + CRLF +
                        "<hr><em>HTTP Web Server</em>" + CRLF +
                        "</body></html>";
                httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_NOT_IMPLEMENTED, response.getBytes("UTF-8").length);
                writer.write(response);
                writer.close();
                responseBody.close();
            }
        }
    }

利用 getRequestMethod()函数得到是何种方式的请求。判断访问路径是否存在见 4.2。

如果访问路径存在,并且访问方式为 GET,则调用函数 HandleGetRequest,见 4.3;若访问方式为 POST,也可以调用相应的函数,但我在之前已经实现过了,这里就不填了;若访问方式为除了 GETPOST 以外的方式,则返回 501 Not IMPLEMENTED:

在这里插入图片描述

预览:

在这里插入图片描述

4.2、判断访问路径是否存在

private static boolean is404NotFound(HttpExchange httpExchange) throws Exception {
        String requestURI = String.valueOf(httpExchange.getRequestURI());
        File file = new File(WEB_ROOT, requestURI);
        if (file.exists()) return false;
        else {
            System.out.println(file.getPath() + "does not exist!" + CRLF);
            NotFoundResponse(httpExchange);
            return true;
        }
    }

前文提到,WEB_ROOT 为获取的当前程序正在运行的路径,加上 requestURI 得到请求的文件,利用 exists()函数判断是否存在。若存在则返回 false,表示不是 404;若不存在则调用 3.2 中提过的函数 NotFoundResponse()。

将文件以字节流的形式发送出去。这里的缓冲区大小为 10240。

例:

在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到