package com.zzk.coding2017.zuoye_2.litestruts;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Struts {
public static View runAction(String actionName,
Map<String, String> parameters) {
View v = new View();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db
.parse("src/com/zzk/coding2017/zuoye_2/litestruts/struts.xml");
Element element = document.getDocumentElement();
NodeList actionList = element.getElementsByTagName("action");// 取得所有的action节点
for (int i = 0; i < actionList.getLength(); i++) {// 遍历所有的actin节点,寻找是否存在名为actionName的节点
Element e = (Element) actionList.item(i);
String name = e.getAttribute("name");
if (name.equals(actionName)) {// 找到对应的类,给类的属性赋值并调用execute函数执行
try {
String cname = e.getAttribute("class");
Class C = Class.forName(cname);
Object o = C.newInstance();
Method m1 = C.getDeclaredMethod("execute");
// 取得所有的getter和setter方法
Method[] methods = C.getMethods();
Hashtable<String, Method> getMethods = new Hashtable<>();
Hashtable<String, Method> setMethods = new Hashtable<>();
// 定义正则表达式,从方法中过滤出getter / setter 函数.
String gs = "get(\\w+)";
Pattern getM = Pattern.compile(gs);
String ss = "set(\\w+)";
Pattern setM = Pattern.compile(ss);
// 把方法中的"set" 或者 "get" 去掉
String rapl = "$1";
String param;
for (int k = 0; k < methods.length; ++k) {
Method m = methods[k];
String methodName = m.getName();
if (Pattern.matches(gs, methodName)) {
param = getM.matcher(methodName)
.replaceAll(rapl).toLowerCase();
if (!param.equals("class")) {
getMethods.put(param, m);
}
} else if (Pattern.matches(ss, methodName)) {
param = setM.matcher(methodName)
.replaceAll(rapl).toLowerCase();
setMethods.put(param, m);
}
}
// 给action所对应类的参数赋值
Iterator<Map.Entry<String, String>> it = parameters
.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> en = it.next();
String Mname = en.getKey();
Method gMethod = setMethods.get(Mname);
if (gMethod != null) {
gMethod.invoke(o, en.getValue());
}
}
// 调用actin对应类的执行方法
String result = (String) m1.invoke(o, null);
// 遍历action子节点,查找对应结果,并返回参数
NodeList childNodes = e.getChildNodes();
/*
* NodeList childNodes = element
* .getElementsByTagName("result");
*/
for (int j = 0; j < childNodes.getLength(); j++) {
if (childNodes.item(j) instanceof Element) {
Element Child = (Element) childNodes.item(j);//这里不加判断会报类型无法转换的错误,查找原因,是说xml中的某些文本会被当做节点存入nodelist中
String ChileName = Child.getAttribute("name");
if (ChileName.equals(result)) {
v.setJsp(Child.getTextContent());//不能用getnodevalue,而要用gettextcontent
// 给view的parameters参数赋值
Map<String, String> vparameters = new HashMap<>();
for (Entry<String, Method> entry : getMethods
.entrySet()) {
String tmp = (String) entry.getValue()
.invoke(o);
vparameters.put(entry.getKey(), tmp);
}
v.setParameters(vparameters);
return v;
}
}
}
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/*
*
* 0. 读取配置文件struts.xml
*
* 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
* 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" ,
* "password"="1234") , 那就应该调用 setName和setPassword方法
*
* 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
*
* 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如
* {"message": "登录成功"} , 放到View对象的parameters
*
* 4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp,
* 放到View对象的jsp字段中。
*/
return null;
}
}