將靜態 HTML 頁面改造為 JSP,核心在於資源路徑管理與模板化複用。遵循 Maven 標準目錄結構,使用 EL 表達式動態生成上下文路徑,實現 CSS/JS/圖片的模組化引用。
src/main/webapp/
├── WEB-INF/
│ ├── views/ # JSP 頁面放這裡,外部無法直接訪問
│ │ ├── index.jsp
│ │ └── include/ # 通用片段
│ │ ├── header.jsp
│ │ └── footer.jsp
│ └── web.xml
├── resources/ # 靜態資源(與 WEB-INF 同級)
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── main.js
│ └── images/
│ └── logo.png
└── index.jsp # 入口頁面(可選)
在 JSP 頁面頂部定義(或放入通用 taglib.jsp 統一引入):
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}" scope="request" />
<!-- CSS -->
<link rel="stylesheet" href="${ctx}/resources/css/style.css">
<!-- JS -->
<script src="${ctx}/resources/js/main.js"></script>
<!-- 圖片 -->
<img src="${ctx}/resources/images/logo.png" alt="Logo">
<!-- 包含通用片段 -->
<jsp:include page="/WEB-INF/views/include/header.jsp" />
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}" scope="request" />
<!DOCTYPE html>
<html>
<head>
<title>${pageTitle} - 我的系統</title>
<link rel="stylesheet" href="${ctx}/resources/css/bootstrap.min.css">
<link rel="stylesheet" href="${ctx}/resources/css/style.css">
</head>
<body>
<jsp:include page="/WEB-INF/views/include/header.jsp" />
<main class="container">
<h1>歡迎,${user.name}</h1>
<c:forEach items="${articleList}" var="article">
<article>
<h2><a href="${ctx}/article/detail?id=${article.id}">${article.title}</a></h2>
<p>${article.summary}</p>
</article>
</c:forEach>
</main>
<jsp:include page="/WEB-INF/views/include/footer.jsp" />
<script src="${ctx}/resources/js/jquery.min.js"></script>
<script src="${ctx}/resources/js/main.js"></script>
</body>
</html>
@Controller
@RequestMapping("/")
public class IndexController {
@GetMapping
public String index(Model model) {
model.addAttribute("pageTitle", "首頁");
model.addAttribute("user", userService.getCurrentUser());
model.addAttribute("articleList", articleService.listLatest(10));
return "index"; // 對應 /WEB-INF/views/index.jsp
}
}
@Configuration
@EnableWebMvc
@ComponentScan("com.example")
public class WebConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addHandler("/resources/**")
.addResourceLocations("/resources/")
.setCachePeriod(3600); // 靜態資源快取 1 小時
}
}
| 問題 | 原因 | 解決 |
|---|---|---|
| CSS/JS 404 | 路徑寫死 /css/...,部署到子路徑下失效 | 統一用 ${ctx}/resources/... |
| JSP 可直接訪問 | 放在 webapp/ 根目錄 | 移至 WEB-INF/views/ |
| EL 表達式不生效 | web.xml 版本過低或 isELIgnored="true" | web.xml 設 version="3.1",移除忽略屬性 |
| 中文亂碼 | 編碼不一致 | JSP pageEncoding="UTF-8",Tomcat URIEncoding="UTF-8" |
新專案建議使用 Thymeleaf(Spring Boot 官方推薦)或 FreeMarker,語法更安全、支援原型預覽、天然防 XSS,JSP 屬於上一代技術,僅維護舊專案時使用。