package com.circle.struts; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by keweiyang on 2017/3/2. */ public class Struts { private final static String D = "1234"; private List<ActionEntity> actionEntityList = new ArrayList<>(); private ActionEntity actionEntity = null; /** * @param actionName action方法名称 例如:LoginAction * @param parameters 参数map,例如:name->liuxin,password->1234 * @param pathName 文件路径 * @return */ public View runAction(String actionName, Map<String, String> parameters, String pathName) { /** * 0.读取配置文件struts.xml * * 1.根据actionName找到对应的class,例如LoginActon,通过反射实例化(创建对象),然后根据parameters中的数据,调用 * 对象的setter方法,例如parameters中的数据是("name"="liuxin","password"="1234"),那就调用setName和setPassword方法 * * 2.通过反射调用对象的execute方法,并获得返回值,例如:"success" * * 3. 通过反射找到对象的所有getter方法(例如getMessage),通过反射调用,把值和属性形成一个HashMap,例如{"message":"登录成功"}, * 放到View对象的parameters * * 4. 根据struts.xml中的<result>配置,以及execute的返回值,确定哪一个jsp,放到View对象的jsp对象中 * */ try { //1:读取struts.xml this.getActionEntityList(pathName); //2:获取对应的classpath String classPath = initParameter(actionName, parameters); //3:反射 View view = createClass(classPath, parameters); return view; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将map中的key值修改为setxxx,并且获取classpath * * @param actionName * @param mapParameters * @return */ private String initParameter(String actionName, Map<String, String> mapParameters) { if (actionName == null || actionName.trim().length() == 0) { throw new IllegalStateException("actionName为空"); } if (mapParameters == null || mapParameters.size() == 0) { throw new IllegalStateException("参数为空"); } String classpath = ""; for (ActionEntity entity : this.actionEntityList) { if (entity.getName().equals(actionName)) { this.actionEntity = entity; classpath = entity.getClassName(); break; } } Map<String, String> map = new HashMap<>(); for (Map.Entry<String, String> entry : mapParameters.entrySet()) { String methodName = "set" + entry.getKey().substring(0, 1).toUpperCase() + entry.getKey().substring(1); map.put(methodName, entry.getValue()); } mapParameters.clear(); for (Map.Entry<String, String> entry : map.entrySet()) { mapParameters.put(entry.getKey(), entry.getValue()); } return classpath; } private View createClass(String classpath, Map<String, String> mapParameters) throws Exception { View view = null; if (classpath.equals("")) { throw new IllegalStateException("classPath为空"); } Class<?> clazz = Class.forName(classpath); Object obj = clazz.newInstance(); Method[] methods = clazz.getDeclaredMethods(); Field[] fields = clazz.getDeclaredFields(); // 先调用setter方法 for (Map.Entry<String, String> entry : mapParameters.entrySet()) { Method method = clazz.getDeclaredMethod(entry.getKey(), String.class); if (method != null) { method.invoke(obj, entry.getValue()); } } // 再调用execute方法 // if (obj instanceof LoginAction) { Method method = clazz.getDeclaredMethod("execute"); String ret = (String) method.invoke(obj, null); Map<String, String> retMap = this.actionEntity.getResultMap(); for (Map.Entry<String, String> result : retMap.entrySet()) { if (ret.equals(result.getKey())) { Map<String, String> map = new HashMap<>(); System.out.println(result.getValue()); this.showView(methods, fields, obj, clazz, map); view = new View(); view.setJsp(result.getValue()); view.setParameters(map); System.out.println(view.toString()); break; } // } } return view; } private void showView(Method[] methods, Field[] fields, Object object, Class<?> clazz, Map<String, String> map) throws Exception { String[] ss = new String[fields.length]; Method[] ms = new Method[methods.length]; for (int i = 0; i < fields.length; i++) { ss[i] = fields[i].getName(); } for (int i = 0; i < ss.length; i++) { String str = ss[i]; ss[i] = "get" + ss[i].substring(0, 1).toUpperCase() + ss[i].substring(1); ms[i] = clazz.getDeclaredMethod(ss[i], null); String returnType = (String) ms[i].invoke(object, null); map.put(str, returnType); // System.out.println(returnType.toString()); } } /** * 读取指定路径 * * @param pathName 文件路径 * @return */ private List<ActionEntity> getActionEntityList(String pathName) { //读取struts.xml配置文件 if (pathName == null || pathName.trim().length() == 0) { throw new IllegalStateException("pathName为空"); } Document document = XmlUtil.getDocument(pathName); Map<String, String> resultMap = null; if (document.hasChildNodes()) { NodeList nodeList = document.getElementsByTagName("struts"); for (int i = 0; i < nodeList.getLength(); i++) { Element rootEle = (Element) nodeList.item(i); if (rootEle.hasChildNodes()) { NodeList childList = rootEle.getElementsByTagName("action"); for (int j = 0; j < childList.getLength(); j++) { Element childEle = (Element) childList.item(j); ActionEntity actionEntity = new ActionEntity(); String name = childEle.getAttribute("name"); String className = childEle.getAttribute("class"); actionEntity.setClassName(className); actionEntity.setName(name); if (childEle.hasChildNodes()) { NodeList grandSonList = childEle.getElementsByTagName("result"); resultMap = new HashMap<>(); for (int k = 0; k < grandSonList.getLength(); k++) { Element resultEle = (Element) grandSonList.item(k); String resultName = resultEle.getAttribute("name"); String value = resultEle.getTextContent(); resultMap.put(resultName, value); } } actionEntity.setResultMap(resultMap); actionEntityList.add(actionEntity); } } } } return actionEntityList; } }