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:
1 public class UserInfo { 2 private String username; 3 private String password; 4 }
interceptor层
MyInterceptor:
1 public class MyInterceptor implements Interceptor { 2 public void destroy() { 3 4 } 5 6 public void init() { 7 System.out.println("拦截器已成功初始化。。。。。"); 8 } 9 10 public String intercept(ActionInvocation invocation) throws Exception { 11 System.out.println("对象"+invocation); 12 Object action = invocation.getAction(); 13 System.out.println("action==========="+action); 14 String value; 15 //判定session里面key值对应的value是否存在 16 Map<String, Object> session = ActionContext.getContext().getSession(); 17 Object name = session.get("username"); 18 String actionName = invocation.getProxy().getActionName(); 19 invocation.getProxy().getNamespace(); 20 21 System.out.println("actionName==========="+actionName); 22 if (actionName.contains("userAction")){ //登录访问其他页面 23 value=invocation.invoke(); 24 }else if(name!=null){ 25 //已经登陆了 ,放行 26 value=invocation.invoke(); 27 String method = invocation.getProxy().getMethod(); 28 System.out.println("方法"+method); 29 }else { 30 value="login"; 31 } 32 System.out.println("逻辑视图名"+value); 33 return value; 34 } 35 }
action:
UserAction:
1 public class LoginAction implements Action,ModelDriven<UserInfo> { 2 private UserInfo userInfo=new UserInfo(); 3 public String execute() throws Exception { 4 System.out.println(userInfo.getUsername()+" "+userInfo.getPassword()); 5 Map<String, Object> session = ActionContext.getContext().getSession(); 6 System.out.println("***************************************"); 7 if (userInfo!=null){ 8 if (userInfo.getUsername().equals("1") && userInfo.getPassword().equals("1")) { 9 System.out.println("==================="); 10 session.put("username", userInfo.getUsername()); 11 return SUCCESS; 12 }else { 13 return LOGIN; 14 } 15 }else { 16 if (session!=null&&session.get("username")!=null){ 17 return "success"; 18 }else { 19 System.out.println("Action的自定义代码"); 20 return "login"; 21 } 22 } 23 } 24 25 public UserInfo getUserInfo() { 26 return userInfo; 27 } 28 29 public void setUserInfo(UserInfo userInfo) { 30 this.userInfo = userInfo; 31 } 32 33 public UserInfo getModel() { 34 return userInfo; 35 } 36 }
struts.xml:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 6 <struts> 7 <constant name="struts.devMode" value="true"></constant> 8 9 <package name="default" namespace="/" extends="struts-default"> 10 <interceptors> 11 <interceptor name="myInter" class="cn.happy.day08interceptor.interceptor.MyInterceptor"></interceptor> 12 <interceptor-stack name="myStack"> 13 <interceptor-ref name="defaultStack"></interceptor-ref> 14 <interceptor-ref name="myInter"></interceptor-ref> 15 </interceptor-stack> 16 </interceptors> 17 <default-interceptor-ref name="myStack"></default-interceptor-ref> 18 </package> 19 <!--植入多个struts.xml文件--> 20 <include file="struts-day08.xml"></include> 21 </struts>
struts-day08.xml:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 6 <struts> 7 <constant name="struts.devMode" value="true"></constant> 8 9 <package name="day08" namespace="/" extends="default"> 10 <action name="userAction" class="cn.happy.day08interceptor.action.LoginAction" method="execute"> 11 <result name="success">/day08/success.jsp</result> 12 <result name="login">/day08/login.jsp</result> 13 </action> 14 <action name="book"> 15 <result name=""></result> 16 </action> 17 </package> 18 19 </struts>
login.jsp
1 <%@ taglib prefix="s" uri="/struts-tags" %> 2 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 <html> 4 <head> 5 <title>Title</title> 6 </head> 7 <body> 8 <s:form name="form1" namespace="/" method="POST" action="userAction"> 9 用户名:<s:textfield name="username"></s:textfield><br/> 10 密码:<s:password name="password"></s:password><br/> 11 <s:submit value="登录"></s:submit> 12 </s:form> 13 </body> 14 </html>
success.jsp
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>Title</title> 5 </head> 6 <body> 7 <h1>添加成功</h1> 8 </body> 9 </html>