首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Struts2 實現 CRUD 完整教程:從 DAO 到 Action 再到 JSP 的全棧實戰

     編輯:Java 相關知識

專案架構概覽

採用經典分層:Model (Book) → DAO (BookDao) → Action (BookAction) → JSP (List/Edit)。為聚焦 Struts2 機制,DAO 使用 ConcurrentHashMap 模擬資料庫。

核心代碼實現

1. 領域模型

public class Book {
    private String isbn;  // 主鍵
    private String title;
    private double price;
    // 構造器、getter/setter 省略
}

2. DAO 層 (單例 + 線程安全 Map)

public class BookDao {
    private static final BookDao INSTANCE = new BookDao();
    private final ConcurrentMap data = new ConcurrentHashMap<>();

    static { /* 初始化 5 本書 */ }

    private BookDao() {}
    public static BookDao getInstance() { return INSTANCE; }

    public Collection getBooks() { return data.values(); }
    public Book getBook(String isbn) { return data.get(isbn); }
    public void storeBook(Book book) { data.put(book.getIsbn(), book); }
    public void removeBook(String isbn) { data.remove(isbn); }
    public void removeBooks(String[] isbns) { for (String id : isbns) data.remove(id); }
}

3. Action 層 (ModelDriven + 分頁)

@Controller("bookAction")
@Scope("prototype")
public class BookAction extends ActionSupport implements ModelDriven {
    private Book book = new Book();
    private String isbn;
    private String[] isbns;
    private Collection books;
    private BookDao dao = BookDao.getInstance();
    // 分頁參數
    private int page = 1, rows = 5;
    private Map pageMap = new HashMap<>();

    @Override public Book getModel() { return book; }
    // getter/setter 省略

    public String list() {
        books = dao.getBooks();
        return SUCCESS;
    }

    public String load() {          // 編輯回顯
        book = dao.getBook(isbn);
        return SUCCESS;
    }

    public String store() {         // 新增/更新
        dao.storeBook(book);
        return SUCCESS;
    }

    public String remove() {        // 刪除(單/批)
        if (isbn != null) dao.removeBook(isbn);
        else dao.removeBooks(isbns);
        return SUCCESS;
    }

    // AJAX 分頁查詢 (EasyUI DataGrid 專用)
    public String query() {
        // 實際專案中由 Service 處理分頁 HQL/SQL
        pageMap.put("rows", books); // 簡化演示
        pageMap.put("total", books.size());
        return "jsonMap";
    }
}

4. struts.xml 配置 (通配符映射 + JSON)

<package name="book" namespace="/Book" extends="struts-default">
    <action name="List" class="bookAction" method="list">
        <result>/Book/List.jsp</result>
    </action>
    <action name="Edit" class="bookAction" method="load">
        <result>/Book/Edit.jsp</result>
    </action>
    <action name="Store" class="bookAction" method="store">
        <result type="redirectAction">List</result>
    </action>
    <action name="Remove" class="bookAction" method="remove">
        <result type="redirectAction">List</result>
    </action>
    <action name="Query" class="bookAction" method="query">
        <result type="json">
            <param name="root">pageMap</param>
        </result>
    </action>
</package>

5. JSP 列表頁 (EasyUI DataGrid + 工具欄)

<%@ taglib prefix="s" uri="/struts-tags" %>
<table id="dg"></table>

<script>
$(function(){
    $('#dg').datagrid({
        url: 'Query.action',
        fitColumns: true, pagination: true, pageSize: 5,
        toolbar: [{
            iconCls: 'icon-add', text: '新增',
            handler: function(){ openDialog('Add'); }
        }, '-', {
            iconCls: 'icon-edit', text: '編輯',
            handler: function(){ openDialog('Edit'); }
        }, '-', {
            iconCls: 'icon-remove', text: '刪除',
            handler: removeSelected
        }],
        columns: [[
            {field:'isbn', title:'ISBN', width:100},
            {field:'title', title:'書名', width:150},
            {field:'price', title:'價格', width:80, formatter: function(v){ return '$'+v; }}
        ]]
    });
});

function openDialog(mode) {
    // 彈窗載入 Edit.jsp,mode 區分新增/編輯
}
function removeSelected() {
    var rows = $('#dg').datagrid('getSelections');
    if (!rows.length) return $.messager.alert('提示','請選中行');
    var ids = rows.map(r => r.isbn).join(',');
    $.post('Remove.action', {isbns: ids}, function(){
        $('#dg').datagrid('reload');
    });
}
</script>

6. 編輯頁 (新增/編輯合一)

<s:form action="Store">
    <s:hidden name="book.isbn" />
    <s:textfield name="book.title" label="書名" />
    <s:textfield name="book.price" label="價格" />
    <s:submit />
</s:form>

關鍵知識點總結

  • ModelDriven:自動將表單數據封裝到 book 對象,name="book.title" 對應 book.setTitle()。
  • redirectAction:POST-REDIRECT-GET 模式,防止重複提交。
  • JSON 插件:type="json" + root 參數,自動序列化指定對象為 JSON 響應。
  • 主鍵處理:新增時 ISBN 為空/前端生成,編輯時隱藏域攜帶原 ISBN,DAO storeBook 統一處理。

本例為教學簡化:生產環境請補全 — 輸入驗證、事務管理、Service 層解耦、分頁查詢下推到 SQL、國際化、權限控制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved