package com.camile._2.litestruts;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import org.apache.commons.digester.Digester;
import org.junit.experimental.theories.Theories;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import com.camile._2.litestruts.bean.Action;
import com.camile._2.litestruts.bean.Result;
import com.camile._2.litestruts.bean.Structs;
/**
* @author Administrator 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字段中
*/
public class Struts {
public View runAction(String actionName, Map<String, String> parameters) {
Structs structs = makeObjFromXml(readProfiles("struts.xml"));
for (Action a : structs.getActions()) {
if (a.getName().equals(actionName)) {
try {
Class<?> actionClass = Class.forName(a.getClazz());
Object instance = actionClass.newInstance();
Field field;
// get field
for (Map.Entry<String, String> entry : parameters.entrySet()) {
field = actionClass.getDeclaredField(entry.getKey());
field.setAccessible(true);
field.set(instance, entry.getValue());
}
Method execute = actionClass.getMethod("execute");
String resultString = (String) execute.invoke(instance);
Method getMessage = actionClass.getMethod("getMessage");
String message = (String) getMessage.invoke(instance);
Map<String, String> map = new HashMap<>();
map.put("message", message);
View view = new View();
String viewPath;
for (Result path : a.getResults()) {
if (path.getName().equals(resultString)) {
viewPath = path.getValue();
view.setParameters(map);
view.setJsp(viewPath);
}
}
return view;
} catch (NoSuchFieldException | SecurityException e) {
System.out.println("获取参数失败");
e.printStackTrace();
} catch (ClassNotFoundException e) {
System.out.println("并没有在xml中找到相关action");
e.printStackTrace();
} catch (InstantiationException | IllegalAccessException e) {
System.out.println("获取反射对象失败");
e.printStackTrace();
} catch (NoSuchMethodException e) {
System.out.println("获取方法");
e.printStackTrace();
} catch (IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
return null;
}
private URL readProfiles(String filePath) {
ClassLoader classLoader = Struts.class.getClassLoader();
URL resource = classLoader.getResource(filePath);
if (resource == null)
throw new RuntimeException("文件不存在");
return resource;
}
private Structs makeObjFromXml(URL resource) {
Digester digester = new Digester();
digester.addObjectCreate("struts", Structs.class);
digester.addObjectCreate("struts/action", Action.class);
digester.addSetProperties("struts/action", new String[] { "name", "class" }, new String[] { "name", "clazz" });
digester.addSetNext("struts/action", "addAction");
digester.addObjectCreate("struts/action/result", Result.class);
digester.addSetProperties("struts/action/result");
digester.addBeanPropertySetter("struts/action/result", "value");
digester.addSetNext("struts/action/result", "addResult");
try {
return (Structs) digester.parse(resource);
} catch (IOException | SAXException e) {
e.printStackTrace();
throw new RuntimeException("解析XML文件时发生错误");
}
}
public static void main(String[] args) {
}
}