Struts2架构剖析

1、客户端向Servlet容器(如Tomcat)提交一个请求

2、请求经过一系列过滤器(如ActionContextCleanUp过滤器等)

3、核心控制器被调用,询问ActionMapper来决定请求是否需要调用某个Action

4、如果ActionMapper决定需要调用某个Action,核心控制器把控制权委派给ActionProxy (备注:JSP请求无需调用Action)

5、ActionProxy通过Configuration Manager询问框架的配置文件(struts.xml),找到需调用的Action类

6、ActionProxy创建一个ActionInvocation的实例

7、 ActionInvocation负责调用Action,在此之前会依次调用所有配置的拦截器

8、Action执行完毕,ActionInvocation负责根据结果码字符串在struts.xml的配置中找到对应的返回结果

9、拦截器被再次反向执行

10、过滤器被再次反向执行

拦截器

为什么需要拦截器?

早期MVC框架将一些通用操作写死在核心控制器中,致使框架灵活性不足、可扩展性降低

Struts 2将核心功能放到多个拦截器中实现,拦截器可自由选择和组合,增强了灵活性,有利于系统的解耦

拦截器的工作原理

拦截器的执行过程是一个递归的过程

自定义拦截器

实现Interceptor接口
void init():初始化拦截器所需资源
void destroy():释放在init()中分配的资源
String intercept(ActionInvocation ai) throws Exception
实现拦截器功能
利用ActionInvocation参数获取Action状态
返回结果码(result)字符串

继承AbstractInterceptor类
提供了init()和destroy()方法的空实现
只需要实现intercept方法即可

案例操作 :

案例架构

entity层:

UserInfo:

 public class UserInfo {
private String username;
private String password;
}

interceptor层

MyInterceptor:

 public class MyInterceptor implements Interceptor {
public void destroy() { } public void init() {
System.out.println("拦截器已成功初始化。。。。。");
} public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("对象"+invocation);
Object action = invocation.getAction();
System.out.println("action==========="+action);
String value;
//判定session里面key值对应的value是否存在
Map<String, Object> session = ActionContext.getContext().getSession();
Object name = session.get("username");
String actionName = invocation.getProxy().getActionName();
invocation.getProxy().getNamespace(); System.out.println("actionName==========="+actionName);
if (actionName.contains("userAction")){ //登录访问其他页面
value=invocation.invoke();
}else if(name!=null){
//已经登陆了 ,放行
value=invocation.invoke();
String method = invocation.getProxy().getMethod();
System.out.println("方法"+method);
}else {
value="login";
}
System.out.println("逻辑视图名"+value);
return value;
}
}

action:

UserAction:

 public class LoginAction implements Action,ModelDriven<UserInfo> {
private UserInfo userInfo=new UserInfo();
public String execute() throws Exception {
System.out.println(userInfo.getUsername()+"\t"+userInfo.getPassword());
Map<String, Object> session = ActionContext.getContext().getSession();
System.out.println("***************************************");
if (userInfo!=null){
if (userInfo.getUsername().equals("1") && userInfo.getPassword().equals("1")) {
System.out.println("===================");
session.put("username", userInfo.getUsername());
return SUCCESS;
}else {
return LOGIN;
}
}else {
if (session!=null&&session.get("username")!=null){
return "success";
}else {
System.out.println("Action的自定义代码");
return "login";
}
}
} public UserInfo getUserInfo() {
return userInfo;
} public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
} public UserInfo getModel() {
return userInfo;
}
}

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"></constant> <package name="default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="myInter" class="cn.happy.day08interceptor.interceptor.MyInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myInter"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"></default-interceptor-ref>
</package>
<!--植入多个struts.xml文件-->
<include file="struts-day08.xml"></include>
</struts>

struts-day08.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"></constant> <package name="day08" namespace="/" extends="default">
<action name="userAction" class="cn.happy.day08interceptor.action.LoginAction" method="execute">
<result name="success">/day08/success.jsp</result>
<result name="login">/day08/login.jsp</result>
</action>
<action name="book">
<result name=""></result>
</action>
</package> </struts>

login.jsp

 <%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<s:form name="form1" namespace="/" method="POST" action="userAction">
用户名:<s:textfield name="username"></s:textfield><br/>
密码:<s:password name="password"></s:password><br/>
<s:submit value="登录"></s:submit>
</s:form>
</body>
</html>

success.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>添加成功</h1>
</body>
</html>

Struts2深入的更多相关文章

  1. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  2. 菜鸟学Struts2——Interceptors

    昨天学习Struts2的Convention plugin,今天利用Convention plugin进行Interceptor学习,虽然是使用Convention plugin进行零配置开发,这只是 ...

  3. 菜鸟学Struts2——零配置(Convention )

    又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Conv ...

  4. 菜鸟学Struts2——Results

    在对Struts2的Action学习之后,对Struts2的Result进行学习.主要对Struts2文档Guides中的Results分支进行学习,如下图: 1.Result Types(Resul ...

  5. 菜鸟学Struts2——Actions

    在对Struts2的工作原理学习之后,对Struts2的Action进行学习.主要对Struts2文档Guides中的Action分支进行学习,如下图: 1.Model Driven(模型驱动) St ...

  6. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  7. 13、零配置Struts2开发

    Convention 插件 从 Struts 2.1 开始, Struts 可以使用 Convention 插件来支持零配置: Convention 插件完全抛弃配置信息, 不仅不需要使用 strut ...

  8. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  9. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

  10. 9、 Struts2验证(声明式验证、自定义验证器)

    1. 什么是Struts2 验证器 一个健壮的 web 应用程序必须确保用户输入是合法.有效的. Struts2 的输入验证 基于 XWork Validation Framework 的声明式验证: ...

随机推荐

  1. Notepad++ 的函数参数提示错误的问题终于解决了

    看第3张图片,明明我输入的是 print_double(), 提示的却是 print() 函数的参数. 这个问题困扰了我半年,今天晚上找到解决问题的办法:

  2. 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)

    一. 基本介绍 回忆: 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候,发现where方法里的参数是Expression<Func<T,bool> ...

  3. [物理学与PDEs]第3章第2节 磁流体力学方程组 2.3 磁流体力学方程组

    1.  磁流体力学方程组 $$\beex \bea \cfrac{\p {\bf H}}{\p t} &-\rot({\bf u}\times{\bf H})=\cfrac{1}{\sigma ...

  4. [物理学与PDEs]第1章第8节 静电场和静磁场 8.3 静磁场

    1. 静磁场: 由稳定电流形成的磁场. 2. 此时, Maxwell 方程组为 $$\beex \bea \Div{\bf D}&=\rho_f,\\ \rot {\bf E}&={\ ...

  5. Coroutine的原理以及实现

    最近在写WinForm,在UI界面需要用到异步的操作,比如加载数据的同时刷系进度条,WinForm提供了不少多线程的操作, 但是多线程里,无法直接修改主线程里添加的UI的get/set属性访问器(可以 ...

  6. js 数字前自动补零

    num为传入的数字,n为需要的字符长度 return (Array(n).join(0) + num).slice(-n); 例如 我想返回两位数  输入6 然后返回06 就可以这样写: return ...

  7. C++中数组作为形参进行传递(转)

    有两种传递方法,一种是function(int a[]); 另一种是function(int *a) 这两种两种方法在函数中对数组参数的修改都会影响到实参本身的值! 对于第一种,根据之前所学,形参是实 ...

  8. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field 数学

    题目链接 题意:给你三个数n,m,k;让你构造出一个nm的矩阵,矩阵元素只有两个值(1,-1),且满足每行每列的乘积为k,问你多少个矩阵. 解法:首先,如果n,m奇偶不同,且k=-1时,必然无解: 设 ...

  9. excel合并

    import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; impor ...

  10. Ubuntu里设置python默认版本为python3(转载)

    0 - 步骤 在命令行中执行下述命令: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 sudo ...