<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Struts2 学习中心</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 1000px; margin: 40px auto; padding: 20px; background:#f7f8fa; }
        h1 { color: #e74c3c; }
        h2 { color: #3498db; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
        .card { background: #fff; padding: 20px; border-radius: 12px; margin: 20px 0; box-shadow:0 4px 14px rgba(0,0,0,.06); }
        .card h3 { margin-top: 0; }
        ul { line-height: 1.9; }
        a { color: #3498db; text-decoration: none; }
        a:hover { text-decoration: underline; }
        .btn { display: inline-block; background: #3498db; color: white; padding: 10px 20px; border-radius: 6px; margin: 5px; }
        .btn:hover { text-decoration: none; background: #2980b9; }
        .btn-green { background: #27ae60; }
        .btn-purple { background: #9b59b6; }
        code { background: #eee; padding: 2px 6px; border-radius: 3px; }
        .lab { background:#fff7e6; border-left:4px solid #fa8c16; padding:15px; border-radius:8px; margin:20px 0; }
        .quick-tools { display:flex; gap:10px; flex-wrap:wrap; margin-top:10px; }
        .grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:16px; }
    </style>
</head>
<body>
    <h1>🎓 Struts2 学习中心</h1>

    <div class="lab">
        <strong>🧪 学习任务卡</strong>
        <ul>
            <li>先点“拦截器演示”，观察执行统计和链路顺序</li>
            <li>再点“计算器”，故意输入非法值体验 Struts2 校验</li>
            <li>最后点“用户管理”，理解 Action + JSP + 表单提交流程</li>
        </ul>
        <div class="quick-tools">
            <a class="btn btn-purple" href="interceptor">直接去拦截器实验</a>
            <a class="btn" href="calc">直接去计算器实验</a>
            <a class="btn btn-green" href="user">直接去用户管理实验</a>
        </div>
    </div>

    <div class="grid">
        <div class="card">
            <h3>👋 最小闭环</h3>
            <p>从 <code>/hello</code> 开始，看 Action 如何返回 JSP 页面。</p>
            <a class="btn" href="hello">打开 Hello</a>
        </div>
        <div class="card">
            <h3>🔢 表单与校验</h3>
            <p>用计算器理解参数绑定、校验失败回显、成功结果显示。</p>
            <a class="btn" href="calc">打开计算器</a>
        </div>
        <div class="card">
            <h3>🛡️ 拦截器机制</h3>
            <p>学习 Struts2 最核心的增强机制：日志、计时、限流、监控。</p>
            <a class="btn btn-purple" href="interceptor">打开拦截器实验</a>
        </div>
        <div class="card">
            <h3>👥 CRUD 业务流</h3>
            <p>通过用户管理体验列表页、表单页、重定向和状态更新。</p>
            <a class="btn btn-green" href="user">打开用户管理</a>
        </div>
        <div class="card">
            <h3>🧪 OGNL / 参数绑定实验</h3>
            <p>通过真正可交互的表单观察 Struts2 的字段绑定、嵌套对象绑定和集合绑定。</p>
            <a class="btn btn-purple" href="ognl">打开 OGNL 实验室</a>
        </div>
        <div class="card">
            <h3>⚠️ 验证与错误流实验</h3>
            <p>学习为什么校验失败不会直接 500，而是回到 input 页面并显示字段级错误。</p>
            <a class="btn" href="validation">打开验证实验室</a>
        </div>
        <div class="card">
            <h3>🚀 AJAX 异步交互</h3>
            <p>学习Struts2如何处理AJAX请求，返回JSON数据，实现无刷新交互和实时数据更新。</p>
            <a class="btn purple" href="ajax">打开AJAX演示</a>
        </div>
        <div class="card">
            <h3>📁 文件上传</h3>
            <p>演示单文件和多文件上传，学习文件类型验证、大小限制和文件处理流程。</p>
            <a class="btn green" href="upload">打开文件上传</a>
        </div>
    </div>

    <h2>📚 学习路径</h2>
    <div class="card">
        <h3>1. MVC 架构</h3>
        <ul>
            <li><strong>Model:</strong> Action 类 + JavaBean</li>
            <li><strong>View:</strong> JSP + Struts 标签库</li>
            <li><strong>Controller:</strong> StrutsPrepareAndExecuteFilter</li>
        </ul>
    </div>

    <div class="card">
        <h3>2. 拦截器机制</h3>
        <ul>
            <li><code>Interceptor</code> 接口: init() → intercept() → destroy()</li>
            <li><code>interceptor-stack</code>: 组合多个拦截器</li>
            <li>执行顺序: 责任链模式（先入后出）</li>
        </ul>
    </div>

    <div class="card">
        <h3>3. OGNL 与标签库</h3>
        <ul>
            <li><code>&lt;s:property value="name"/&gt;</code> - 输出属性</li>
            <li><code>&lt;s:iterator value="list"&gt;</code> - 遍历集合</li>
            <li><code>&lt;s:form&gt;</code> + <code>&lt;s:textfield&gt;</code> - 表单绑定</li>
        </ul>
    </div>

    <div class="card">
        <h3>4. 你当前项目里有哪些实验</h3>
        <ul>
            <li><strong>Hello：</strong>最小 Action/JSP 映射</li>
            <li><strong>Calculator：</strong>参数绑定 + 校验 + 错误回显</li>
            <li><strong>Interceptor：</strong>理解自定义拦截器与请求链</li>
            <li><strong>User CRUD：</strong>模拟真实业务增删改查</li>
        </ul>
    </div>

    <p><a href="/">← 返回首页</a></p>
</body>
</html>
