package com.github.eulerlcs.jmr.litestruts.core; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.commons.digester.Digester; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; import com.github.eulerlcs.jmr.litestruts.degister.StrutsConfig; import com.github.eulerlcs.jmr.litestruts.degister.StrutsDigester; /** * <ul> * <li>读取配置文件struts.xml</li> * <li>根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) * 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , * "password"="1234") , 那就应该调用 setName和setPassword方法</li> * <li>通过反射调用对象的exectue 方法, 并获得返回值,例如"success"</li> * <li>通过反射找到对象的所有getter方法(例如 getMessage), 通过反射来调用, 把值和属性形成一个HashMap , 例如 * {"message": "登录成功"} , 放到View对象的parameters</li> * <li>根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, 放到View对象的jsp字段中。</li> * </ul> */ public class Struts { private final static Logger log = LoggerFactory.getLogger(Struts.class); private static StrutsConfig config = null; 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字段中。 * */ // 0. getConfig(); // 1.1. Object object = createInstance(actionName); if (object == null) { return null; } // 1.2. if (!prepareParameters(object, parameters)) { return null; } // 2. String viewId = execute(object); if (viewId == null) { return null; } // 3. View view = biuldView(object); if (view == null) { return null; } // 4. String uri = config.getActionMap().get(actionName).getResults().get(viewId).getUrl(); view.setJsp(uri); return view; } private static StrutsConfig getConfig() { if (config != null) { return config; } Digester d = StrutsDigester.newInstance(); try { File file = new File("data", "struts.xml"); config = (StrutsConfig) d.parse(file); } catch (IOException | SAXException e) { log.error("getConfig", e); System.exit(1); } return config; } private static Object createInstance(String actionName) { if (actionName == null) { return null; } String className = config.getActionMap().get(actionName).getClazz(); Object object = null; try { Class<?> clazz = Class.forName(className); object = clazz.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { log.error("createInstance", e); } return object; } private static boolean prepareParameters(Object object, Map<String, String> parameters) { if (parameters == null || parameters.size() == 0) { return true; } Class<?> clazz = object.getClass(); Method setter = null; try { for (String key : parameters.keySet()) { setter = clazz.getMethod(biuldSetterName(key), String.class); setter.setAccessible(true); setter.invoke(object, parameters.get(key)); } } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { log.error("prepareParameters", e); return false; } return true; } private static String biuldSetterName(String name) { String setterName = "set"; setterName += name.substring(0, 1).toUpperCase() + name.substring(1); return setterName; } private static String debiuldGetterName(String getterName) { if (getterName == null || getterName.length() <= 3) { return null; } if (!getterName.substring(0, 3).equals("get")) { return null; } String name = getterName.substring(3, 4).toLowerCase() + getterName.substring(4); return name; } private static String execute(Object object) { final String METHOD_EXECUTE = "execute"; String viewId = null; Class<?> clazz = object.getClass(); try { Method method = clazz.getMethod(METHOD_EXECUTE); viewId = (String) method.invoke(object); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { log.error("execute", e); return viewId; } return viewId; } private static View biuldView(Object object) { View view = new View(); Map<String, Object> parameters = new HashMap<>(); Class<?> clazz = object.getClass(); Method[] methods; try { methods = clazz.getMethods(); for (Method method : methods) { String name = debiuldGetterName(method.getName()); if (name == null) { continue; } Object value = method.invoke(object); parameters.put(name, value); } view.setParameters(parameters); } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { log.error("biuldResult", e); return null; } return view; } }