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日

相关文章

  • Vue3中watch的最佳用法

    下面我就为你详细地讲解一下“Vue3中watch的最佳用法”的完整攻略。 什么是Vue3的watch 首先,我们需要明确一下Vue3中的watch是什么。Vue3中的watch是一个响应式API,可以监听数据变化并触发相应的操作。在Vue2中,我们可能会使用一个对象中的watch属性来实现数据的观察,而在Vue3中,我们可以使用watch函数来实现相同的功能…

    Vue 2023年5月27日
    00
  • JS简单实现点击按钮或文字显示遮罩层的方法

    下面是JS简单实现点击按钮或文字显示遮罩层的方法的完整攻略: 1. 初步思路 实现点击按钮或文字显示遮罩层,我们需要实现以下两个步骤: 点击按钮或文字后,触发显示遮罩层的函数 显示遮罩层,覆盖整个页面或部分页面 2. 实现过程 2.1 触发函数 我们可以通过以下两种方式触发函数: 2.1.1 绑定事件 我们可以通过JS绑定事件,当用户点击按钮或文字时触发事件…

    Vue 2023年5月28日
    00
  • nodejs(officegen)+vue(axios)在客户端导出word文档的方法

    下面是详细讲解“nodejs(officegen)+vue(axios)在客户端导出word文档的方法”的完整攻略: 一、安装依赖 首先需要安装nodejs的officegen模块以及vue的axios模块。在安装完nodejs之后,可以使用以下命令进行安装: npm install –save officegen axios 二、创建服务端代码 创建一个…

    Vue 2023年5月27日
    00
  • vue-i18n的9以上版本中@被用作特殊字符处理,直接用会报错问题

    在vue-i18n的9以上版本中,@符号被用作特殊字符处理。如果在国际化文件中直接使用@符号,会导致解析错误并报错。因此,需要进行转义处理,才能正常使用。 处理方法如下: 1.将@符号转义为其HTML实体编码,即”@”。 将”@”转义为”@”可以避免在vue-i18n中使用@符号时报错。例如,以下是一个包含@符号的英文字符串: { &quot…

    Vue 2023年5月27日
    00
  • 浅谈Vue入门需掌握的知识

    浅谈Vue入门需掌握的知识 Vue是一种流行的JavaScript框架,用于构建交互式Web界面。如果想入门Vue,需要掌握以下几个知识点: HTML基础 Vue将HTML作为模板语言,所以要熟练掌握HTML的基础知识,包括HTML标签、表单元素、图像等等。但是Vue的模板语法略有不同,需要注意。 <div id="app">…

    Vue 2023年5月28日
    00
  • Vue中使用 setTimeout() setInterval()函数的问题

    关于Vue中使用setTimeout()和setInterval()函数的问题,需要考虑到以下几个方面的内容: 在Vue中如何使用setTimeout()和setInterval()函数 在Vue中使用setTimeout()和setInterval()函数需要注意哪些问题 Vue中使用setTimeout()和setInterval()会涉及到的一些示例及…

    Vue 2023年5月29日
    00
  • 详解Vuex的属性

    下面就详细讲解一下Vuex的属性: Vuex的属性 Vuex是一个专为Vue.js应用程序开发的状态管理模式,它集中管理Vue应用程序中的所有组件的状态。在Vuex中,有几个重要的属性:state、mutations、actions、getters和modules,下面将逐一进行详解。 state state是Vuex中存储响应式数据的地方,唯一的数据源。当…

    Vue 2023年5月27日
    00
  • vue 获取元素额外生成的data-v-xxx操作

    当Vue渲染一个组件的时候,会自动生成一些指令,如data-v-xxx。这些指令是Vue为了保证组件的封装性、作用域隔离、样式隔离等方面做出的设计。如果应用CSS属性的时候直接写在后代元素上,并且如果后代元素被渲染成为一个组件,这个样式将不会应用到这个后代元素上,导致样式失效。 Vue提供了一些API来获取这些额外生成的data-v-xxx操作,常见的方式有…

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