import com.byhieg.utils.bexception.UncheckedException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public class Struts {
public static View runAction(String actionName, Map<String, String> parameters) {
/*
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字段中。
*/
//创建文件对象,ClassName,view对象等必备的对象以及得到params参数中所有的key-value
String fileName = "/Users/byhieg/IdeaProjects/learnjava/src/com/byhieg/coding2017/homework305/struts.xml";
String className;
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
Iterator iterator = parameters.entrySet().iterator();
String[] methodNames = new String[parameters.size()];
int i = 0;
View view = new View();
Map map = new HashMap();
// 得到set方法的方法名
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
String key = entry.getKey();
keys.add(key);
values.add(entry.getValue());
methodNames[i++] = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
}
try {
//反射得到对象
Element element = getTargetElement(actionName, fileName);
className = getClassName(element);
Class clz = Class.forName(className);
Object obj = clz.newInstance();
//根据上面的set方法名的数组,依次调用,
for (int j = 0; j < methodNames.length; j++) {
Method method = clz.getMethod(methodNames[j], String.class);
method.invoke(obj, values.get(j));
}
//执行execute方法
Method method = clz.getMethod("execute");
String result = (String) method.invoke(obj);
//得到所有方法,判断哪些是get方法,是的话,生成需要的map
Method[] methods = clz.getMethods();
for (Method item : methods) {
if (item.getName().contains("get")) {
String key = item.getName().substring(3).toLowerCase();
Object value = item.invoke(obj);
map.put(key, value);
}
}
view.setParameters(map);
//根据result得到jsp,放入view对象中
String jsp = getJsp(element, result);
view.setJsp(jsp);
return view;
} catch (DocumentException e) {
System.out.println("文件找不到");
} catch (ClassNotFoundException e) {
System.out.println("找不到指定的类");
} catch (InstantiationException | IllegalAccessException e) {
System.out.println("创建对象失败");
} catch (NoSuchMethodException e) {
System.out.println("方法创建失败");
} catch (InvocationTargetException e) {
System.out.println("方法执行失败");
}
return view;
}
/**
*
* @param element 指定的的节点
* @return 返回该节点对应的ClassName的值
* @throws DocumentException 文件异常
*/
private static String getClassName(Element element) throws DocumentException {
return element.attribute(1).getValue();
}
/**
*
* @param actionName actionName
* @param fileName xml文件路径
* @return 指定actionName对应的节点元素
* @throws DocumentException 文件异常
*/
private static Element getTargetElement(String actionName, String fileName) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(fileName));
Element rootNode = document.getRootElement();
List<Element> elements = rootNode.elements();
for (Element item : elements) {
if (actionName.equals(item.attribute(0).getValue())) {
return item;
}
}
return null;
}
/**
* 通过result,得到指定的JSP
* @param element actionName对象的节点
* @param result result标签的name
* @return result标签的值
*/
private static String getJsp(Element element,String result) {
List<Element> elements = element.elements();
for (Element e : elements) {
if (result.equals(e.attribute(0).getValue())){
return e.getTextTrim();
}
}
return null;
}
}