SpringBoot 静态资源访问(图片/JS/CSS)配置详解

在 SpringBoot 项目开发中,静态资源访问 是前端页面、图片上传、富文本、后台管理系统必备的功能。

很多同学经常遇到:图片上传成功但访问 404、JS/CSS 加载失败、自定义目录不生效、线上环境无法访问等问题。

今天就来讲讲 SpringBoot 静态资源的默认规则、自定义配置、本地映射、外部路径、权限放行、打包部署


一、什么是静态资源?

  • • 图片:jpg、png、gif、webp

  • • 样式:css、less、scss

  • • 脚本:js、ts

  • • 静态页面:html、ico、font

  • • 上传文件:Excel、PDF、视频

SpringBoot 对这些资源提供自动映射 ,也支持高度自定义


二、SpringBoot 默认静态资源规则(自动生效)

默认 5 个静态资源路径(优先级从高到低):

    1. META-INF/resources
    1. resources/
    1. static/(最常用)
    1. public/
    1. webapp/

默认访问规则:

直接访问资源名即可,不需要加目录前缀。

示例:

go 复制代码
src/main/resources/static/images/logo.png

访问地址:

go 复制代码
http://localhost:8080/images/logo.png

三、最常用场景:自定义静态资源映射

实际项目中,我们会把用户上传的图片/文件 存放在服务器外部路径,避免项目重新打包文件丢失。

这时候必须用:SpringMVC 资源映射

1. 编写配置类

go 复制代码
package com.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 静态资源配置
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 静态资源映射
     * 访问路径 /uploads/xxx.jpg  →  映射到本地 D:/uploads/xxx.jpg
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 1. 访问 URL 规则
        registry.addResourceHandler("/uploads/**")
                // 2. 本地真实路径(末尾必须加 /)
                .addResourceLocations("file:D:/uploads/");

        // 2. 也可以配置相对路径
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }
}

2. 访问示例

本地文件:

go 复制代码
D:/uploads/avatar.jpg

访问地址:

go 复制代码
http://localhost:8080/uploads/avatar.jpg

四、application.yml 配置静态资源

如果你不想写配置类,可以直接在 yml 中配置:

go 复制代码
spring:
  web:
    resources:
      # 自定义静态资源路径
      static-locations: classpath:/static/,classpath:/public/,file:./uploads/

⚠️ 注意:
配置后会覆盖默认路径,不是追加,所以要把需要的路径都写上。


五、静态资源放行(解决 Shiro/Security 拦截 404)

如果项目集成了 Shiro/Spring Security,静态资源会被登录拦截,必须手动放行:

1. Shiro 放行配置

go 复制代码
filterMap.put("/static/**", "anon");
filterMap.put("/uploads/**", "anon");
filterMap.put("/**.js", "anon");
filterMap.put("/**.css", "anon");
filterMap.put("/**.png", "anon");
filterMap.put("/**.jpg", "anon");
filterMap.put("/**.ico", "anon");

2. Security 放行配置

go 复制代码
http.authorizeRequests()
    .antMatchers("/static/**","/uploads/**","/**.js","/**.css").permitAll()
    .anyRequest().authenticated();

六、自定义 favicon.ico(网站图标)

只需要把 favicon.ico 放到:

go 复制代码
resources/static/favicon.ico

SpringBoot 自动加载,无需任何配置。


七、SpringBoot 静态资源缓存(生产优化)

go 复制代码
registry.addResourceHandler("/static/**")
        .addResourceLocations("classpath:/static/")
        // 浏览器缓存 10 天
        .setCachePeriod(864000);

八、图片上传 + 回显完整实战

1. 上传接口

go 复制代码
@PostMapping("/upload")
public Result upload(MultipartFile file) throws IOException {
    // 上传目录
    String path = "D:/uploads/";
    File dir = new File(path);
    if (!dir.exists()) dir.mkdirs();

    // 文件名
    String fileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
    file.transferTo(new File(path + fileName));

    // 返回可访问的 URL
    String url = "http://localhost:8080/uploads/" + fileName;
    return Result.success(url);
}

2. 配置映射

go 复制代码
registry.addResourceHandler("/uploads/**")
        .addResourceLocations("file:D:/uploads/");

九、Linux 服务器部署路径写法

go 复制代码
registry.addResourceHandler("/uploads/**")
        .addResourceLocations("file:/usr/local/uploads/");

十、静态资源 404 常见原因

    1. 路径末尾缺少 /

    错误:/uploads

    正确:/uploads/**

    1. 本地路径末尾缺少 /

    错误:file:D:/uploads

    正确:file:D:/uploads/

    1. 被拦截器/权限框架拦截

    需要放行静态资源

    1. Windows 与 Linux 路径格式不一致

    Windows:D:/uploads/

    Linux:/usr/local/uploads/

    1. 目录权限不足

    Linux 需要给目录读写权限


十一、SpringBoot 静态资源核心总结

    1. 默认路径:static 文件夹直接访问
    1. 外部文件:用 addResourceHandler 映射
    1. 图片上传:必须用外部路径,避免打包丢失
    1. 权限拦截:一定要放行静态资源
    1. 路径格式:末尾必须加 /
    1. 生产环境:配置缓存提升性能

掌握这些,所有静态资源问题全部解决!


结尾互动

大家在开发中有没有遇到过静态资源 404、图片无法访问的问题?

都是怎么解决的?欢迎评论区留言交流!


相关推荐
猪猪拆迁队1 天前
虚拟工厂仿真引擎的架构设计:让一条产线可编程、可观测、可干预
后端·ai编程
字节跳动数据库1 天前
文章分享——相似函数处理方法
人工智能·后端·程序员
云技纵横1 天前
@Transactional 失效的 7 种场景:第 5 种最难排查
后端
用户6757049885021 天前
你知道 Go 结构体和结构体指针调用的区别吗?一文带你彻底搞懂!
后端·go
程序员cxuan1 天前
读懂 Claude Code 架构分析系列,第一篇,开始!
人工智能·后端·架构
用户6757049885021 天前
面试官问“装饰器模式”,这样回答薪资多要 3000!
后端
tntxia1 天前
Geo Scene域名修改引起的一些问题
后端
用户298698530141 天前
Java 实现 Word 文档加密与权限解除
java·后端
vanuan1 天前
给你的A2A-Agent加把锁-认证鉴权实战指南
后端
Yeats_Liao1 天前
14:Servlet中的页面跳转-Java Web
java·后端·架构