package com.coding2017.litestruts; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import com.google.common.base.Strings; public class Struts { private static final String STRUTS_FILE_PATH = "/struts.xml"; private static final String ACTION_EXECUTE_METHOD = "execute"; /** * 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字段中。 * * @param actionName * @param parameters * @return */ public static View runAction(String actionName, Map<String, String> parameters) { if (Strings.isNullOrEmpty(actionName)) { return null; } StrutsDefinition strutsDefinition = StrutsXmlUtil .parseResource(Struts.class.getResourceAsStream(STRUTS_FILE_PATH)); if (strutsDefinition == null) { return null; } StrutsDefinition.ActionDefinition actionDefinition = findActionDefinition(strutsDefinition, actionName); if (actionDefinition == null) { return null; } try { Class<?> actionClass = Class.forName(actionDefinition.getClazz()); Object action = actionClass.newInstance(); setParameter(actionClass, action, parameters); Method executeMethod = actionClass.getMethod(ACTION_EXECUTE_METHOD); String actionResult = (String) executeMethod.invoke(action); StrutsDefinition.ResultDefinition resultDefinition = findResultDefinition(actionDefinition, actionResult); if (resultDefinition == null) { return null; } View view = new View(); view.setJsp(resultDefinition.getValue()); view.setParameters(makeParameters(action, actionClass)); return view; } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } private static Map makeParameters(Object action, Class<?> actionClass) throws InvocationTargetException, IllegalAccessException { Method[] methods = actionClass.getMethods(); Map map = new HashMap(); for (Method method : methods) { if (method.getName().startsWith("get")) { map.put(getField(method.getName()), method.invoke(action)); } } return map; } private static String getField(String getMethodName) { String field = getMethodName.substring(3); return field.substring(0, 1).toLowerCase() + field.substring(1); } private static StrutsDefinition.ResultDefinition findResultDefinition( StrutsDefinition.ActionDefinition actionDefinition, String actionResult) { for (StrutsDefinition.ResultDefinition resultDefinition : actionDefinition.getResultDefinitions()) { if (resultDefinition.getName().equals(actionResult)) { return resultDefinition; } } return null; } private static void setParameter(Class<?> actionClass, Object action, Map<String, String> parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { for (Map.Entry<String, String> paramEntry : parameters.entrySet()) { String setMethodName = getMethodName(paramEntry.getKey()); Method method = actionClass.getMethod(setMethodName, String.class); method.invoke(action, paramEntry.getValue()); } } private static String getMethodName(String field) { return "set" + field.substring(0, 1).toUpperCase() + field.substring(1); } private static StrutsDefinition.ActionDefinition findActionDefinition(StrutsDefinition strutsDefinition, String actionName) { for (StrutsDefinition.ActionDefinition definition : strutsDefinition.getActionDefinitionList()) { if (actionName.equals(definition.getName())) { return definition; } } return null; } }