分享知识-快乐自己: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 Info = new UserInfo();

    public UserInfo getInfo() {
        return Info;
    }

    public void setInfo(UserInfo info) {
        Info = info;
    }

    public String loginAction() {
        Map<String, Object> session = ActionContext.getContext().getSession();
        Map<String, Object> context = ActionContext.getContext().getValueStack().getContext();
        try {
            //再次访问登陆页面的时候判断是否已经登陆了
            UserInfo userInfo = (UserInfo) session.get("userInfo");
            if (userInfo != null) {
                System.out.println("已登陆");
                return "success";
            }
            if (!("admin".equals(Info.getUserName()))) {
                context.put("errorName", "用户名错误");
            } else if (!("admin".equals(Info.getUserPwd()))) {
                context.put("errorPwd", "密码错误");
            } else {
                System.out.println("Info:"+Info.getUserName());
                session.put("userInfo", Info);
                return "success";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "input";
    }

    public String success() {
        return SUCCESS;
    }


    @Override
    public UserInfo getModel() {
        return Info;
    }
}
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.

面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!

posted @ 2018-11-20 14:58  GDBD  阅读(422)  评论(0编辑  收藏  举报