package com.coderising.litestruts; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; public class Struts { private static Map<String, ActionXml> actionXmlMap; static { //0. 读取配置文件struts.xml actionXmlMap = parserXml("src/com/coderising/litestruts/struts.xml"); System.out.println("parse end"); } public static View runAction(String actionName, Map<String, String> parameters) { try { ActionXml actionXml = actionXmlMap.get(actionName); if (actionName == null) { return null; } else { String className = actionXml.getClassName(); Class cls = Class.forName(className); Object obj = cls.newInstance(); /** 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , "password"="1234") , 那就应该调用 setName和setPassword方法 */ Method[] methods = cls.getMethods(); for (String field : parameters.keySet()) { for (Method method : methods) { if (method.getName().startsWith("set") && method.getName().toLowerCase().endsWith(field.toLowerCase())) { method.invoke(obj, parameters.get(field)); break; } } } Method action = cls.getMethod("execute"); //通过反射调用对象的exectue 方法, 并获得返回值,例如"success" String result = (String) action.invoke(obj); /** 通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , 放到View对象的parameters */ Field[] fields = cls.getDeclaredFields(); Map<String, Object> params = new HashMap<>(); for (Field field : fields) { for (Method method : methods) { if (method.getName().startsWith("get") && method.getName().toLowerCase().endsWith(field.getName().toLowerCase())) { String viewResult = (String) method.invoke(obj); params.put(field.getName(), viewResult); break; } } } /** 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, 放到View对象的jsp字段中。 */ View view = new View(); view.setParameters(params); view.setJsp(actionXmlMap.get(actionName).getMap().get(result)); return view; } } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } catch (InstantiationException e) { e.printStackTrace(); return null; } catch (IllegalAccessException e) { e.printStackTrace(); return null; } catch (NoSuchMethodException e) { e.printStackTrace(); return null; } catch (InvocationTargetException e) { e.printStackTrace(); return null; } } //解析xml文件 private static Map<String, ActionXml> parserXml(String fileName) { try { Map<String, ActionXml> map = new HashMap<>(); //create documentBuilder DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); //create document Document document = db.parse(fileName); //extract root element Element root = document.getDocumentElement(); System.out.println("Root element :" + document.getDocumentElement().getNodeName()); NodeList nodeList = document.getElementsByTagName("action"); System.out.println("----------------------------"); for (int temp = 0; temp < nodeList.getLength(); temp++) { Node nNode = nodeList.item(temp); System.out.println("\nCurrent Element :" + nNode.getNodeName()); if (nNode.getNodeType() == Node.ELEMENT_NODE) { ActionXml actionXml = new ActionXml(); Element eElement = (Element) nNode; System.out.println("action name : " + eElement.getAttribute("name")); System.out.println("class name : " + eElement.getAttribute("class")); actionXml.setName(eElement.getAttribute("name")); actionXml.setClassName(eElement.getAttribute("class")); NodeList result = eElement.getElementsByTagName("result"); Map<String, String> results = new HashMap<>(); for (int i = 0; i < result.getLength(); i++) { Node resultNode = result.item(i); if (resultNode.getNodeType() == Node.ELEMENT_NODE) { Element resultElement = (Element) resultNode; System.out.println("result name:" + resultElement.getAttribute("name")); System.out.println("result context:" + resultElement.getTextContent()); results.put(resultElement.getAttribute("name"), resultElement.getTextContent()); } actionXml.setMap(results); } map.put(actionXml.getName(), actionXml); } } return map; } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { // parserXml("src/com/coderising/litestruts/struts.xml"); } }