package com.coding.litestruts; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; public class Struts { public static View runAction(String actionName, Map<String,String> parameters) { /* 0. 读取配置文件struts.xml dom4j 来读取 */ List<Element> elements = null; try { elements = openStrutsXML("struts.xml"); } catch (DocumentException e) { e.printStackTrace(); } for (Element element: elements) { String name = element.attribute("name").getValue(); String aClass = element.attribute("class").getValue(); /* 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , "password"="1234") ,那就应该调用 setName和setPassword方法 */ //此时的name等于传入的actionName Class<?> clazz = null; try { clazz = Class.forName(aClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } Object obj = null; try { obj = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } for (Map.Entry entry: parameters.entrySet()) { String key = entry.getKey().toString(); String parSetName = parSetName(key); Method method = null; try { method = clazz.getMethod(parSetName, String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } try { method.invoke(obj, entry.getValue()); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" Method execute = null; try { execute = clazz.getMethod("execute", null); } catch (NoSuchMethodException e) { e.printStackTrace(); } Object result = null; try { result = execute.invoke(obj, null); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } Map resultParameters = new HashMap(); // 3. 通过反射找到对象的所有getter方法(例如 getMessage), // 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , // 放到View对象的parameters Field[] fields = clazz.getDeclaredFields(); //此处取到的方法是所有的public修饰的方法 Method[] methods = clazz.getMethods(); for (Field field: fields) { String fieldName = field.getName(); String parGetName = parGetName(fieldName); boolean isGetMethod = checkGetMethod(methods, parGetName); if (!isGetMethod) { continue; } Method method = null; try { method = clazz.getMethod(parGetName, null); } catch (NoSuchMethodException e) { e.printStackTrace(); } try { Object getResult = method.invoke(obj, null); if (getResult != null) { resultParameters.put(fieldName, getResult.toString()); } //如果execute方法返回fail,添加错误信息到map中 if ("fail".equals(result)) { resultParameters.put("message", "login failed,please check your user/pwd"); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, //放到View对象的jsp字段中。 List<Element> resultElements = element.elements("result"); for (Element resultElemnt: resultElements) { Attribute resultNode = resultElemnt.attribute("name"); String resultValue = resultNode.getValue(); String resultJsp = resultElemnt.getTextTrim(); if (result.equals(resultValue)) { View view = new View(); view.setJsp(resultJsp); view.setParameters(resultParameters); return view; } } } return null; } /** * 打开struts.xml文件, * @param strutsXMLPath struts.xml文件的位置 * @return List<Element>节点对象 * @throws DocumentException */ public static List<Element> openStrutsXML(String strutsXMLPath) throws DocumentException { InputStream in = View.class.getResourceAsStream(strutsXMLPath); SAXReader reader = new SAXReader(); Document document = reader.read(in); Element rootElement = document.getRootElement(); return (List<Element>) rootElement.elements("action"); } /** * 拼接属性的get方法 * @param fieldName * @return */ public static String parGetName(String fieldName) { if (null == fieldName || "".equals(fieldName)) { return null; } int startIndex = 0; if (fieldName.charAt(0) == '_') startIndex = 1; return "get" + fieldName.substring(startIndex, startIndex + 1).toUpperCase() + fieldName.substring(startIndex + 1); } /** * 拼接在某属性的 set方法 * * @param fieldName * @return String */ public static String parSetName(String fieldName) { if (null == fieldName || "".equals(fieldName)) { return null; } int startIndex = 0; if (fieldName.charAt(0) == '_') startIndex = 1; return "set" + fieldName.substring(startIndex, startIndex + 1).toUpperCase() + fieldName.substring(startIndex + 1); } /** * 判断是否存在某属性的 get方法 * * @param methods * @param fieldGetMet * @return boolean */ public static boolean checkGetMethod(Method[] methods, String fieldGetMet) { for (Method met : methods) { if (fieldGetMet.equals(met.getName())) { return true; } } return false; } }