FilterDispatcher是struts2.0.x到2.1.2版本的核心过滤器.!
StrutsPrepareAndExecuteFilter是自2.1.3开始就替代了FilterDispatcher的.!
01.Struts 2架构剖析 /执行流程
配置
流程文解:
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、过滤器被再次执行
02.Struts 2核心接口和类
03.为什么需要拦截器
早期MVC框架将一些通用操作写死在核心控制器中,致使框架灵活性不足、可扩展性降低 Struts 2将核心功能放到多个拦截器中实现,拦截器可自由选择和组合,增强了灵活性,有利于系统的解耦
Mvc和三层的区别?
解析:MVC是表示层的三个组件。核心用途: 将请求和展示分离。
三层侧重的是架构层面的一个流程组件封装。
04.什么是拦截器
拦截对Action请求的一个类。
实现Interceptor接口。继承AbstractInterceptor类
Struts 2大多数核心功能是通过拦截器实现的,每个拦截器完成某项功能
拦截器方法在Action执行之前或者之后执行
拦截器栈
从结构上看,拦截器栈相当于多个拦截器的组合
在功能上看,拦截器栈也是拦截器
拦截器与过滤器原理很相似
提到拦截器,使我不得不想起武侠剧中劫匪们常说的一句话:“此山是我开,此树是我栽,要打此路过,留下买路财!”。难不成程序中也有“打劫”的,说的没错,拦截器就是个打劫的。在现实生活中,劫匪劫的大都是钱财,当然也有别的什么,那么程序中的“劫匪”劫的又是什么呢?或者说程序中为什么需要它?在我们的日常编程中少不了写一些重复的代码,例如在一个地方中写了一段代码,后来发现这段代码在其它地方中同样需要,在传统的编程中我们一定会采取复制、粘贴的办法。如果这段代码只在这一两个处需要,我们采取这种办法,还说的过去,但是如果系统对这段代码过于依赖,也就是这段代码在系统中出现的过多,如果那一天我们发现这段代码中在某些地方还需要完善,我们是不是要着个修改它们呢?我估计没有人会这么做,它严重违反了软件开发中一条非常重要的DRY规则,不写重复代码。说了这么多你一定知道我们为什么需要在程序中弄一个“劫匪”了吧。这个“劫匪”就是并不是劫取什么东西,只是为了在某个程序执行前后,动态的增加一些功能(以前所写通用代码块)或进行一些检查工作。那么这个拦截器到底是怎么实现的呢?实际上它是用Java中的动态代理来实现的。
06.拦截器工作原理
拦截器的执行过程是一个递归的过程
三阶段执行周期:
1、做一些Action执行前的预处理
2、将控制交给后续拦截器或返回结果字符串
3、做一些Action执行后的处理
07.自定义拦截器
实体:
自定义拦截器类:
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);
//获取Action类
Object action = invocation.getAction();
System.out.println(action);
String value;
//获取Session 判断里面key值对应的value是否存在
Map<String, Object> session = ActionContext.getContext().getSession();
Object username = session.get("username");
//找到需要的Action
String actionName = invocation.getProxy().getActionName();
invocation.getProxy().getNamespace();
System.out.println(actionName);
if (actionName.equals("LoginActions")){
//将action
value=invocation.invoke();
}else if (username!=null){
//已经登陆
value=invocation.invoke();
String method = invocation.getProxy().getMethod();
System.out.println("方法"+method);
}else {
value="login";
}
System.out.println("逻辑视图名"+value);
return value;
}
}
Action:
public class LoginAction implements Action,ModelDriven<Userinfo> {
private Userinfo userinfo=new Userinfo();
public String execute() throws Exception {
Map<String, Object> session = ActionContext.getContext().getSession();
if (userinfo!=null){
if (userinfo.getUsername().equals("1")&&userinfo.getUserpassword().equals("1")){
//记录session
session.put("username",userinfo.getUsername());
System.out.println("Action的"+userinfo.getUsername());
return SUCCESS;
}else {
return LOGIN;
}
}else if (session!=null&&session.get("username")!=null){
System.out.println("Action的"+session.get("username"));
return SUCCESS;
}else {
return LOGIN;
}
}
public Userinfo getUserinfo() {
return userinfo;
}
public void setUserinfo(Userinfo userinfo) {
this.userinfo = userinfo;
}
public Userinfo getModel() {
return userinfo;
}
}
Struts.xml:
<!--自定义拦截器-->
<interceptors>
<!--指定自定义拦截器-->
<interceptor name="MyInterceptor" class="cn.happy.day04.interceptor.MyInterceptor"></interceptor>
<!-- Basic stack -->
<interceptor-stack name="MyStack">
<!--先走一次struts的拦截器-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="MyInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="MyStack"/>
<default-action-ref name="index"></default-action-ref>
<action name="index">
<result>day04/login.jsp</result>
</action>
Struts-Login.xml:
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>
</web-app>
<action name="LoginActions" class="cn.happy.day04.LoginAction">
<result name="success">/day04/SUCCESS.jsp</result>
<result name="login">/day04/login.jsp</result>
</action>