本文示範如何將傳統「JSP + Servlet + JavaBean」MVC 專案,逐步重構為 Struts 2.1.6 應用。採用 Convention Plugin 零組態開發,大幅減少 XML 設定,讓 Action 類自動映射至 URL,JSP 置於 WEB-INF/content 保護直接訪問。
解壓 struts-2.1.6-all.zip,將下列 JAR 複製至 WEB-INF/lib:
xwork-2.1.2.jar
struts2-core-2.1.6.jar
struts2-convention-plugin-2.1.6.jar
ognl-2.6.11.jar
freemarker-2.3.13.jar
commons-logging-1.0.4.jar
commons-fileupload-1.2.1.jar
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
單一 Filter 取代多個 Servlet 映射,極度簡潔。
web/
├── WEB-INF/
│ ├── content/ <-- 新增,受保護目錄
│ │ ├── index.jsp
│ │ ├── people.jsp
│ │ └── people-input.jsp
│ ├── lib/ <-- Struts JARs
│ └── web.xml
└── src/
└── cn/he/action/PeopleAction.java
JSP 移入 WEB-INF/content 可防止用戶直接訪問,提升安全性。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><title>MVC MODEL</title></head><body>
<h1>MVC MODEL</h1>
<ul>
<li><a href="people!input.action">添加人員</a></li>
<li><a href="people.action">人員列表</a></li>
</ul>
</body></html>
注意:
!methodName.action 語法指定 Action 方法https://localhost:8080/MvcModel/index(無 .jsp 後綴)或 index.actionpackage cn.he.action;
import java.util.List;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import cn.he.manager.Manager;
import cn.he.pojo.People;
import com.opensymphony.xwork2.ActionSupport;
@Results({
@Result(name = "reload", location = "people.action", type = "redirect")
})
public class PeopleAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private Manager manager = new Manager();
private int id;
private People people;
private List<People> peoples;
// 預設執行 list()
@Override
public String execute() throws Exception { return list(); }
// 查詢列表
public String list() throws Exception {
System.out.println("list");
peoples = manager.queryAllPeople();
System.out.println("name = " + peoples.size());
return SUCCESS;
}
// 進入新增頁面
public String input() throws Exception {
System.out.println("input");
return INPUT;
}
// 保存新增
public String save() throws Exception {
manager.addPeople(people);
return "reload"; // 重導向 people.action 避免重複提交
}
// 刪除
public String delete() throws Exception {
manager.delPeople(id);
return "reload";
}
// Getter/Setter 略
}
Action 結尾,套件名含 action/struts/web 會被自動掃描!methodName.action(如 input() 對應 people!input.action)SUCCESS 預設轉向 /WEB-INF/content/people.jsp@Result(name="reload", type="redirect") 實現 POST-Redirect-GET 模式<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<html><head><title>People列表頁</title></head><body>
<table>
<tr><td>id</td><td>name</td><td>delete</td></tr>
<s:iterator value="peoples" var="peo">
<tr>
<td><s:property value="people.id"/></td>
<td>${peo.name}</td>
<td><a href="people!delete.action?id=${peo.id}">刪除</a></td>
</tr>
</s:iterator>
</table>
</body></html>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html><head><title>People添加頁</title></head><body>
<form action="people!save.action" method="post">
名字: <input type="text" name="people.name"/> <br/>
<input type="submit" value="添加"/>
</form>
</body></html>
name="people.name" 透過 OGNL 自動填充 Action 的 people.name 屬性。
https://localhost:8080/MvcModel/indexpeople.jsp 資料people-input.jsp 表單save() → 重導向列表頁delete() → 重導向列表頁| 面向 | Servlet 手工 MVC | Struts 2.1.6 |
|---|---|---|
| 請求映射 | web.xml 逐一定義 Servlet | 單一 Filter + Convention 自動掃描 |
| Action 類 | 需實作特定介面/繼承基類 | POJO 繼承 ActionSupport,註解配置 |
| 參數綁定 | 手動 request.getParameter() | OGNL 自動填充屬性 |
| 結果導向 | RequestDispatcher.forward() | 註解/慣例定義,支援 redirect/chain |
| JSP 保護 | 需手工放置 WEB-INF | 慣例預設 WEB-INF/content |
| 程式碼量 | 大量樣板代碼 | 極少,專注業務邏輯 |