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:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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; } }
UserInfo:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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;
}
}
UserInterceptor:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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";
}
}
struts.xml:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<?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>
login.jsp:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ 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>
success.jsp:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Success</title>
</head>
<body>
<h2>Success</h2>
</body>
</html>
web.xml:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<!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>
Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear.
面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!