必须使用 ${pagecontext.request.contextpath} 或 拼接资源路径,否则以 / 开头的硬编码路径会忽略应用上下文导致 404;相对路径易受当前 url 影响而失效;css 内部 url() 与 jsp 路径无关,需按 css 文件位置计算。

直接写 /css/style.css 会 404,因为浏览器按服务器根路径解析,漏掉了应用的 context path(比如 /myapp);必须用 ${pageContext.request.contextPath} 或 <url></url> 拼出完整上下文前缀。
为什么 /css/style.css 在 JSP 里总 404
浏览器看到 href="/css/style.css",就无条件请求 http://localhost:8080/css/style.css——完全不认你部署在 /myapp 下的事实。哪怕页面地址是 http://localhost:8080/myapp/list.jsp,它也不会自动补上前缀。结果就是服务端找不到该路径,返回 404。
- 硬编码
/开头的路径 = 告诉浏览器“从服务器根开始找”,不是“从我这个应用根开始” - 相对路径(如
css/style.css或../css/style.css)更危险:URL 由当前请求路径决定,/admin/user.jsp和/user.jsp会生成不同 base,极易错乱 - Spring MVC、Struts 等框架跳转后,请求 URL 路径变长,相对路径失效概率陡增
${pageContext.request.contextPath} 是最常用也最稳的写法
它不需要额外 taglib,JSP 2.0+ 默认支持,语义清晰,还能拼接变量。
- 基础用法:
<link rel="stylesheet" href="%24%7BpageContext.request.contextPath%7D/css/main.css"> - 带主题切换:
<link rel="stylesheet" href="%24%7BpageContext.request.contextPath%7D/css/%24%7Btheme%7D.css">(c:url不支持这种插值) - 避免手误:别写成
${pageContext.request.contextPath }/css/(尾部多空格),EL 表达式会静默失败 - 注意大小写:
contextPath是小写 p,写成ContextPath会取不到值
<url></url> 要么不用,要用就必须规范
c:url 是 JSTL 标签,不是 JSP 原生能力,用之前得确认环境已就绪。
- 必须引入 taglib:
- 路径必须以
/开头:<url value="/css/main.css"></url>✅;<url value="css/main.css"></url>❌(变成相对路径) - 不能嵌套变量:
<url value="/css/${theme}.css"></url>会原样输出,不会解析 EL - Spring Boot 项目默认不含 JSTL,需显式添加依赖:
jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api+org.glassfish.web:jakarta.servlet.jsp.jstl
CSS 文件内部的 url() 引用跟 JSP 路径完全无关
无论你怎么写 <link href="...">,CSS 文件里写的 background: url(images/bg.png),永远以该 CSS 文件自身位置为基准解析,不是以 JSP 页面位置算。
- 如果
main.css在/css/main.css,而图片在/images/bg.png,就得写url(../images/bg.png) -
c:url和contextPath对 CSS 内部的url()零影响,别指望它们能“透传”进去 - 真正要统一管理资源路径,得靠构建工具(如 Webpack)或后端静态资源映射,而不是在 JSP 层硬凑
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











