package com.coderising.litestruts; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; 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) { /* * * 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字段中。 * */ View view = new View(); /* * 0、读取xml文件 */ String path = "src/com/coderising/litestruts/struts.xml"; Document document = null; try { document = new SAXReader().read(path); } catch (DocumentException e) { e.printStackTrace(); } /* * 1、 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , * "password"="1234") , 那就应该调用 setName和setPassword方法 */ // 获取根节点 Element root = document.getRootElement(); // 遍历根节点下面的节点 Iterator<?> actionIt = root.elementIterator("action"); while (actionIt.hasNext()) { Element action = (Element) actionIt.next(); if (action.attribute("name").getValue().equals(actionName)) { String className = action.attribute("class").getValue(); Class<?> clazz = null; try { // 通过actionName找到className,并得到类 clazz = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } Object clazzObject = null; try { // 创建类的一个对象 clazzObject = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // 遍历放参数的map Set<String> keySet = parameters.keySet(); for (String key : keySet) { // 拼接set方法的name String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1, key.length()); // 得到set方法对象 Method setMethod = null; try { setMethod = clazz.getMethod(methodName, String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } try { // 调用set方法,参数为parameters中对应的value setMethod.invoke(clazzObject, parameters.get(key)); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } /* * 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" */ Method executeMethod = null; try { // 得到exectue方法 executeMethod = clazz.getMethod("execute"); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } String string = null; try { // 调用exectue方法 string = (String) executeMethod.invoke(clazzObject); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } /* * 3、通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, * 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , * 放到View对象的parameters */ Map<String, Object> map = new HashMap<>(); Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.getName().substring(0, 3).equals("get") && !method.getName().equals("getClass")) { Object str = null; try { // 调用get方法 str = method.invoke(clazzObject); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } map.put(method.getName().substring(3).toLowerCase(), str); } } view.setParameters(map); /* * 4、根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, * 放到View对象的jsp字段中。 */ @SuppressWarnings("unchecked") List<Element> elements = action.elements(); for (Element element : elements) { if (element.attribute("name").getValue().equals(string)) { String jspName = element.getText(); view.setJsp(jspName); } } } } return view; } }