分享知識-快樂自己:Struts2框架 工作原理及執行流程圖(攔截器的使用)
Struts2 架構圖:
1):提交請求
客戶端通過 HttpServletRequest 向 Servlet (即Tomcat)提交一個請求。
請求經過一系列的過濾器,例如圖中的 ActionContextCleanUp 和 Other filer (SlterMesh,etc)等,最後被 Struts 的核心過濾器 FilterDispatcher 控制到。
注:核心控制器 2.1.3 版本之後 Struts FileterDispatcher 核心控制器變成了 StrutsPrepareAndExcuteFilte
下圖所示:
被核心控制器控制到 才會訪問 ActionMapper 來決定是否呼叫某個 action (即使用者是否要求某個action)。
如果是其他資源請求例如 jsp 頁面,不會用到 action。
2):移交控制權
如果要用 action ,核心控制器將控制權 給 ActionProxy (即是 action 的代理)。
ActionProxy 獲得控制權之後通過 ConfigurationManager 物件載入核心配置檔案 struts.xml。
Struts 的 action 在這個配置檔案進行配置 , 所以要載入它。
3):建立 ActionInvocation 的例項
如果在 struts.xml 找到需要呼叫的action ,ActionProxy 會建立一個 ActionInvocation 的例項。
4):呼叫 action 錢的攔截器
攔截器是 struts2 非常重要的概念,是核心功能實現,Struts 中的大部分功能通過攔截器實現。
Actioninvocation 包括建立的 action 例項,同時包括另外非常重要的一部分====攔截器。
呼叫 action 前後還會呼叫很多的攔截器
在呼叫 action 之前會依此呼叫使用者所定義的攔截器。
5):呼叫 action 的業務方法進行業務處理
當把 action 前的攔截器執行完之後才會呼叫 action 的業務方法進行業務處理,
然後返回一個 Result (業務方法對應 String 型別的返回值,即使字串,例如 SUCCESS,INPUT,REEOR,NONE,LOGIN 和使用者自己在 Struts 對應定義 result標籤name屬性的值)。
6):匹配 result
然後根據返回的字串來排程我們的試圖來匹配我們的 struts.xml 中對應 action 標籤中的result 標籤。
一般來說返回一個 jsp 頁面,或者呼叫另某一個 action
7):反向執行攔截器
當返回檢視之後並沒有真正響應使用者,還需要把執行過的攔截器倒過來反向執行一遍。
8):響應客戶端
當這些攔截器被反向執行後,通過 HttpServletResponse 響應客戶端的請求。
簡單實現 登陸 驗證:點我下載原始碼
訪問路徑:沒有登陸直接訪問 localhost:8080/success 主頁面的時候會跳轉到登入頁
目錄結構:
UserAction:
package com.gdbd.action;
import com.gdbd.bean.UserInfo;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import java.util.Map;
/**
* @author asus
*/
public class UserAction extends ActionSupport implements ModelDriven<UserInfo> {
private UserInfo userInfo = new UserInfo();
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
public String loginAction() {
Map<String, Object> session = ActionContext.getContext().getSession();
Map<String, Object> context = ActionContext.getContext().getValueStack().getContext();
try {
//再次訪問登陸頁面的時候判斷是否已經登陸了
UserInfo userInfo = (UserInfo) context.get("userInfo");
if (userInfo != null) {
return "success";
}
if (!("admin".equals(userInfo.getUserName()))) {
context.put("errorName", "使用者名稱錯誤");
} else if (!("admin".equals(userInfo.getUserPwd()))) {
context.put("errorPwd", "密碼錯誤");
} else {
session.put("userInfo", userInfo);
return "success";
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "input";
}
public String success() {
return SUCCESS;
}
@Override
public UserInfo getModel() {
return userInfo;
}
}
View Code
UserInfo:
package com.gdbd.bean;
import java.io.Serializable;
/**
* user 實體類
* @author asus
*/
public class UserInfo implements Serializable {
private String userName;
private String userPwd;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
View Code
UserInterceptor:
package com.gdbd.util;
import com.gdbd.bean.UserInfo;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import java.util.Map;
/**
* @author asus
*/
public class UserInterceptor implements Interceptor {
@Override
public void destroy() {
System.out.println("===============銷燬==================");
}
@Override
public void init() {
System.out.println("===============初始化==================");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("=======進入攔截器=======");
System.out.println(invocation.getProxy().getActionName()+"======");
Map<String, Object> session = invocation.getInvocationContext().getSession();
UserInfo userInfo = (UserInfo) session.get("userInfo");
if (userInfo != null) {
String invoke = invocation.invoke();
System.out.println("===========" + invoke);
return invoke;
}
return "input";
}
}
View Code
struts.xml:
<?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>
<!--全域性配置:修改預設的日期提示資訊-->
<!--<constant name="struts.i18n.encoding" value="UTF-8"/>-->
<!--<constant name="struts.custom.i18n.resources" value="message"></constant>-->
<package name="user" namespace="/user" extends="struts-default">
<!--定義攔截器-->
<interceptors>
<!--自定義的攔截器-->
<interceptor name="author" class="com.mlq.uitl.AuthorizationInterceptor"></interceptor>
<!--定義攔截器棧-->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="author"/>
</interceptor-stack>
</interceptors>
<!--<default-interceptor-ref name="myStack"></default-interceptor-ref>-->
<!--沒有找到頁面預設顯示(故意把路徑寫錯可以測試效果)-->
<default-action-ref name="defaultAction"/>
<!--定義一個全域性結果-->
<global-results>
<result name="input">/fail.jsp</result>
</global-results>
<action name="defaultAction">
<result>/error.jsp</result>
</action>
<action name="login" class="com.mlq.action.LoginegisterRActionG" method="login">
<result type="redirectAction">${message}</result>
<result name="input">/login.jsp</result>
</action>
<action name="suc">
<result name="success">/success.jsp</result>
<result name="input">/login.jsp</result>
<interceptor-ref name="myStack"/>
</action>
</package>
</struts>
View Code
login.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登入</title>
</head>
<body>
<h2>登入</h2>
<s:debug/>
<s:form method="post" action="login">
<s:textfield label="請輸入使用者名稱" name="userName"></s:textfield>
<s:password label="請輸入密碼" name="userPwd"></s:password>
<s:property value="#errorName"/><s:property value="#errorPwd"/>
<s:submit value="登陸"></s:submit>
</s:form>
</body>
</html>
View Code
success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Success</title>
</head>
<body>
<h2>Success</h2>
</body>
</html>
View Code
web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--核心控制器-->
<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>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
View Code
Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear.
面對過去無怨無悔,把握現在充滿信心,備戰未來無所畏懼。保持信念,克服恐懼!一點一滴的積累,一點一滴的沉澱,學技術需要不斷的積澱!