feat: expand struts demo lab
This commit is contained in:
@@ -1,102 +1,50 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>文件上传 - Struts2 学习</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Upload Guide</title>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', 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; }
|
||||
.content { background: white; border-radius: 20px; padding: 40px; }
|
||||
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; }
|
||||
.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; }
|
||||
body { margin: 0; padding: 24px; font-family: "Aptos", "Segoe UI", sans-serif; background: linear-gradient(135deg, #0ea5e9, #38bdf8); }
|
||||
.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: #0284c7; 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: #edf7ff; color: #0284c7; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="breadcrumb">
|
||||
<a href="/">🏠 首页</a> / 文件上传
|
||||
</div>
|
||||
<div class="content">
|
||||
<h1>📁 文件上传</h1>
|
||||
|
||||
<h2>1. 单文件上传</h2>
|
||||
<div class="section">
|
||||
<pre><span class="comment">// Action</span>
|
||||
<span class="keyword">public class</span> UploadAction <span class="keyword">extends</span> ActionSupport {
|
||||
|
||||
<span class="comment">// 文件对象</span>
|
||||
<span class="keyword">private</span> File upload;
|
||||
|
||||
<span class="comment">// 文件名 (格式: 属性名FileName)</span>
|
||||
<span class="keyword">private</span> String uploadFileName;
|
||||
|
||||
<span class="comment">// 文件类型 (格式: 属性名ContentType)</span>
|
||||
<span class="keyword">private</span> String uploadContentType;
|
||||
|
||||
<span class="annotation">@Override</span>
|
||||
<span class="keyword">public</span> String execute() <span class="keyword">throws</span> Exception {
|
||||
<span class="comment">// 保存文件</span>
|
||||
String path = ServletActionContext.getServletContext()
|
||||
.getRealPath(<span class="string">"/upload"</span>);
|
||||
<span class="keyword">new</span> File(path, uploadFileName).createNewFile();
|
||||
|
||||
<span class="comment">// 复制文件</span>
|
||||
FileUtils.copyFile(upload, <span class="keyword">new</span> File(path, uploadFileName));
|
||||
|
||||
<span class="keyword">return</span> SUCCESS;
|
||||
}
|
||||
|
||||
<span class="comment">// getter/setter</span>
|
||||
<span class="keyword">public</span> File getUpload() { <span class="keyword">return</span> upload; }
|
||||
<span class="keyword">public void</span> setUpload(File upload) { <span class="keyword">this</span>.upload = upload; }
|
||||
<span class="keyword">public</span> String getUploadFileName() { <span class="keyword">return</span> uploadFileName; }
|
||||
<span class="keyword">public void</span> setUploadFileName(String uploadFileName) { <span class="keyword">this</span>.uploadFileName = uploadFileName; }
|
||||
<span class="keyword">public</span> String getUploadContentType() { <span class="keyword">return</span> uploadContentType; }
|
||||
<span class="keyword">public void</span> setUploadContentType(String uploadContentType) { <span class="keyword">this</span>.uploadContentType = uploadContentType; }
|
||||
}</pre>
|
||||
</div>
|
||||
|
||||
<h2>2. JSP 表单</h2>
|
||||
<div class="section">
|
||||
<pre><span class="comment"><%@ taglib prefix="s" uri="/struts-tags" %></span>
|
||||
<span class="keyword"><s:form</span> action=<span class="string">"upload"</span> method=<span class="string">"post"</span> enctype=<span class="string">"multipart/form-data"</span><span class="keyword">></span>
|
||||
<span class="keyword"><s:file</span> name=<span class="string">"upload"</span> label=<span class="string">"选择文件"</span>/>
|
||||
<span class="keyword"><s:submit</span> value=<span class="string">"上传"</span>/>
|
||||
<span class="keyword"></s:form></span></pre>
|
||||
</div>
|
||||
|
||||
<h2>3. 多文件上传</h2>
|
||||
<div class="section">
|
||||
<pre><span class="comment">// 使用 List 接收多文件</span>
|
||||
<span class="keyword">private</span> List<File> uploads;
|
||||
<span class="keyword">private</span> List<String> uploadsFileName;
|
||||
<div class="shell">
|
||||
<div class="eyebrow">Guide</div>
|
||||
<h1>Upload demo guide</h1>
|
||||
<p>The refreshed upload flow is deliberately safer for demo use. It shows multipart binding and metadata capture without persisting files.</p>
|
||||
|
||||
<span class="comment">// 表单</span>
|
||||
<span class="keyword"><s:file</span> name=<span class="string">"uploads"</span> multiple=<span class="string">"multiple"</span>/></pre>
|
||||
</div>
|
||||
|
||||
<h2>4. 限制文件大小和类型</h2>
|
||||
<div class="section">
|
||||
<pre><span class="comment">// struts.xml 配置</span>
|
||||
<span class="keyword"><action</span> name=<span class="string">"upload"</span> class=<span class="string">"com.demo.UploadAction"</span><span class="keyword">></span>
|
||||
<span class="keyword"><interceptor-ref</span> name=<span class="string">"fileUpload"</span><span class="keyword">></span>
|
||||
<span class="keyword"><param</span> name=<span class="string">"maximumSize"</span><span class="keyword">></span>10485760<span class="keyword"></param></span><span class="comment"><!-- 10MB --></span>
|
||||
<span class="keyword"><param</span> name=<span class="string">"allowedTypes"</span><span class="keyword">></span>image/png,image/jpeg<span class="keyword"></param></span>
|
||||
<span class="keyword"></interceptor-ref></span>
|
||||
<span class="keyword"><result></span>/upload/success.jsp<span class="keyword"></result></span>
|
||||
<span class="keyword"></action></span></pre>
|
||||
</div>
|
||||
|
||||
<a href="/demo/ajax" class="btn">下一节:AJAX →</a>
|
||||
<h2>Core binding fields</h2>
|
||||
<ul>
|
||||
<li><code>File upload</code> for the primary file object.</li>
|
||||
<li><code>String uploadFileName</code> for the original filename.</li>
|
||||
<li><code>String uploadContentType</code> for the MIME type.</li>
|
||||
<li>Optional lists for multiple files.</li>
|
||||
</ul>
|
||||
|
||||
<pre>public class FileUploadAction extends ActionSupport {
|
||||
private File upload;
|
||||
private String uploadFileName;
|
||||
private String uploadContentType;
|
||||
|
||||
public String execute() {
|
||||
// demo keeps metadata only
|
||||
return SUCCESS;
|
||||
}
|
||||
}</pre>
|
||||
|
||||
<div class="links">
|
||||
<a class="btn" href="../../upload/index.jsp">Open upload demo</a>
|
||||
<a class="btn" href="../../index.jsp">Back to portal</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user