首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Struts 2 上傳圖片存入 MySQL BLOB 完整實戰:FormFile 處理、ActionForm 驗證、PreparedStatement 二進制流寫入

     編輯:MySQL 資料庫相關知識

資料庫準備

CREATE DATABASE test;
USE test;
CREATE TABLE pic (
    name VARCHAR(20),
    pic BLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

JSP 上傳頁面 (multipart/form-data 必須)

<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head><title>圖片上傳</title></head>
<body>
<s:form action="upload" enctype="multipart/form-data">
    <s:file name="file" label="選擇圖片" />
    <s:textfield name="name" label="圖片名稱" />
    <s:submit value="上傳" />
    <s:cancel />
</s:form>
</body>
</html>

ActionForm (Struts 1 風格,現代建議 Struts 2 ModelDriven)

package com.example.struts.form;

import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;

public class UploadForm extends ActionForm {
    private FormFile file;
    private String name;

    public FormFile getFile() { return file; }
    public void setFile(FormFile file) { this.file = file; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

Action 處理邏輯 (核心:二進制流寫入)

package com.example.struts.action;

import java.io.IOException;
import java.sql.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.upload.FormFile;
import com.example.struts.form.UploadForm;

public class UploadAction extends Action {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response) {
        UploadForm uf = (UploadForm) form;
        FormFile file = uf.getFile();
        String name = uf.getName();

        // 基本驗證
        if (file == null || file.getFileSize() == 0) {
            ActionErrors errors = new ActionErrors();
            errors.add("file", new ActionMessage("error.file.required"));
            saveErrors(request, errors);
            return mapping.findForward("error");
        }

        Connection conn = null;
        PreparedStatement ps = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC";
            conn = DriverManager.getConnection(url, "root", "password");

            String sql = "INSERT INTO pic (name, pic) VALUES (?, ?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, name);
            // 關鍵:使用二進制流避免記憶體溢出
            ps.setBinaryStream(2, file.getInputStream(), file.getFileSize());

            ps.executeUpdate();
            return mapping.findForward("success");
        } catch (Exception e) {
            e.printStackTrace();
            return mapping.findForward("error");
        } finally {
            try { if (ps != null) ps.close(); } catch (SQLException ignored) {}
            try { if (conn != null) conn.close(); } catch (SQLException ignored) {}
        }
    }
}

struts-config.xml 關鍵配置

<form-bean name="uploadForm" type="com.example.struts.form.UploadForm"/>

<action path="/upload"
        type="com.example.struts.action.UploadAction"
        name="uploadForm"
        scope="request"
        input="/upload.jsp">
    <forward name="success" path="/success.jsp"/>
    <forward name="error" path="/error.jsp"/>
</action>

<controller maxFileSize="10M" />  <!-- 限制上傳大小 -->

關鍵技術點總結

現代化建議 (Struts 2 / Spring MVC / Spring Boot)

  • Struts 2:@Action + File 屬性自動注入,攔截器 fileUpload 處理大小/類型限制。
  • Spring MVC:@PostMapping + MultipartFile,file.getBytes() 或 file.getInputStream()。
  • 資料庫層:大物件建議外部儲存 (MinIO/S3/檔案系統),資料庫僅存 URI + 元資料,避免 BLOB 膨脹影響備份/複寫效能。

結語

Struts 上傳圖片存 MySQL BLOB 核心在於 multipart/form-data + FormFile + PreparedStatement.setBinaryStream 三要素。現代架構建議外部物件儲存 + 資料庫元資料,若必須資料庫存儲,使用連線池、流式寫入、完整異常處理,確保穩定可靠。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
點說明
enctypemultipart/form-data 必須,否則 FormFile 為 null
FormFileStruts 封裝上傳檔案,提供 getInputStream()/getFileSize()/getFileName()
setBinaryStreamJDBC 4.0+ 支援流式寫入 BLOB,大檔案不佔用 JVM 堆記憶體
連線池生產環境必須使用 DataSource (DBCP/HikariCP/JNDI),禁止手動 DriverManager
異常處理finally 區塊確保連線/Statement 關閉,避免洩漏