package com.coderising.litestruts; import java.io.File; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Struts { public static View runAction(String actionName, Map<String, String> parameters) throws ClassNotFoundException, DocumentException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { /* * * 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字段中。 * */ String[] methodNames = createSetMethodNames(parameters); Struts.class.getResourceAsStream("/struts.xml"); Element element = getTargetElement(actionName); String className = element.attribute(1).getValue(); Class clz = Class.forName(className); Object obj = clz.newInstance(); invokeObjectSetter(parameters, methodNames, clz, obj); View view = new View(); view.setParameters(createGetterMap(clz, obj)); setViewJsp(view, element, clz, obj); return view; } private static String[] createSetMethodNames(Map<String, String> parameters) { String[] methodNames = new String[parameters.size()]; int i = 0; for (String key : parameters.keySet()) { methodNames[i++] = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); } return methodNames; } private static void setViewJsp(View view, Element element, Class clz, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { view.setJsp(getJsp(element, executeToGetResult(clz, obj))); } private static Map createGetterMap(Class clz, Object obj) throws IllegalAccessException, InvocationTargetException { Map map = new HashMap(); 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); } } return map; } private static String executeToGetResult(Class clz, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Method method = clz.getMethod("execute"); String result = (String) method.invoke(obj); return result; } private static void invokeObjectSetter(Map<String, String> parameters, String[] methodNames, Class clz, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { for (String key : methodNames) { Method method = clz.getMethod(key, String.class); method.invoke(obj, parameters.get(key)); } } private static Element getTargetElement(String actionName) throws DocumentException { SAXReader reader = new SAXReader(); InputStream inputStream =Struts.class.getResourceAsStream("/struts.xml"); Document document = reader.read(inputStream); Element rootNode = document.getRootElement(); List<Element> elements = rootNode.elements(); for (Element item : elements) { if (actionName.equals(item.attribute(0).getValue())) { return item; } } return null; } 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; } }