简单模拟struts2核心控制器利用反射原理实现参数传递和物理视图跳转
在能够运用struts2框架进行简单网站开发后,对struts2的一些较原框架强大的功能希望有更深刻的理解,于是尝试从底层开始摸索,本文就在重新学习struts2后,利用简单代码对核心控制器的主要功能进行理解。
首先,介绍一下strut2的处理流程:
1、浏览器发出请求,即***.action
2、请求被核心控制器的StrutsPrepareAndExecuteFilter拦截
3、搜索struts.xml配置文件,寻找Action的属性name为***的配置信息,而后根据class属性,通过反射原理创建Action实例
actionInst
4、调用request.getParameterNames返回所有的请求参数名存入paramMap
使用循环(String paramName : paramMap.keySet())//传入所有参数
{
//1、得到请求参数名对应的set方法
Method setter = Action类.getMethod("set"+paramName的首字母大写)
//2、获得参数名对应的参数值
String paramValue = paramMap.get(paramName)
//3、以Action实例为调用者,调用setter方法,把参数值作为参数传入
setter.invoke(actionInst , paramValue)
}
5、再次通过反射来调用method属性所指定的方法,返回一个字符串
6、根据字符串匹配struts.xml中<result>元素的属性name值,进行相对应物理视图的跳转
/**************附模拟核心控制器代码********************************/
//自定义的Action类==========
1 class MyAction{ 2 //待传值的参数 3 private String name ; 4 private String pass; 5 6 //空构造函数 7 public MyAction() { 8 } 9 10 public MyAction(String name, String pass) { 11 this.name = name; 12 this.pass = pass; 13 } 14 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public String getPass() { 24 return pass; 25 } 26 27 public void setPass(String pass) { 28 this.pass = pass; 29 } 30 31 public String regist(){ 32 System.out.println("name----->"+name); 33 System.out.println("pass----->"+pass); 34 return "sucess"; 35 } 36 }
//核心控制器==============
1 public class CoreFilter { 2 3 4 //模拟配置文件struts.xml 5 /** 6 <action name = "abc" class = "MyAcion" method = "regist"> 7 <result name = "success">********.jsp</result> 8 ...... 9 </action> 10 **/ 11 public static void main(String[] args) throws Exception { 12 //假如控制器收到abc.action请求,通过解析structs.xml 13 String classProp = "MyAction"; 14 15 //反射原理:获取action类所对应的Class对象 16 Class actionClazz = Class.forName("test.MyAction"); 17 18 //利用Class对象得到类实例 19 Object actionInst = actionClazz.newInstance(); //此处要求action含有无参构造函数的原因 20 21 //利用Map来模拟请求参数 22 // struct2的核心Filter用下面的代码。得到所有的请求<参数名--参数值>,组成Map 23 //Map<String , String > paramMap = request.getParamMap(); 24 //相当于如下模拟过程: 25 Map <String,String> paramMap = new HashMap<String, String>(); 26 paramMap.put("name","张三"); 27 paramMap.put("pass","123"); 28 for(String paramName : paramMap.keySet()){ 29 //得到请求参数名对应的setter方法 30 //setName() and setPass() 31 Method setter = actionClazz.getMethod("set" 32 +paramName.substring(0,1).toUpperCase() 33 +paramName.substring(1),String.class); 34 35 //得到请求参数对应的值 36 String paramValue = paramMap.get(paramName); 37 38 //以Action实例为调用者,调用setter方法,吧参数值作为参数传入 39 setter.invoke(actionInst,paramValue);//主调者actionInst,参数值为paramValue 40 } 41 Method targetMethod = actionClazz.getMethod("regist"); 42 String result = (String)targetMethod.invoke(actionInst); 43 44 if(result.equals("某个result的name属性值")){ 45 //request.getRequestDispatcher().forward() 46 } 47 }
}
//执行结果