Files
struts2-demo/web/demo/validation/index.jsp
2026-03-18 15:18:30 +08:00

227 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单验证 - Struts2 学习</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; }
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; }
.note { background: #fff3e0; border-left: 4px solid #ff9800; padding: 15px; margin: 20px 0; border-radius: 0 10px 10px 0; }
.tip { background: #e3f2fd; border-left: 4px solid #2196f3; padding: 15px; margin: 20px 0; border-radius: 0 10px 10px 0; }
</style>
</head>
<body>
<div class="container">
<div class="breadcrumb">
<a href="/">🏠 首页</a> / 表单验证
</div>
<div class="content">
<h1>✅ 表单验证</h1>
<div class="note">
<strong>📝 本节要点:</strong> 掌握 Struts2 的两种验证方式:编程式验证和声明式验证
</div>
<h2>1. 验证方式概览</h2>
<div class="section">
<table style="width:100%; border-collapse: collapse;">
<tr style="background:#667eea; color:white;">
<th style="padding:10px; text-align:left;">方式</th>
<th style="padding:10px; text-align:left;">实现方式</th>
<th style="padding:10px; text-align:left;">适用场景</th>
</tr>
<tr style="background:#f8f9fa;">
<td style="padding:10px;">编程式</td>
<td style="padding:10px;">重写 validate() 方法</td>
<td style="padding:10px;">简单验证,逻辑复杂</td>
</tr>
<tr>
<td style="padding:10px;">声明式 - 方法级</td>
<td style="padding:10px;">validateXxx() 方法</td>
<td style="padding:10px;">特定方法的验证</td>
</tr>
<tr style="background:#f8f9fa;">
<td style="padding:10px;">声明式 - XML</td>
<td style="padding:10px;">XxxAction-validation.xml</td>
<td style="padding:10px;">可复用,团队协作</td>
</tr>
</table>
</div>
<h2>2. 方式一:编程式验证 (validate)</h2>
<div class="section">
<pre><span class="keyword">public class</span> LoginAction <span class="keyword">extends</span> ActionSupport {
<span class="keyword">private</span> String username;
<span class="keyword">private</span> String password;
<span class="annotation">@Override</span>
<span class="keyword">public</span> String execute() {
<span class="comment">// 登录逻辑...</span>
<span class="keyword">return</span> SUCCESS;
}
<span class="comment">/**
* 验证方法 - 对所有 execute 方法都生效
*/</span>
<span class="annotation">@Override</span>
<span class="keyword">public void</span> validate() {
<span class="comment">// 用户名验证</span>
<span class="keyword">if</span> (username == <span class="keyword">null</span> || username.trim().length() < 3) {
addFieldError(<span class="string">"username"</span>, <span class="string">"用户名至少3个字符"</span>);
}
<span class="comment">// 密码验证</span>
<span class="keyword">if</span> (password == <span class="keyword">null</span> || password.length() < 6) {
addFieldError(<span class="string">"password"</span>, <span class="string">"密码至少6个字符"</span>);
}
}
<span class="comment">// getter/setter...</span>
}</pre>
</div>
<h2>3. 方式二:方法级验证 (validateXxx)</h2>
<div class="section">
<pre><span class="comment">/**
* 只验证 register 方法,不验证 login 方法
*/</span>
<span class="keyword">public void</span> validateRegister() {
<span class="keyword">if</span> (email == <span class="keyword">null</span> || !email.contains(<span class="string">"@"</span>)) {
addFieldError(<span class="string">"email"</span>, <span class="string">"邮箱格式不正确"</span>);
}
}</pre>
</div>
<h2>4. 方式三XML 声明式验证</h2>
<div class="tip">
<strong>优点:</strong> 验证规则与代码分离,团队协作更清晰,可复用
</div>
<h3>4.1 创建验证文件</h3>
<div class="section">
<p>文件名格式:<code>ActionName-validation.xml</code></p>
<p>位置:<code>WEB-INF/classes/com/demo/action/</code></p>
<pre><span class="comment">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="keyword">&lt;!DOCTYPE validators PUBLIC</span>
<span class="string">"-//OpenSymphony Group//XWork Validator 1.0.3//EN"</span>
<span class="string">"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;validators&gt;</span>
<span class="comment">&lt;!-- 字段验证 --&gt;</span>
<span class="keyword">&lt;field</span> name=<span class="string">"username"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;field-validator</span> type=<span class="string">"requiredstring"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;message&gt;</span>用户名不能为空<span class="keyword">&lt;/message&gt;</span>
<span class="keyword">&lt;/field-validator&gt;</span>
<span class="keyword">&lt;field-validator</span> type=<span class="string">"stringlength"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;param</span> name=<span class="string">"minLength"</span><span class="keyword">&gt;</span>3<span class="keyword">&lt;/param&gt;</span>
<span class="keyword">&lt;param</span> name=<span class="string">"maxLength"</span><span class="keyword">&gt;</span>20<span class="keyword">&lt;/param&gt;</span>
<span class="keyword">&lt;message&gt;</span>用户名长度3-20字符<span class="keyword">&lt;/message&gt;</span>
<span class="keyword">&lt;/field-validator&gt;</span>
<span class="keyword">&lt;/field&gt;</span>
<span class="comment">&lt;!-- 字段验证email --&gt;</span>
<span class="keyword">&lt;field</span> name=<span class="string">"email"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;field-validator</span> type=<span class="string">"email"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;message&gt;</span>邮箱格式不正确<span class="keyword">&lt;/message&gt;</span>
<span class="keyword">&lt;/field-validator&gt;</span>
<span class="keyword">&lt;/field&gt;</span>
<span class="comment">&lt;!-- 非字段验证 --&gt;</span>
<span class="keyword">&lt;validator</span> type=<span class="string">"expression"</span><span class="keyword">&gt;</span>
<span class="keyword">&lt;param</span> name=<span class="string">"expression"</span><span class="keyword">&gt;</span>password==confirmPassword<span class="keyword">&lt;/param&gt;</span>
<span class="keyword">&lt;message&gt;</span>两次密码不一致<span class="keyword">&lt;/message&gt;</span>
<span class="keyword">&lt;/validator&gt;</span>
<span class="keyword">&lt;/validators&gt;</span></pre>
</div>
<h2>5. 常用验证器类型</h2>
<div class="section">
<table style="width:100%; border-collapse: collapse;">
<tr style="background:#667eea; color:white;">
<th style="padding:10px; text-align:left;">验证器</th>
<th style="padding:10px; text-align:left;">说明</th>
<th style="padding:10px; text-align:left;">示例</th>
</tr>
<tr style="background:#f8f9fa;">
<td style="padding:10px;">required</td>
<td style="padding:10px;">必填</td>
<td style="padding:10px;">username 不能为空</td>
</tr>
<tr>
<td style="padding:10px;">requiredstring</td>
<td style="padding:10px;">字符串必填</td>
<td style="padding:10px;">不能为空字符串</td>
</tr>
<tr style="background:#f8f9fa;">
<td style="padding:10px;">stringlength</td>
<td style="padding:10px;">字符串长度</td>
<td style="padding:10px;">minLength, maxLength</td>
</tr>
<tr>
<td style="padding:10px;">email</td>
<td style="padding:10px;">邮箱格式</td>
<td style="padding:10px;">xxx@xxx.com</td>
</tr>
<tr style="background:#f8f9fa;">
<td style="padding:10px;">regex</td>
<td style="padding:10px;">正则表达式</td>
<td style="padding:10px;">手机号、身份证等</td>
</tr>
<tr>
<td style="padding:10px;">int</td>
<td style="padding:10px;">整数范围</td>
<td style="padding:10px;">min, max</td>
</tr>
<tr style="background:#f8f9fa;">
<td style="padding:10px;">url</td>
<td style="padding:10px;">URL 格式</td>
<td style="padding:10px;">http://xxx.com</td>
</tr>
<tr>
<td style="padding:10px;">date</td>
<td style="padding:10px;">日期范围</td>
<td style="padding:10px;">min, max</td>
</tr>
</table>
</div>
<h2>6. 在 JSP 中显示错误</h2>
<div class="section">
<pre><span class="comment">&lt;%@ taglib prefix="s" uri="/struts-tags" %&gt;</span>
<span class="comment">&lt;!-- 显示特定字段的错误 --&gt;</span>
<span class="keyword">&lt;s:fielderror</span> fieldName=<span class="string">"username"</span>/&gt;
<span class="comment">&lt;!-- 显示所有字段错误 --&gt;</span>
<span class="keyword">&lt;s:fielderror</span>/&gt;
<span class="comment">&lt;!-- 显示 Action 级别错误 --&gt;</span>
<span class="keyword">&lt;s:actionerror</span>/&gt;
<span class="comment">&lt;!-- 显示 Action 级别消息 --&gt;</span>
<span class="keyword">&lt;s:actionmessage</span>/&gt;</pre>
</div>
<div style="margin-top: 30px;">
<a href="/demo/model" class="btn">下一节:数据封装 →</a>
<a href="/" class="btn" style="background: #764ba2;">← 返回首页</a>
</div>
</div>
</div>
</body>
</html>