package com.coding.week2.litestruts; import org.dom4j.DocumentException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; 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(); try { //0 //得到action类名 String actionClassName = StrutsXmlUtil.getActionClassName(actionName); //得到action的结果及jsp路径 Map<String,String> jspMap = StrutsXmlUtil.getResultOfAction(actionName); //加载类 Class clazz = Class.forName(actionClassName); //实例化对象 Object obj = clazz.newInstance(); Method[] methods = clazz.getDeclaredMethods(); //1 注入action实例变量 setFields(obj, methods, parameters); //2 执行action String result = excute(obj, methods); //3 获取返回的参数 Map<String,Object> viewParams = buildReturnParams(obj, methods); view.setParameters(viewParams); //4 设置返回的jsp String jsp = jspMap.get(result); view.setJsp(jsp); } catch (DocumentException | ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } return view; } private static String excute(Object obj, Method[] methods ) throws InvocationTargetException, IllegalAccessException { for(Method method : methods){ String methodName = method.getName(); if("execute".equals(methodName)){ return (String) method.invoke(obj); } } return ""; } private static void setFields(Object obj, Method[] methods, Map<String,String> parameters) throws InvocationTargetException, IllegalAccessException { Set<Map.Entry<String, String>> entities = parameters.entrySet(); for(Map.Entry<String, String> entry : entities){ for(Method method : methods){ if(method.getName().equals("set" + upperFirstChar(entry.getKey()))){ method.invoke(obj, entry.getValue()); } } } } private static Map<String, Object> buildReturnParams(Object obj, Method[] methods) throws InvocationTargetException, IllegalAccessException { Map<String,Object> viewParams = new HashMap<>(); for(Method method : methods){ String methodName = method.getName(); if(methodName.startsWith("get")){ Object ret = method.invoke(obj); String field = methodName.substring(3); viewParams.put(lowerFirstChar(field), ret); } } return viewParams; } private static String upperFirstChar(String str){ char[] cs = str.toCharArray(); cs[0] -= 32; return new String(cs); } private static String lowerFirstChar(String str){ char[] cs = str.toCharArray(); cs[0] += 32; return new String(cs); } }