Struts2框架整理(CRUD+运行流程)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangligong/article/details/52917244
本博客使用Struts2框架实现CRUD操作,同时通过Debug调试了解Struts2框架内部运行流程。



CRUD

      需求(Create-Retrieve-Upate-Delete)
    使用Struts框架实现增删改查
     
    需求分析
     ①页面
          index.jsp(首页)
          list.jsp(显示所有图书)
          add.jsp(添加一本图书)
          update.jsp(更新/修改一本图书)
     ②类
          实体类
          dao类(模拟一个数据库)
          action类(处理请求)
     ③搭建框架环境
           [1]导入jar
           [2]在web.xml中配置核心控制器
           [3]配置struts.xml
     
     编码,测试

    代码:
                                                                                 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</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>


  基础类:
                                                                    Book类
package com.atguigu.bean;

public class Book {

    public Integer bookId;
    private String bookName;
    private String author;
    private double price;

    public Book() {
        super();
    }

    public Book(Integer bookId, String bookName, String author, double price) {
        super();
        this.bookId = bookId;
        this.bookName = bookName;
        this.author = author;
        this.price = price;
    }

    public Integer getBookId() {
        return bookId;
    }

    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book [bookId=" + bookId + ", bookName=" + bookName
                + ", author=" + author + ", price=" + price + "]";
    }

}
                                                                               BookDao类
package com.atguigu.dao;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.atguigu.bean.Book;

public class BookDao {

    private static Map<Integer, Book> map = new LinkedHashMap<>();
     //用于实现id自增
    private static Integer id = 105;

    static{
        map.put(101, new Book(101, "罗马人的故事1", "盐田七生", 34.5));
        map.put(102, new Book(102, "罗马人的故事2", "盐田七生", 34.5));
        map.put(103, new Book(103, "罗马人的故事3", "盐田七生", 34.5));
        map.put(104, new Book(104, "罗马人的故事4", "盐田七生", 34.5));
        map.put(105, new Book(105, "罗马人的故事5", "盐田七生", 34.5));
    }
    /**
     * 获取所有图书
     * @return
     */
    public List<Book> getAllBook() {
        return new ArrayList<Book>(map.values());
    }
    /**
     * 保存一本图书/修改一本图书
     * 当book对象有id的时候,通过覆盖原先的值而达到修改功能
     * 当book对象没有id的时候,实现保存功能
     * @param book
     */
    public void saveBook(Book book) {
        if(book.getBookId() == null) {
            book.setBookId(++id);
        }
        map.put(book.getBookId(), book);
    }
    /**
     * 根据图书bookId删除图书
     * @param bookId
     */
    public void deleteBook(Integer bookId) {
        map.remove(bookId);
    }
    /**
     * 根据bookId获取到一本图书
     * @param bookId
     * @return
     */
    public Book getBook(Integer bookId) {
        return map.get(bookId);
    }
}


一个功能实现过程:
                                                                         index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center"><a href="${pageContext.request.contextPath }/booklist.action">获取所有图书</a></h1>
</body>
</html>

                                                                        配置获取所有图书的action
<!-- 配置获取所有图书的action -->
        <action name="booklist" class="com.atguigu.action.BookAction" method="bookList">
            <result name="booklist">/bookList.jsp</result>
        </action>
                                                                        编写Action方法
    public String bookList() {
        //获取所有图书
        List<Book> booklist = bookDao.getAllBook();
        //将图书放到request中(map栈)
        request.put("booklist", booklist);
        return "booklist";
    }


                                                                       bookList.jsp显示所有图书
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!-- struts标签库不能使用EL表达式,要使用ognl式子(#表示map集合)
        之前将所有图书放到了map栈中
     -->
    <s:if test="#request.booklist == null || #request.booklist.empty">
        <h1 align="center">没有图书,快去购物吧!</h1>
    </s:if>
    <s:else>
    <h1 align="center">图书列表</h1>
    <table border="1" width="80%" align="center">
        <tr>
            <th>编号</th>
            <th>书名</th>
            <th>作者</th>
            <th>价格</th>
            <th>修改</th>
            <th>删除</th>
        </tr>
        <!-- 使用ognl从map栈中获取东西 -->
        <s:iterator value="#request.booklist">
            <tr>
                <td><s:property value="bookId"/></td>
                <td><s:property value="bookName"/></td>
                <td><s:property value="author"/></td>
                <td><s:property value="price"/></td>
                <td><s:a action="modify?bookId=%{bookId}">修改</s:a></td>
                <!-- 通过使用%{}告诉框架按照ognl表达式解析 -->
                <td><s:a action="delete?bookId=%{bookId}">删除</s:a></td>
            </tr>
        </s:iterator>
    </table>
    </s:else>
    <h1 align="center"><a href="${pageContext.request.contextPath }/save.jsp">添加</a></h1>
</body>
</html>


这样一个简单的获取所有图书的流程就使用Struts框架实现了


CRUD全部功能代码:

                                                    index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center"><a href="${pageContext.request.contextPath }/booklist.action">获取所有图书</a></h1>
</body>
</html>

                                                  bookList.jsp
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!-- struts标签库不能使用EL表达式,要使用ognl式子(#表示map集合)
        之前将所有图书放到了map栈中
     -->
    <s:if test="#request.booklist == null || #request.booklist.empty">
        <h1 align="center">没有图书,快去购物吧!</h1>
    </s:if>
    <s:else>
    <h1 align="center">图书列表</h1>
    <table border="1" width="80%" align="center">
        <tr>
            <th>编号</th>
            <th>书名</th>
            <th>作者</th>
            <th>价格</th>
            <th>修改</th>
            <th>删除</th>
        </tr>
        <!-- 使用ognl从map栈中获取东西 -->
        <s:iterator value="#request.booklist">
            <tr>
                <td><s:property value="bookId"/></td>
                <td><s:property value="bookName"/></td>
                <td><s:property value="author"/></td>
                <td><s:property value="price"/></td>
                <td><s:a action="modify?bookId=%{bookId}">修改</s:a></td>
                <!-- 通过使用%{}告诉框架按照ognl表达式解析 -->
                <td><s:a action="delete?bookId=%{bookId}">删除</s:a></td>
            </tr>
        </s:iterator>
    </table>
    </s:else>
    <h1 align="center"><a href="${pageContext.request.contextPath }/save.jsp">添加</a></h1>
</body>
</html>
                                                    save.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags"  prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center">添加图书</h1>
    <!-- struts表单标签 -->
    <s:form action="/saveBook">
        <s:textfield name="bookName" label="书名"/>
        <s:textfield name="author" label="作者"/>
        <s:textfield name="price" label="价格"/>
        <s:submit value="保存" />
    </s:form>
</body>
</html>
                                                                                                    
                                               modify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center">修改图书</h1>
    <!-- struts表单标签 -->
    <s:form action="/domodifyBook">
        <s:hidden name="bookId"/>
        <s:textfield name="bookName" label="书名"/>
        <s:textfield name="author" label="作者"/>
        <s:textfield name="price" label="价格"/>
        <s:submit value="修改" />
    </s:form>
</body>
</html>

                                                 struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">

<!--        <action name="test" class="com.atguigu.test.Test" method="test"> -->
<!--            <result>/success.jsp</result> -->
<!--        </action> -->
        <!-- 配置获取所有图书的action -->
        <action name="booklist" class="com.atguigu.action.BookAction" method="bookList">
            <result name="booklist">/bookList.jsp</result>
        </action>
        <!-- 需要重定向到图书列表,需要转到一个action -->
        <action name="saveBook" class="com.atguigu.action.BookAction" method="saveBook">
            <!-- 需要重定向到图书列表 -->
            <result name="booklist" type="redirectAction">
                <param name="actionName">booklist</param>
                <param name="namespace">/</param>
            </result>
        </action>

        <action name="modify" class="com.atguigu.action.BookAction" method="modifyBook">
            <result name="modify">/modify.jsp</result>
        </action>

        <action name="domodifyBook" class="com.atguigu.action.BookAction" method="domodifyBook">
            <result name="booklist" type="redirectAction">
                <param name="actionName">booklist</param>
                <param name="namespace">/</param>
            </result>
        </action>
        <action name="delete" class="com.atguigu.action.BookAction" method="deleteBook">
            <result name="booklist" type="redirectAction">
                <param name="actionName">booklist</param>
                <param name="namespace">/</param>
            </result>
        </action>


    </package>
</struts>

                                       BookAction.java
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.RequestAware;

import com.atguigu.bean.Book;
import com.atguigu.dao.BookDao;
import com.opensymphony.xwork2.ActionContext;

/**
 * 用于处理有关图书请求的action
 * @author LENOVO
 *
 */
public class BookAction implements RequestAware {

    private BookDao bookDao = new BookDao();

    private String bookName;
    private String author;
    private double price;
    private Integer bookId;

    private Map<String, Object> request;

    public String bookList() {
        //获取所有图书
        List<Book> booklist = bookDao.getAllBook();
        //将图书放到request中(map栈)
        request.put("booklist", booklist);
        return "booklist";
    }
    /**
     * 保存图书,
     * 获取表单中的值
     *  ①声明属性
     *  ②提供set方法
     * @return
     */
    public String saveBook() {
        Book book = new Book(null, bookName, author, price);
        bookDao.saveBook(book);
        //System.out.println(book);
        return "booklist";
    }
    /**
     * 根据图书id删除图书
     * @return
     */
    public String deleteBook() {
        bookDao.deleteBook(bookId);
        return "booklist";
    }
    /**
     * 修改图书
     *  ①在表单处回显将要修改的图书
     *  ②保存修改
     * @return
     */
    public String modifyBook() {
        //现将根据id获取到的图书保存到对象栈中
        Book book = bookDao.getBook(bookId);
//      System.out.println(book);
        //压入对象栈
        ActionContext.getContext().getValueStack().push(book);
        return "modify";
    }
    /**
     * 修改图书
     * @return
     */
    public String domodifyBook() {
        Book book = new Book(bookId, bookName, author, price);
        bookDao.saveBook(book);
        return "booklist";
    }

    @Override
    public void setRequest(Map<String, Object> request) {
        this.request = request;
    }

    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }
}

 Struts2框架内部运行流程




                                                                       相关的几个 API
ActionMapping:Simple class that holds the action mapping information used to invoke a Struts action. The name and namespace are required
 
ActionMapper:When given an HttpServletRequest, the ActionMapper may return null if no action invocation request matches, or it may return an ActionMapping that describes an action invocation for the framework to try
 
ActionProxy:ActionProxy is an extra layer between XWork and the action so that different proxies are possible.
 
ActionInvocation:An ActionInvocation represents the execution state of an Action. It holds the Interceptors and the Action instance. By repeated re-entrant execution of the invoke() method, initially by the ActionProxy, then by the Interceptors, the Interceptors are all executed, and then the Action and the Result.
                                                                                                                    
                                                                                                           
                                                                   Struts2 运行流程分析

1. 请求发送给 StrutsPrepareAndExecuteFilter
2. StrutsPrepareAndExecuteFilter 询问 ActionMapper: 该请求是否是一个 Struts2 请求(即是否返回一个非空的 ActionMapping 对象)
3. 若 ActionMapper 认为该请求是一个 Struts2 请求,则 StrutsPrepareAndExecuteFilter 把请求的处理交给 ActionProxy
4. ActionProxy 通过 Configuration Manager 询问框架的配置文件,确定需要调用的 Action 类及 Action 方法
5. ActionProxy 创建一个 ActionInvocation 的实例,并进行初始化
6. ActionInvocation 实例在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
7. Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。调用结果的 execute 方法,渲染结果。在渲染的过程中可以使用Struts2 框架中的标签。
8. 执行各个拦截器 invocation.invoke() 之后的代码
9. 把结果发送到客户端

 
  
附录:Debug断点
      
 
      







猜你喜欢

转载自blog.csdn.net/wangligong/article/details/52917244