feat: expand struts demo lab

This commit is contained in:
Codex
2026-03-18 18:12:20 +08:00
parent 1f60832445
commit fba7b0497f
25 changed files with 1847 additions and 1447 deletions

View File

@@ -1,168 +1,53 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World - Struts2 学习</title>
<title>Hello Action Guide</title>
<style>
body { font-family: 'Segoe UI', 'PingFang SC', sans-serif; background: linear-gradient(135deg, #667eea, #764ba2); min-height: 100vh; margin: 0; padding: 20px; }
.container { max-width: 1200px; margin: 0 auto; }
.breadcrumb { background: white; padding: 15px 25px; border-radius: 10px; margin-bottom: 20px; }
.breadcrumb a { color: #667eea; text-decoration: none; }
.content { background: white; border-radius: 20px; padding: 40px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); }
h1 { color: #667eea; border-bottom: 3px solid #667eea; padding-bottom: 15px; }
h2 { color: #764ba2; margin-top: 30px; }
.section { margin: 25px 0; padding: 20px; background: #f8f9fa; border-radius: 10px; }
code { background: #1e1e1e; color: #d4d4d4; padding: 2px 8px; border-radius: 4px; font-family: Consolas, monospace; }
pre { background: #1e1e1e; color: #d4d4d4; padding: 20px; border-radius: 10px; overflow-x: auto; font-size: 0.9em; }
.keyword { color: #569cd6; }
.string { color: #ce9178; }
.comment { color: #6a9955; }
.btn { display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 25px; margin-right: 10px; }
.btn:hover { background: #764ba2; }
.note { background: #fff3e0; border-left: 4px solid #ff9800; padding: 15px; margin: 20px 0; border-radius: 0 10px 10px 0; }
body { margin: 0; padding: 24px; font-family: "Aptos", "Segoe UI", sans-serif; background: linear-gradient(135deg, #1464c7, #3a8dff); }
.shell { max-width: 980px; margin: 0 auto; background: rgba(255,255,255,0.96); border-radius: 28px; padding: 28px; box-shadow: 0 24px 60px rgba(0,0,0,0.18); }
.eyebrow { font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em; color: #1464c7; font-weight: 800; }
h1, h2 { margin: 10px 0 12px; }
p, li { color: #53667d; line-height: 1.9; }
pre { background: #101827; color: #d9e7ff; padding: 18px; border-radius: 18px; overflow-x: auto; }
.links { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.btn { display: inline-flex; padding: 10px 14px; border-radius: 999px; text-decoration: none; font-weight: 700; background: #e8f2ff; color: #1464c7; }
</style>
</head>
<body>
<div class="container">
<div class="breadcrumb">
<a href="/">🏠 首页</a> / Hello World
</div>
<div class="content">
<h1>👋 Hello World - 第一个 Struts2 应用</h1>
<div class="note">
<strong>📝 本节要点:</strong> 创建最简单的 Struts2 应用,掌握 Action 编写和 struts.xml 配置
</div>
<h2>1. 项目结构</h2>
<pre>
webapp/
├── WEB-INF/
│ ├── web.xml
│ └── lib/
│ └── struts2-core.jar
├── struts.xml ← Action 配置
├── index.jsp
└── hello.jsp ← 结果页面</pre>
<h2>2. web.xml 配置</h2>
<div class="section">
<pre><span class="comment">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="keyword">&lt;web-app</span> xmlns=<span class="string">"http://xmlns.jcp.org/xml/ns/javaee"</span><span class="keyword">&gt;</span>
<span class="comment">&lt;!-- Struts2 核心过滤器 --&gt;</span>
<span class="keyword">&lt;filter&gt;</span>
<span class="keyword">&lt;filter-name&gt;</span>struts2<span class="keyword">&lt;/filter-name&gt;</span>
<span class="keyword">&lt;filter-class&gt;</span>
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
<span class="keyword">&lt;/filter-class&gt;</span>
<span class="keyword">&lt;/filter&gt;</span>
<span class="keyword">&lt;filter-mapping&gt;</span>
<span class="keyword">&lt;filter-name&gt;</span>struts2<span class="keyword">&lt;/filter-name&gt;</span>
<span class="keyword">&lt;url-pattern&gt;</span>/*<span class="keyword">&lt;/url-pattern&gt;</span>
<span class="keyword">&lt;/filter-mapping&gt;</span>
<span class="keyword">&lt;/web-app&gt;</span></pre>
</div>
<h2>3. struts.xml 配置</h2>
<div class="section">
<pre><span class="comment">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="keyword">&lt;!DOCTYPE struts PUBLIC</span>
<span class="string">"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"</span>
<span class="string">"http://struts.apache.org/dtds/struts-2.5.dtd"</span><span class="keyword">&gt;</span>
<div class="shell">
<div class="eyebrow">Guide</div>
<h1>Hello action walkthrough</h1>
<p>The hello demo is still the best first stop for explaining how Struts2 maps a request to an action and then routes to a JSP result.</p>
<span class="keyword">&lt;struts&gt;</span>
<span class="comment">&lt;!-- 开发模式 --&gt;</span>
<span class="keyword">&lt;constant</span> name=<span class="string">"struts.devMode"</span> value=<span class="string">"true"</span><span class="keyword">/&gt;</span>
<span class="comment">&lt;!-- 定义包 --&gt;</span>
<span class="keyword">&lt;package</span> name=<span class="string">"default"</span> namespace=<span class="string">"/"</span> extends=<span class="string">"struts-default"</span><span class="keyword">&gt;</span>
<span class="comment">&lt;!-- Action 配置 --&gt;</span>
<span class="keyword">&lt;action</span> name=<span class="string">"hello"</span> class=<span class="string">"com.demo.HelloAction"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;result&gt;</span>/hello.jsp<span class="keyword">&lt;/result&gt;</span>
<span class="keyword">&lt;/action&gt;</span>
<span class="keyword">&lt;/package&gt;</span>
<span class="keyword">&lt;/struts&gt;</span></pre>
</div>
<h2>4. HelloAction.java</h2>
<div class="section">
<pre><span class="keyword">package</span> com.demo;
<h2>Flow</h2>
<ul>
<li>The browser requests <code>/hello</code> or <code>/hello?name=Team</code>.</li>
<li>Struts populates the <code>name</code> property on <code>HelloAction</code>.</li>
<li><code>execute()</code> builds a view message and returns <code>SUCCESS</code>.</li>
<li>The framework resolves the success result to <code>/hello.jsp</code>.</li>
</ul>
<span class="keyword">import</span> com.opensymphony.xwork2.ActionSupport;
<h2>Minimal action shape</h2>
<pre>public class HelloAction extends ActionSupport {
private String name;
private String message;
<span class="comment">/**
* 第一个 Struts2 Action
* 继承 ActionSupport 可以获得验证、国际化的能力
*/</span>
<span class="keyword">public class</span> HelloAction <span class="keyword">extends</span> ActionSupport {
<span class="comment">// 接收参数</span>
<span class="keyword">private</span> String name;
<span class="comment">// 返回给页面的数据</span>
<span class="keyword">private</span> String message;
<span class="comment">/**
* 执行方法,默认调用
*/</span>
<span class="annotation">@Override</span>
<span class="keyword">public</span> String execute() <span class="keyword">throws</span> Exception {
<span class="keyword">if</span> (name == <span class="keyword">null</span> || name.trim().isEmpty()) {
name = <span class="string">"Struts2 学习者"</span>;
public String execute() {
if (name == null || name.trim().isEmpty()) {
name = "World";
}
message = <span class="string">"你好, "</span> + name + <span class="string">"! 欢迎学习 Struts2!"</span>;
<span class="keyword">return</span> SUCCESS; <span class="comment">// 返回 "success"</span>
message = "Hello, " + name + "!";
return SUCCESS;
}
<span class="comment">// Getter/Setter 必须提供Struts2 通过反射注入参数</span>
<span class="keyword">public</span> String getName() { <span class="keyword">return</span> name; }
<span class="keyword">public void</span> setName(String name) { <span class="keyword">this</span>.name = name; }
<span class="keyword">public</span> String getMessage() { <span class="keyword">return</span> message; }
<span class="keyword">public void</span> setMessage(String message) { <span class="keyword">this</span>.message = message; }
}</pre>
</div>
<h2>5. hello.jsp 结果页面</h2>
<div class="section">
<pre><span class="comment">&lt;%@ page contentType="text/html;charset=UTF-8" language="java" %&gt;</span>
<span class="comment">&lt;%@ taglib prefix="s" uri="/struts-tags" %&gt;</span>
<span class="keyword">&lt;!DOCTYPE html&gt;</span>
<span class="keyword">&lt;html&gt;</span>
<span class="keyword">&lt;body&gt;</span>
<span class="comment">&lt;!-- 使用 Struts2 标签获取 Action 返回的值 --&gt;</span>
<span class="keyword">&lt;h1&gt;&lt;s:property</span> value=<span class="string">"message"</span>/&gt;&lt;/h1&gt;
<span class="keyword">&lt;/body&gt;</span>
<span class="keyword">&lt;/html&gt;</span></pre>
</div>
<h2>6. 访问方式</h2>
<div class="section">
<p>启动应用后,访问:</p>
<code>http://localhost:8080/hello</code> - 默认执行<br>
<code>http://localhost:8080/hello?name=张三</code> - 传递参数
</div>
<h2>执行流程图</h2>
<div class="section">
<pre style="text-align: center;">
浏览器请求 → Struts2 Filter → ActionProxy → HelloAction.execute()
→ 返回 "success" → 配置的 result → hello.jsp → 浏览器</pre>
</div>
<div style="margin-top: 30px;">
<a href="/demo/validation" class="btn">下一节:表单验证 →</a>
<a href="/" class="btn" style="background: #764ba2;">← 返回首页</a>
</div>
<div class="links">
<a class="btn" href="../../hello?name=Platform%20Team">Run hello action</a>
<a class="btn" href="../../index.jsp">Back to portal</a>
</div>
</div>
</body>
</html>
</html>