package rui.study.coding2017.coderising.liteststruts;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Struts {
public static View runAction(String actionName, Map<String,String> parameters) {
View view=new View();
try {
StrutsAction strutsAction= StrutsAction.getFormStrutsMap(actionName);
Class clazz=strutsAction.getaClass();
Object object=clazz.newInstance();
setActionValue(parameters,object);
String resultStr = execute(object);
getVlaue(view, object);
getJspPath(view, strutsAction, resultStr);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return view;
}
/**
*
1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
("name"="test" , "password"="1234") ,
那就应该调用 setName和setPassword方法
* @param parameters 请求参数
* @param object 对象
*/
private static void setActionValue(Map<String, String> parameters, Object object) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
for (Map.Entry<String,String> entry: parameters.entrySet()) {
String key=entry.getKey();
String methodName="set"+key.substring(0,1).toUpperCase()+key.substring(1,key.length());
Method method=object.getClass().getMethod(methodName,String.class);
method.invoke(object,entry.getValue());
}
}
/**
* 2. 通过反射调用对象的execute 方法, 并获得返回值,例如"success"
* @param object 反射生成的对象
* @return 执行结果表示
*/
private static String execute(Object object) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, IOException {
Method executeMethod=object.getClass().getMethod("execute");
Object returnObj=executeMethod.invoke(object);
if(returnObj.getClass()!=String.class) throw new IOException("不支持非页面跳转类型");
return (String) returnObj;
}
/**
*
3. 通过反射找到对象的所有getter方法(例如 getMessage),
通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
放到View对象的parameters
* @param view 视图
* @param object 反射之后的action类
*/
private static void getVlaue(View view, Object object) throws IllegalAccessException, InvocationTargetException {
Map<String,Object> resultMap=new HashMap<String,Object>();
Method[] methods=object.getClass().getDeclaredMethods();
for (Method getMethod:methods) {
String methodName=getMethod.getName();
if(methodName.contains("get")){
Object o=getMethod.invoke(object);
String fileName=methodName.replace("get","");
fileName=fileName.substring(0,1).toLowerCase()+fileName.substring(1,fileName.length());
resultMap.put(fileName,o);
}
}
view.setParameters(resultMap);
}
/**
4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp,
放到View对象的jsp字段中。
* @param view 视图
* @param strutsAction xml解析后的存储类
* @param resultStr 结果表示
*/
private static void getJspPath(View view, StrutsAction strutsAction, String resultStr) {
for (StrutsAction.Result result:strutsAction.getResults()) {
if(result.name.equals(resultStr))view.setJsp(result.jspPath);
}
}
}