package com.coderising.litestruts; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.collections4.CollectionUtils; import com.coderising.litestruts.api.StructAction; import com.coderising.litestruts.api.View; import com.coderising.litestruts.parser.StructXmlParser; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class Struts { private static Map<String, StructAction> actionMapping = Maps.newConcurrentMap(); private static final String DEFAULT_CONFIG = "struts.xml"; private static List<String> configFiles; static { // 读取配置文件struts.xml loadStrutsConfig(configFiles); } public static View runAction(String actionName, Map<String, String> parameters) { View view = new View(); try { StructAction action = actionMapping.get(actionName); Class clazz = Class.forName(action.getClazzName()); Object instance = clazz.newInstance(); String result = (String) process(clazz, instance, parameters, action); buildView(view, action, instance, result); } catch (Exception e) { e.printStackTrace(); } return view; } private static void buildView(View view, StructAction action, Object instance, String result) throws IntrospectionException, ClassNotFoundException, IllegalAccessException, InvocationTargetException { // 读取action属性 BeanInfo beanInfo = Introspector.getBeanInfo(Class.forName(action.getClazzName())); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); Map<Object, Object> prop = Maps.newHashMap(); for (PropertyDescriptor PropertyDescriptor : propertyDescriptors) { Method readMethod = PropertyDescriptor.getReadMethod(); // 内省存在一个问题就是说属性的get方法本身不一定存在 if (readMethod != null) { Object invoke = readMethod.invoke(instance); prop.put(PropertyDescriptor.getName(), invoke); } } // 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp, 放到View对象的jsp字段中。 Map<String, String> actions = action.getActions(); view.setParameters(prop); view.setJsp(actions.get(result)); } @SuppressWarnings("unchecked") private static Object process(Class clazz, Object instance, Map<String, String> parameters, StructAction action) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { // 根据actionName找到相对应的class ,属性填充我认为暴力反射会更好一点 for (Map.Entry<String, String> entry : parameters.entrySet()) { try { Field field = clazz.getDeclaredField(entry.getKey()); field.setAccessible(true); field.set(instance, entry.getValue()); } catch (NoSuchFieldException e) { e.printStackTrace(); } } // 通过反射调用对象的execute方法 Method execute = clazz.getDeclaredMethod("execute"); execute.setAccessible(true); return execute.invoke(instance); } private static void loadStrutsConfig(List<String> configFiles) { if (CollectionUtils.isEmpty(configFiles)) { configFiles = Lists.newArrayList(DEFAULT_CONFIG); } for (String configFile : configFiles) { InputStream inputStream = Struts.class.getResourceAsStream(configFile); SAXParser parser = null; try { parser = SAXParserFactory.newInstance().newSAXParser(); StructXmlParser structXmlParser = new StructXmlParser(); parser.parse(inputStream, structXmlParser); List<StructAction> actions = structXmlParser.getData(); for (StructAction action : actions) { actionMapping.put(action.getName(), action); } } catch (Exception e) { e.printStackTrace(); } } } public void setConfigFiles(List<String> configFiles) { configFiles = configFiles; } }