CRUD is the abbreviation of Create, Read, Update, and Delete, and it is a microcosm of ordinary applications. If you master the CRUD writing of a framework, it means that you can use the framework to create ordinary applications. Therefore, when you use the new framework to develop OLTP (Online Transaction Processing) applications, you will first study how to write CRUD. This is similar to the way people like to write "Hello World" when learning new programming languages.
This article is intended to describe the development of CRUD on Struts 2, so for the sake of simplicity and ease of understanding, I will not spend time on database operations. Instead, a hash table (Hash Map) that simulates the database.
Specific implementation
First, let's take a look at the "fake" DAO (Data Access Object, data access object), the code is as follows:
package tutorial.dao;import java.util.Collection;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import tutorial.model.Book;public class BookDao {private static final BookDao instance;private static final ConcurrentMap<String, Book> data;static {instance = new BookDao();data = new ConcurrentHashMap<String, Book>();data.put("978-0735619678", new Book("978-0735619678", "Code Complete, Second Edition", 32.99));data.put("978-0596007867", new Book("978-0596007867", "The Art of Project Management", 35.96));data.put("978-0201633610", new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));data.put("978-0596527341", new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));data.put("978-0735605350", new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));}private BookDao() {}public static BookDao getInstance() {return instance;}public Collection<Book> 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[] isbn) {for(String isbn : isbn) {data.remove(isbn);}}}Listing 1 src/tutorial/dao/BookDao.java
I believe that no explanation is required for the above code. I use the ConcurrentMap data structure to store Book objects, which is mainly to facilitate the retrieval and storage of Book objects; in addition, I also set the data variable to be statically unique to simulate the application's database.
Next is the Data Model Book class, the code is as follows:
package tutorial.model;public class Book {private String isbn;private String title;private double price;public Book() { }public Book(String isbn, String title, double price) {this.isbn = isbn;this.title = title;this.price = price;}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;} }Listing 2 src/tutorial/model/Book.java
The Book class has three attributes: isbn, title and price represent the number, name and price of the book, respectively. The number is used to uniquely identify the book (equivalent to the primary key in the database).
Then, let's take a look at the code of the Action class:
package tutorial.action;import java.util.Collection;import tutorial.dao.BookDao;import tutorial.model.Book;import com.opensymphony.xwork2.ActionSupport;public class BookAction extends ActionSupport {private static final long serialVersionUID = 872316812305356L;private String isbn;private String[] isbn;private Book book;private Collection<Book> books;private BookDao dao = BookDao.getInstance();public Book getBook() {return book;}public void setBook(Book book) {this.book = book;}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}public String[] getIsbnns() {return isbn;}public void setIsbnns(String[] isbnns) {this.isbns = isbnns;}public Collection<Book> getBooks() {return books;}public void setBooks(Collection<Book> books) {this.books = books;}public String load() {book = dao.getBook(isbn);return SUCCESS;}public String list() {books = dao.getBooks();return SUCCESS;}public String store() {dao.storeBook(book);return SUCCESS;}public String remove() {if(null != isbn) {dao.removeBook(isbn);} else {dao.removeBooks(isbns);}return SUCCESS;}}Listing 3 src/tutorial/action/BookAction.java
In BookAction class, the attribute isbn is used to represent the number of books to be edited or deleted, the attribute isbns is used to represent the number array of books to be deleted, the attribute book represents the current book, and the attribute books represents the current book list. BookAction has four Action methods, load, list, store and remove, that is, CRUD is all implemented in BookAction.
Next is the Action configuration code:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN""http://struts.apache.org/dtds/struts-2.0.dtd"><struts><package name="Struts2_CRUD_DEMO" extends="struts-default" namespace="/Book"><action name="List" method="list"><result>List.jsp</result></action><action name="Edit" method="load"><result>Edit.jsp</result></action><action name="Store" method="store"><result type="redirect">List.action</result></action></action><action name="Remove" method="remove"><result type="redirect">List.action</result></action></package></struts>
Listing 4 src/struts.xml
In the above configuration, I used four Action definitions. They are all within the "/Book" namespace. In this way, I can call the four Action methods of BookAction for CRUD operations by "http://localhost:8080/Struts2_CRUD/Book/List.action", "http://localhost:8080/Struts2_CRUD/Book/Edit.action", "http://localhost:8080/Struts2_CRUD/Book/Store.action" and "http://localhost:8080/Struts2_CRUD/Book/Remove.action". Of course, this is just a personal preference. You can only define an Action (assuming its name is "Book"), and then access it through "http://localhost:8080/Struts2_CRUD/Book!list.action". For details, please refer to "Struts 2.0 Action Explanation". Also, I use a result of type redirect (redirect) since I want to return to the list page after finishing editing or deletion.
Here is the code for the list page:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %><%@ taglib prefix="s" uri="/struts-tags" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Book List</title><style type="text/css">table {border: 1px solid black;border-collapse: collapse;}table thead tr th {border: 1px solid black;padding: 3px;background-color: #cccccc;}table tbody td {border: 1px solid black;padding: 3px;}</style></head><body> <h2>Book List</h2><s:form action="Remove" theme="simple"><table cellpacing="0"><thead><tr><th>Select</th><th>ISBN</th><th>Title</th><th>Price</th><th>Operation</th></tr></thead><tbody><s:iterator value="books"><tr><td><input type="checkbox" name="isbn" value='<s:property value="isbn" />' /></td><td><s:property value="isbn" /> /></td><td>$<s:property value="price" /></td><td><a href='<s:url action="Edit"><s:param name="isbn" value="isbn" /></s:url>'>Edit</a><a href='<s:url action="Remove"><s:param name="isbn" value="isbn" /></s:url>'>Delete</a></td></tr></s:iterator></tbody></table><s:submit value="Remove" /><a href="Edit.jsp">Add Book</a></s:form> </body></html>Listing 5 WebContent/Book/List.jsp
In the above code, it is worth noting that in the <s:form> tag, I set the theme property to "simple", so that it can cancel its default table layout. Previously, some friends asked me, "What should I do if I don't want the submit button to be placed on the right?" The above sweating is one of the answers. Of course, it is better to customize a theme and apply it to the entire site by default, so that you can get a unified site style. I will describe this in detail in future articles.
The page code for editing or adding books is as follows:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %><%@ taglib prefix="s" uri="/struts-tags" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Book</title></head><body> <h2><s:if test="null == book">Add Book</s:if><s:else>Edit Book</s:else></h2><s:form action="Store" ><s:textfield name="book.isbn" label="ISBN" /><s:textfield name="book.title" label="Title" /><s:textfield name="book.price" label="Price" /><s:submit /></s:form></body></html>
Listing 6 WebContent/Book/Edit.jsp
If the book is null, it means that the page is used to add books, and vice versa is the edit page.
To facilitate everyone to run the examples, I also posted the web.xml code, as follows:
<?xml version="1.0" encoding="UTF-8"?><web-app id="WebApp_9" version="2.4"xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"><display-name>Struts 2 Fileupload</display-name><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping><welcome-file-list><welcome-file>index.html</welcome-file></welcome-file-list></web-app>
Listing 7 WebContent/WEB-INF/web.xml
The task is done, the following is published to run the application, type: http://localhost:8080/Struts2_CRUD/Book/List.action in the browser, and the page shown in the figure below appears:
Listing 8 Listing Page
Click "Add Book" and the page shown in the figure below appears:
Listing 9 Add Book Page
Return to the list page and click "Edit", and the page shown in the figure below appears:
Listing 10 Edit Book Page
Summarize
This article only briefly introduces the CRUD implementation method of Struts 2, so many functions are not implemented, such as internationalization and data verification. You can improve it based on the above example, and it is also good to practice. If you don’t understand, please leave me a message. The editor will reply to everyone in time. Thank you very much for your support to the Wulin Network website!