1. 程式人生 > >[Java Web] Struts 2

[Java Web] Struts 2

nds actions pattern htm 截器 相關配置 視圖 動態方法調用 協助

一、簡述

MVC全名Model View Controller,是一種將業務邏輯、數據和界面顯示分離的方法。

Struts是一個基於MVC模式設計的Web應用框架,其各層結構功能如下:

  1. 模型(Model):負責管理應用程序的數據,通過響應視圖的請求和控制器的指令來更新數據。
  2. 視圖(View):用於應用程序中處理數據的顯示。是與用戶的交互頁面,負責接收用戶的輸入信息,並將處理後的數據顯示。
  3. 控制器(Controller):負責接收用戶的請求和數據,並判斷應當將請求交由什麽模型來處理已經處理後的數據由什麽視圖來顯示。

Struts 2的請求執行流程如下:

  1. 客戶端發送的請求通過StrutsPrepareAndExecuteFilter過濾器。
  2. Action映射器查詢對應的Action對象並返回Action對象的代理,代理從配置文件讀取相關配置並經過一系列攔截器後調用指定Action對象。
  3. 當Action處理請求完成後,將響應的處理結果在視圖層上顯示。在視圖層通過映射類型變量或Struts標簽顯示數據,最後將HTTP響應返回給瀏覽器。

二、控制器

Action是Struts 2框架的核心。每個URL映射到特定的Action上,後者提供對用戶的請求進行處理所需的邏輯。

Action的兩個重要功能分別是將數據從請求傳遞到視圖和協助框架確定什麽結果應該呈現在視圖中。

Action提供了部分處理結果的預定義字符串變量:

靜態變量 說明
ERROR Action執行失敗的返回值,如驗證信息錯誤。
INPUT 返回某個輸入信息頁面的返回值,如修改信息頁面。
LOGIN 需要用戶登陸的返回值,如登陸驗證失敗需要重新登陸。
NONE Action執行成功的返回值,不返回到成功頁面。
SUCCESS Action執行成功的返回值,返回到成功頁面。

ActionSupport類實現了Action接口,創建控制器時一般需要繼承該類。

用戶提交表單後信息會自動註入到與Action對象響應的屬性中,前提是在Action類中必須提供屬性的setter方法。

技術分享圖片
//MessageAction.java
package action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import java.util.Map;

public class MessageAction extends ActionSupport {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String execute() throws Exception {
        Map
<String, Object> session = ActionContext.getContext().getSession(); session.put("message", message); return (message == null || message.isEmpty()) ? ActionSupport.ERROR : ActionSupport.SUCCESS; } } //index.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <form action="MessageAction.action" method="post"> <input type="text" name="message" id="message" placeholder="輸入文本"/> <input type="submit" value="提交"/> </form> <c:if test="${sessionScope.message != null && !sessionScope.message.isEmpty()}"> <c:out value="文本:${sessionScope.message}"/> </c:if> </body> </html> //struts.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <!-- namespace決定了Action的訪問路徑 --> <package name="action" namespace="/" extends="struts-default"> <action name="MessageAction" class="action.MessageAction"> <result name="error">/index.jsp</result> <result name="success">/index.jsp</result> </action> </package> </struts> //web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
View Code

三、動態方法調用

動態方法調用是為了讓Action對應多個請求處理,以避免Action的數量太多。

1.感嘆號方式是在請求Action的URL地址後加上請求字符串(方法名),與Action對象中的方法進行匹配。URL與請求字符串之間以感嘆號進行分隔,該方式一般不推薦使用。

技術分享圖片
//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
<a href="OperateAction!insert.action">添加</a>
<a href="OperateAction!delete.action">刪除</a>
<a href="OperateAction!update.action">更新</a>
<a href="OperateAction!select.action">查詢</a>

<c:if test="${sessionScope.operate ne null}">
    <c:out value="操作:${sessionScope.operate}"/>
</c:if>
</body>
</html>




//OperateAction.java
package action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import java.util.Map;

public class OperateAction extends ActionSupport {
    private String setAttribute(String operate) {
        Map<String, Object> session = ActionContext.getContext().getSession();
        session.put("operate", operate);
        return operate;
    }

    public String insert() {
        return setAttribute("insert");
    }

    public String delete() {
        return setAttribute("delete");
    }

    public String update() {
        return setAttribute("update");
    }

    public String select() {
        return setAttribute("select");
    }
}




//struts.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
    <!-- Struts 2.5後調用動態方法需要關閉strict-method-invocation -->
    <package name="action" namespace="/" extends="struts-default" strict-method-invocation="false">
        <action name="OperateAction" class="action.OperateAction">
            <result name="select">/index.jsp</result>
            <result name="delete">/index.jsp</result>
            <result name="update">/index.jsp</result>
            <result name="insert">/index.jsp</result>
        </action>
    </package>
</struts>
View Code

2.用戶發送Action請求時,在默認情況下執行execute方法。但在多個業務邏輯分支的Action對象中,需要通過指定<action>標簽中的method屬性,從而調用對應的邏輯方法進行處理。

技術分享圖片
//OperateAction.java
package action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import java.util.Map;

public class OperateAction extends ActionSupport {
    private void setAttribute(String operate) {
        Map<String, Object> session = ActionContext.getContext().getSession();
        session.put("operate", operate);
    }

    public String insert() {
        setAttribute("insert");
        return ActionSupport.SUCCESS;
    }

    public String delete() {
        setAttribute("delete");
        return ActionSupport.SUCCESS;
    }

    public String update() {
        setAttribute("update");
        return ActionSupport.SUCCESS;
    }

    public String select() {
        setAttribute("select");
        return ActionSupport.SUCCESS;
    }
}



//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
<a href="insertAction.action">添加</a>
<a href="deleteAction.action">刪除</a>
<a href="updateAction.action">更新</a>
<a href="selectAction.action">查詢</a>

<c:if test="${sessionScope.operate ne null}">
    <c:out value="操作:${sessionScope.operate}"/>
</c:if>

</body>
</html>


//struts.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
    <package name="action" namespace="/" extends="struts-default" strict-method-invocation="false">
        <action name="insertAction" class="action.OperateAction" method="insert">
            <result name="success">/index.jsp</result>
        </action>
        <action name="deleteAction" class="action.OperateAction" method="delete">
            <result name="success">/index.jsp</result>
        </action>
        <action name="updateAction" class="action.OperateAction" method="update">
            <result name="success">/index.jsp</result>
        </action>
        <action name="selectAction" class="action.OperateAction" method="select">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>
View Code

3.在配置文件struts.xml中支持使用通配符,達到簡化配置代碼的效果。是動態方法調用中最常用的一種方式。

技術分享圖片
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
    <package name="action" namespace="/" extends="struts-default" strict-method-invocation="false">
        <action name="*Action" class="action.OperateAction" method="{1}">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>
View Code

四、映射類型

在Web項目配置Struts 2框架,使用Action對象處理用戶的請求。這時一般通過ActionContext對象獲取映射類型的request、session和application變量,用於保存處理後的信息。

技術分享圖片
//SetAction.java
package action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import java.util.Map;

public class SetAction extends ActionSupport {
    @Override
    @SuppressWarnings("unchecked")
    public String execute() throws Exception {
        ActionContext context = ActionContext.getContext();
        Map<String, Object> request = (Map<String, Object>) context.get("request");
        Map<String, Object> session = context.getSession();
        Map<String, Object> application = context.getApplication();

        request.put("requestValue", 0);
        session.put("sessionValue", 1);
        application.put("applicationValue", 2);

        return ActionSupport.SUCCESS;
    }
}



//struts.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <package name="action" namespace="/" extends="struts-default">
        <action name="setAction" class="action.SetAction">
            <result>/index.jsp</result>
        </action>
    </package>
</struts>



//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
<a href="setAction.action">獲取</a>

<c:if test="${requestScope.requestValue ne null}">
    <c:out value="Request Value =  ${requestScope.requestValue}"/>
</c:if>
<c:if test="${sessionScope.sessionValue ne null}">
    <c:out value="Session Value =  ${sessionScope.sessionValue}"/>
</c:if>
<c:if test="${applicationScope.applicationValue ne null}">
    <c:out value="Application Value = ${applicationScope.applicationValue}"/>
</c:if>
</body>
</html>
View Code

[Java Web] Struts 2