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

通过Servlet访问指定前缀静态资源,解决JS/CSS/字体等文件404及解析异常问题

问题根因

你的代码存在两个核心错误导致返回内容无法正常解析:

  • 流读取逻辑完全错误:你调用的无参inputStream.read()方法每次仅返回单个字节的数值(0~255),并没有把文件内容写入你定义的buffer数组,最终输出的都是数组初始的0值,所以返回内容完全不可读。
  • 缺失必要响应头:没有给返回内容配置正确的MIME类型、内容长度等信息,浏览器无法识别你返回的内容格式,自然无法正常渲染。

解决方案

第一步:修正Servlet代码

以下是完整可用的实现,适配文本、二进制类静态资源的返回:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 解析请求路径,匹配实际静态资源位置
    String requestPath = req.getPathInfo();
    // 配置默认访问页,比如访问/myPage/时直接返回首页
    if (requestPath == null || requestPath.isBlank()) {
        requestPath = "/index.html";
    }
    // 这里假设静态资源存放在webapp下的my-static目录,可根据你的实际存放位置调整路径拼接逻辑
    String realPath = getServletContext().getRealPath("/my-static" + requestPath);
    File resourceFile = new File(realPath);

    // 2. 资源合法性校验
    if (!resourceFile.exists() || resourceFile.isDirectory() || !resourceFile.canRead()) {
        resp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    // 可选:防止路径遍历漏洞,避免恶意用户读取服务器敏感文件
    if (!realPath.startsWith(getServletContext().getRealPath("/my-static"))) {
        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
    }

    // 3. 设置正确的响应头
    // 自动匹配文件对应的MIME类型
    String mimeType = getServletContext().getMimeType(resourceFile.getName());
    resp.setContentType(mimeType != null ? mimeType : "application/octet-stream");
    // 设置内容长度,避免浏览器端出现截断或者粘包问题
    resp.setContentLengthLong(resourceFile.length());
    // 可选:配置静态资源缓存,降低服务器压力,示例为缓存7天
    resp.setHeader("Cache-Control", "public, max-age=604800");

    // 4. 正确的流拷贝逻辑
    try (FileInputStream in = new FileInputStream(resourceFile);
         OutputStream out = resp.getOutputStream()) {
        byte[] buffer = new byte[1024];
        int bytesRead;
        // read(buffer)会将内容读入buffer数组,返回本次读取到的字节长度
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
        out.flush();
    } catch (Exception e) {
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        e.printStackTrace();
    }
}

第二步:调整静态资源存放位置

把你需要返回的html、js、css、字体等所有静态资源都放到你代码里配置的对应目录下(上面示例是webapp下的my-static目录),访问/myPage/xxx.js时就会自动读取对应目录下的xxx.js返回。

注意事项

如果你的静态资源是放在jar包内部的类路径下,需要替换FileInputStream为this.getClass().getResourceAsStream("类路径下的资源位置")读取,避免文件找不到的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:24:03