package org.wsc.coderising.litestruts; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.wsc.coderising.litestruts.util.DocumentUtil; import org.xml.sax.SAXException; public class Struts { private static final DocumentUtil DOCUMENT_UTIL; private static Document document; static{ /* 0. 读取配置文件struts.xml */ DOCUMENT_UTIL = DocumentUtil.newInstance(); try { document = DOCUMENT_UTIL.getDocument("src/org/wsc/litestruts/struts.xml"); } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } /** * * @param actionName * @param parameters * @return */ public static View runAction(String actionName, Map<String, String> parameters) { String className = null; String jsp = null; Map<String, String> results = new HashMap<String, String>(); Node struts = document.getDocumentElement();// 获取根节点 NodeList actions = struts.getChildNodes();// 获取子节点 for (int i = 0; i < actions.getLength(); i++) { // 过滤空节点 if (actions.item(i).getNodeType() != Node.ELEMENT_NODE) continue; Element action = (Element) actions.item(i); if (!action.getAttribute("name").equals(actionName)) continue; className = action.getAttribute("class"); /* * 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , * "password"="1234") , 那就应该调用 setName和setPassword方法 */ Class clazz = null; Object instance = null; try { clazz = Class.forName(className); instance = clazz.getConstructor().newInstance(); Set<String> keySet = parameters.keySet(); for (String key : keySet) { Object parameter = parameters.get(key); Method method = instance.getClass().getMethod( "set" + (key.substring(0, 1).toUpperCase() + key.substring(1)), parameter.getClass()); method.invoke(instance, parameter); } } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { e.printStackTrace(); } /* 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" */ String rt = null; try { Method method = clazz.getMethod("execute"); rt = (String) method.invoke(instance); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* * 3. 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap * , 例如 {"message": "登录成功"} , 放到View对象的parameters */ Field[] fields = instance.getClass().getDeclaredFields(); Method[] methods = instance.getClass().getMethods(); for (Field field : fields) { String fieldName = field.getName(); for (Method method : methods) { if (method.getName() .equals(("get" + (fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1))))) { try { results.put(fieldName, (String) method.invoke(instance)); break; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } } } NodeList resultNodes = action.getChildNodes(); for (int j = 0; j < resultNodes.getLength(); j++) { if (resultNodes.item(j).getNodeType() != Node.ELEMENT_NODE) continue; Element result = (Element) resultNodes.item(j); if (!result.getAttribute("name").equals(rt)) continue; jsp = result.getTextContent(); } } /* * 4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, * 放到View对象的jsp字段中。 */ View view = new View(); view.setJsp(jsp); view.setParameters(results); return view; } }