Java 实现简单静态资源Web服务器的示例

实现一个简单的静态资源Web服务器,可以基于Java语言编写。本文将提供一个完整的攻略,方便初学者快速上手。

1 创建项目

首先需要创建一个Java项目,可以使用Eclipse或者其他IDE。创建项目后,需要创建如下的目录结构:

src
├── main
│   └── java
│       └── com
│           └── example
│               └── webserver
│                   ├── HttpServer.java
│                   └── ResourceLoader.java
└── test
    └── java
        └── com
            └── example
                └── webserver
                    ├── HttpServerTest.java
                    └── ResourceLoaderTest.java

其中,src/main/java/com/example/webserver目录下是自己定义的代码,src/test/java/com/example/webserver目录下是测试代码。

2 实现HttpServer

com.example.webserver包下创建HttpServer类,用于启动HTTP服务器。具体实现步骤如下:

  1. 导入必要的包,如java.net.*,java.io.*等。
package com.example.webserver;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
  1. 创建HttpServer类,主要包括以下函数:
public class HttpServer {
    private int port; // 端口号
    private ServerSocket serverSocket; // 服务器套接字

    public HttpServer(int port) {
        this.port = port;
    }

    // 启动服务器
    public void start() throws Exception {
        try {
            serverSocket = new ServerSocket(port);

            while (true) {
                Socket socket = serverSocket.accept(); // 监听客户端
                handleRequest(socket);
            }
        } catch (Exception e) {
            throw new Exception("Could not start server" + e);
        }
    }

    // 处理请求
    private void handleRequest(Socket socket) throws Exception {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); OutputStream out = socket.getOutputStream()) {
            String path = in.readLine().split(" ")[1];

            byte[] contents;

            if ("/".equals(path)) {
                path = "index.html";
            }

            try {
                Path filePath = Paths.get("public", path);
                contents = Files.readAllBytes(filePath);
                out.write(generateHeader(200, contents.length, getMimeType(filePath)).getBytes());
            } catch (Exception e) {
                contents = "404 Not Found".getBytes();
                out.write(generateHeader(404, contents.length, "text/plain").getBytes());
            }

            out.write(contents);
        } catch (Exception e) {
            System.err.println("Error handling connection: " + e);
        } finally {
            socket.close(); // 关闭客户端
        }
    }

    // 生成HTTP头部
    private String generateHeader(int statusCode, int contentLength, String mimeType) {
        String CRLF = "\r\n";
        return String.format("HTTP/1.1 %d OK%s" + "Content-Length: %d%s" + "Content-Type: %s%s%s", statusCode, CRLF, contentLength, CRLF, mimeType, CRLF, CRLF);
    }

    // 获取MIME类型
    private String getMimeType(Path filePath) throws Exception {
        String type = Files.probeContentType(filePath);
        if (type == null) {
            return "application/octet-stream";
        }
        return type;
    }
}

以上代码中,主要包括以下几个函数:

  • HttpServer(int port):构造函数,初始化端口号。
  • start():启动HTTP服务器。
  • handleRequest(Socket socket):处理请求,包括解析HTTP请求头、获取请求文件路径、读取文件内容、生成HTTP响应头和发送响应等步骤。
  • generateHeader(int statusCode, int contentLength, String mimeType):生成HTTP响应头。
  • getMimeType(Path filePath):获取文件的MIME类型。

需要注意的是,这里只是一个简单的实现,对于比较复杂的HTTP请求并没有实现。

3 实现ResourceLoader

com.example.webserver包下创建ResourceLoader类,用于加载资源文件。具体实现步骤如下:

  1. 导入必要的包,如java.net.*,java.io.*等。
package com.example.webserver;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
  1. 创建ResourceLoader类,主要包括以下函数:
public class ResourceLoader {
    // 加载资源文件
    public static byte[] load(String path) throws Exception {
        Path filePath = Paths.get("public", path);
        return Files.readAllBytes(filePath);
    }
}

以上代码中,load(String path)函数用于加载指定路径下的文件,并返回文件的字节数组,如果文件不存在则抛出异常。

4 实现示例

下面给出两个示例,分别是加载图片和HTML文件。

public目录下放置一个图片文件example.jpg和一个HTML文件index.html(可以使用随便找到的图片和HTML文件),创建如下主函数:

package com.example.webserver;

public class App {
    public static void main(String[] args) throws Exception {
        HttpServer server = new HttpServer(8080);
        server.start();
    }
}

然后运行该程序即可启动HTTP服务器。在浏览器中访问http://localhost:8080/example.jpg即可查看图片,访问http://localhost:8080/即可查看HTML文件。

这里再给出一个示例,通过ResourceLoader直接加载HTML文件。修改handleRequest函数如下:

private void handleRequest(Socket socket) throws Exception {
    try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); OutputStream out = socket.getOutputStream()) {
        String path = in.readLine().split(" ")[1];

        byte[] contents;

        if ("/".equals(path)) {
            contents = ResourceLoader.load("index.html");
            out.write(generateHeader(200, contents.length, "text/html").getBytes());
        } else {
            try {
                Path filePath = Paths.get("public", path);
                contents = Files.readAllBytes(filePath);
                out.write(generateHeader(200, contents.length, getMimeType(filePath)).getBytes());
            } catch (Exception e) {
                contents = "404 Not Found".getBytes();
                out.write(generateHeader(404, contents.length, "text/plain").getBytes());
            }
        }

        out.write(contents);
    } catch (Exception e) {
        System.err.println("Error handling connection: " + e);
    } finally {
        socket.close(); // 关闭客户端
    }
}

这个示例中,如果请求的是根目录,就直接通过ResourceLoader加载index.html文件,并返回HTML内容。否则就按照原来的方式处理请求。

至此,一个简单的静态资源Web服务器就完成了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 实现简单静态资源Web服务器的示例 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • vuex的几个属性及其使用传参方式

    好的!下面是有关Vuex的属性及其使用方法的详细攻略。 Vuex属性 State – 状态属性 State是Vuex中存放数据的地方。它的作用是承载用户数据及当前应用的状态信息。在组件中通过$store.state来获取数据。 Getter – 获取属性 Getter是vuex中用于从状态层中获取数据的函数。Getter可以对State中的数据进行二次处理后…

    Vue 2023年5月28日
    00
  • vue.js实现备忘录功能的方法

    下面我来详细讲解一下“vue.js实现备忘录功能的方法”的完整攻略。 1. 确定页面结构 首先需要在页面中确定备忘录的展示位置或容器。此处推荐使用<div>标签做为备忘录的容器,所有备忘录信息都将渲染到这个容器中。 <div id="memos"></div> 2. 创建数据模型 接下来要创建备忘录的数…

    Vue 2023年5月27日
    00
  • Promise改写获取萤石云直播地址接口示例

    下面是关于“Promise改写获取萤石云直播地址接口示例”的完整攻略: 什么是Promise Promise是一种基于回调函数的异步编程解决方案,可以简化嵌套回调函数的代码,使异步代码更易读、更易维护和扩展。 要理解Promise的运作流程,需要了解Promise有三种状态:Pending(进行中)、Fulfilled(已完成)和Rejected(已失败)。…

    Vue 2023年5月28日
    00
  • iview实现动态表单和自定义验证时间段重叠

    iView是一款基于Vue.js的UI框架,可以快速搭建美观、易用的网页应用程序。在iView中实现动态表单和自定义验证时间段重叠的功能,需要深入了解iView的表单组件和验证组件。 实现动态表单 在iView中,通过<Form :model=”formData”>和<FormItem>标签可以构建表单。动态表单的实现需要以下步骤: …

    Vue 2023年5月29日
    00
  • vue解决跨域问题(推荐)

    下面是详细的Vue解决跨域问题的攻略: 前置知识要求 在学习Vue解决跨域问题之前,需要掌握以下知识: Vue基础,至少了解Vue的组件、生命周期等基础知识; 了解Axios,Axios是一款优秀的HTTP请求库,用于发送Ajax请求。 Vue跨域问题解决方案 在Vue中,解决跨域问题可以采用以下方法: 1. 设置代理服务器 在Vue的config/inde…

    Vue 2023年5月27日
    00
  • Vue入门之数量加减运算操作示例

    那我就来详细地讲一下“Vue入门之数量加减运算操作示例”的完整攻略。 一、前置知识 在学习Vue的运算操作之前,需要先掌握一些基本的前置知识: HTML 和 CSS的基础语法:Vue是一种基于HTML和CSS的框架,因此需要熟练掌握HTML和CSS的基本语法。 JavaScript 基础:Vue是通过JavaScript实现的,所以需要熟练掌握JavaScr…

    Vue 2023年5月27日
    00
  • vue实现商城上货组件简易版

    下面我将为你详细讲解“Vue实现商城上货组件简易版”的完整攻略,包含以下几个步骤: 一、设计组件结构 在Vue中设计组件有以下几个要点: 1. 组件的数据 组件必须拥有数据,这些数据可以通过props传递来自父组件的数据,也可以通过data()方法定义组件自身的数据。 2. 组件的模板 Vue使用HTML模板作为组件的呈现形式。 3. 组件的方法 Vue组件…

    Vue 2023年5月28日
    00
  • Vue中使用Sortable的示例代码

    下面是“Vue中使用Sortable的示例代码”的完整攻略: 什么是Sortable? Sortable 是一个强大的 JavaScript 库,可以使任何列表进行拖放排序。它可以把所有 HTML 元素(包括表格行)变成拖动元素。您可以使用它来启用您的用户重新排列您的网页上的 DOM 元素的功能。 Vue中使用Sortable的示例代码 第一步:安装Sort…

    Vue 2023年5月29日
    00
合作推广
合作推广
分享本页
返回顶部