You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java Socket服务器中设置webroot?

Socket Java服务器Web根目录一次性配置方案

首次搭建基于Socket的Java服务器时,若想一次性设置webroot,避免每次解析请求目标时重复处理路径转换,可通过以下方式实现:

核心思路

  1. 在服务器初始化时传入webroot路径,将其作为全局固定的根目录
  2. 处理客户端请求时,直接拼接webroot与请求路径,同时添加安全校验防止目录遍历攻击
  3. 统一处理根路径请求(如/),默认映射到index.html

修改后的服务器线程代码

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ServerThread extends Thread {

    private final ServerSocket serverSocket;
    private final Path webRoot;

    // 构造方法新增webroot参数,初始化时固定根目录
    public ServerThread(int port, String webRootPath) throws IOException {
        this.serverSocket = new ServerSocket(port);
        // 转换为绝对路径并标准化,避免路径歧义
        this.webRoot = Paths.get(webRootPath).toAbsolutePath().normalize();
    }

    @Override
    public void run() {
        System.out.println("Server started, web root: " + webRoot);

        try {
            while (serverSocket.isBound() && !serverSocket.isClosed()) {
                Socket socket = serverSocket.accept();
                // 将webroot传递给连接处理线程
                ConnectionThread connectionThread = new ConnectionThread(socket, webRoot);
                connectionThread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

连接处理线程的路径处理逻辑

import java.io.IOException;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;

public class ConnectionThread extends Thread {

    private final Socket socket;
    private final Path webRoot;

    public ConnectionThread(Socket socket, Path webRoot) {
        this.socket = socket;
        this.webRoot = webRoot;
    }

    @Override
    public void run() {
        try (Scanner input = new Scanner(socket.getInputStream());
             var output = socket.getOutputStream()) {

            // 读取HTTP请求行,提取请求路径
            String requestLine = input.nextLine();
            String[] parts = requestLine.split(" ");
            if (parts.length < 2) {
                output.write("HTTP/1.1 400 Bad Request\r\n\r\n".getBytes());
                return;
            }
            String requestPath = parts[1];

            // 根路径请求默认映射到index.html
            if (requestPath.equals("/")) {
                requestPath = "/index.html";
            }

            // 拼接并标准化实际文件路径
            Path targetPath = webRoot.resolve(Paths.get(requestPath)).normalize();

            // 安全校验:确保目标路径在webroot范围内,防止目录遍历攻击
            if (!targetPath.startsWith(webRoot)) {
                output.write("HTTP/1.1 403 Forbidden\r\n\r\n".getBytes());
                return;
            }

            // 响应客户端请求
            if (Files.exists(targetPath) && Files.isRegularFile(targetPath)) {
                output.write("HTTP/1.1 200 OK\r\n".getBytes());
                output.write(("Content-Length: " + Files.size(targetPath) + "\r\n").getBytes());
                output.write("\r\n".getBytes());
                Files.copy(targetPath, output);
            } else {
                output.write("HTTP/1.1 404 Not Found\r\n\r\n".getBytes());
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用说明

初始化服务器时,直接传入webroot路径即可:

public static void main(String[] args) throws IOException {
    // 示例:将当前目录下的web文件夹作为根目录
    ServerThread server = new ServerThread(8080, "./web");
    server.start();
}

关键注意点

  • 路径标准化:使用toAbsolutePath().normalize()消除路径中的.、..等歧义符号
  • 安全校验:通过targetPath.startsWith(webRoot)确保请求不会访问webroot以外的文件,避免目录遍历漏洞
  • 默认页处理:统一将根路径请求映射到index.html,符合常规Web服务器行为

内容的提问来源于stack exchange,提问作者KotekBehemotek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:33:17