Skip to content

Commit 15b2651

Browse files
committed
implement Struts by Korben
1 parent a747667 commit 15b2651

File tree

8 files changed

+335
-0
lines changed

8 files changed

+335
-0
lines changed
Binary file not shown.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.korben.coderising.litestruts;
2+
3+
/**
4+
* 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
5+
*
6+
* @author liuxin
7+
*/
8+
public class LoginAction {
9+
private String name;
10+
private String password;
11+
private String message;
12+
13+
public String getName() {
14+
return name;
15+
}
16+
17+
public void setName(String name) {
18+
this.name = name;
19+
}
20+
21+
public String getPassword() {
22+
return password;
23+
}
24+
25+
public void setPassword(String password) {
26+
this.password = password;
27+
}
28+
29+
public String execute() {
30+
if ("test".equals(name) && "1234".equals(password)) {
31+
this.message = "login successful";
32+
return "success";
33+
}
34+
this.message = "login failed,please check your user/pwd";
35+
return "fail";
36+
}
37+
38+
public String getMessage() {
39+
return this.message;
40+
}
41+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package org.korben.coderising.litestruts;
2+
3+
import java.lang.reflect.Field;
4+
import java.lang.reflect.InvocationTargetException;
5+
import java.lang.reflect.Method;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
import java.util.Objects;
9+
import org.korben.coderising.litestruts.dom.StrutsAction;
10+
import org.korben.coderising.litestruts.util.StrutsParser;
11+
12+
public class Struts {
13+
14+
/**
15+
* 0. 读取配置文件struts.xml
16+
*
17+
* 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
18+
* 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
19+
* ("name"="test" , "password"="1234") ,
20+
* 那就应该调用 setName和setPassword方法
21+
*
22+
* 2. 通过反射调用对象的execute 方法, 并获得返回值,例如"success"
23+
*
24+
* 3. 通过反射找到对象的所有getter方法(例如 getMessage),
25+
* 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
26+
* 放到View对象的parameters
27+
*
28+
* 4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp,
29+
* 放到View对象的jsp字段中。
30+
*/
31+
public static View runAction(String actionName, Map<String, String> parameters) {
32+
Map<String, StrutsAction> actionMap = StrutsParser.doParse();
33+
StrutsAction action = actionMap.get(actionName);
34+
35+
if (action == null) {
36+
System.out.println("couldn't get action: " + actionName + ", return");
37+
return null;
38+
}
39+
40+
try {
41+
// 通过反射, 创建实例对象
42+
Class<?> actionClass = Class.forName(action.getActionClassName());
43+
Object actionObj = actionClass.newInstance();
44+
45+
// 调用 parameters 中的 set 方法
46+
for (Map.Entry<String, String> parameterEntry : parameters.entrySet()) {
47+
Method[] methods = actionClass.getMethods();
48+
for (Method method : methods) {
49+
if (method.getName().equalsIgnoreCase("set" + parameterEntry.getKey())) {
50+
method.invoke(actionObj, parameterEntry.getValue());
51+
}
52+
}
53+
}
54+
//for (Map.Entry<String, String> parameterEntry : parameters.entrySet()) {
55+
// for (PropertyDescriptor propertyDescriptor :
56+
// Introspector.getBeanInfo(actionClass).getPropertyDescriptors()) {
57+
// if (propertyDescriptor.getDisplayName().equals(parameterEntry.getKey())) {
58+
// Method writeMethod = propertyDescriptor.getWriteMethod();
59+
// writeMethod.invoke(actionObj, parameterEntry.getValue());
60+
// }
61+
// }
62+
//}
63+
64+
// 调用 execute 方法
65+
Method executeMethod = actionClass.getMethod("execute");
66+
Object executeResult = executeMethod.invoke(actionObj);
67+
68+
// 根据 execute 方法的结果, 获取 xml 配置的 jsp 页面
69+
String jsp = action.getAttributes().get(Objects.toString(executeResult));
70+
71+
// 调用 get 方法
72+
Map<String, String> actionFieldMap = new HashMap<>();
73+
Field[] actionFields = actionClass.getDeclaredFields();
74+
for (Field actionFiled : actionFields) {
75+
Method[] methods = actionClass.getMethods();
76+
for (Method method : methods) {
77+
if (method.getName().equalsIgnoreCase("get" + actionFiled.getName())) {
78+
method.invoke(actionObj);
79+
actionFieldMap.put(actionFiled.getName(), Objects.toString(method.invoke(actionObj)));
80+
}
81+
}
82+
}
83+
//for (PropertyDescriptor propertyDescriptor :
84+
// Introspector.getBeanInfo(actionClass).getPropertyDescriptors()) {
85+
// Method readMethod = propertyDescriptor.getReadMethod();
86+
// Object readMethodResult = readMethod.invoke(actionObj);
87+
// actionFieldMap.put(propertyDescriptor.getDisplayName(), Objects.toString(readMethodResult));
88+
//}
89+
90+
// 返回 View 对象
91+
View view = new View();
92+
view.setParameters(actionFieldMap);
93+
view.setJsp(jsp);
94+
return view;
95+
} catch (ClassNotFoundException e) {
96+
e.printStackTrace();
97+
} catch (InstantiationException e) {
98+
e.printStackTrace();
99+
} catch (IllegalAccessException e) {
100+
e.printStackTrace();
101+
} catch (InvocationTargetException e) {
102+
e.printStackTrace();
103+
} catch (NoSuchMethodException e) {
104+
e.printStackTrace();
105+
}/* catch (IntrospectionException e) {
106+
e.printStackTrace();
107+
}*/
108+
109+
return null;
110+
}
111+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.korben.coderising.litestruts;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
8+
public class StrutsTest {
9+
10+
@Test
11+
public void testLoginActionSuccess() {
12+
13+
String actionName = "login";
14+
15+
Map<String, String> params = new HashMap<String, String>();
16+
params.put("name", "test");
17+
params.put("password", "1234");
18+
19+
View view = Struts.runAction(actionName, params);
20+
21+
Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
22+
Assert.assertEquals("login successful", view.getParameters().get("message"));
23+
}
24+
25+
@Test
26+
public void testLoginActionFailed() {
27+
String actionName = "login";
28+
Map<String, String> params = new HashMap<String, String>();
29+
params.put("name", "test");
30+
params.put("password", "123456"); //密码和预设的不一致
31+
32+
View view = Struts.runAction(actionName, params);
33+
34+
Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
35+
Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
36+
}
37+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.korben.coderising.litestruts;
2+
3+
import java.util.Map;
4+
5+
public class View {
6+
private String jsp;
7+
private Map parameters;
8+
9+
public String getJsp() {
10+
return jsp;
11+
}
12+
13+
public View setJsp(String jsp) {
14+
this.jsp = jsp;
15+
return this;
16+
}
17+
18+
public Map getParameters() {
19+
return parameters;
20+
}
21+
22+
public View setParameters(Map parameters) {
23+
this.parameters = parameters;
24+
return this;
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.korben.coderising.litestruts.dom;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* Created by Korben on 03/03/2017.
7+
*/
8+
public class StrutsAction {
9+
private String actionClassName;
10+
private Map<String, String> attributes;
11+
12+
public String getActionClassName() {
13+
return actionClassName;
14+
}
15+
16+
public void setActionClassName(String actionClassName) {
17+
this.actionClassName = actionClassName;
18+
}
19+
20+
public Map<String, String> getAttributes() {
21+
return attributes;
22+
}
23+
24+
public void setAttributes(Map<String, String> attributes) {
25+
this.attributes = attributes;
26+
}
27+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.korben.coderising.litestruts.util;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.util.ArrayList;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
import org.dom4j.Document;
10+
import org.dom4j.DocumentException;
11+
import org.dom4j.Element;
12+
import org.dom4j.io.SAXReader;
13+
import org.korben.coderising.litestruts.dom.StrutsAction;
14+
15+
/**
16+
* 解析struts.xml
17+
*
18+
* Created by Korben on 03/03/2017.
19+
*/
20+
public class StrutsParser {
21+
22+
private static final String STRUTS_XML = "struts.xml";
23+
24+
public static void main(String[] args) {
25+
Map<String, StrutsAction> strutsActions = doParse();
26+
System.out.println(strutsActions.size());
27+
}
28+
29+
public static Map<String, StrutsAction> doParse() {
30+
Map<String, StrutsAction> resultMap = new HashMap<>();
31+
32+
SAXReader reader = new SAXReader();
33+
InputStream in = getStrutsInputStream();
34+
try {
35+
Document document = reader.read(in);
36+
Element rootElement = document.getRootElement();
37+
38+
// parse action element
39+
List<Element> elementActions = rootElement.elements();
40+
for (Element elementAction : elementActions) {
41+
StrutsAction action = new StrutsAction();
42+
43+
// parse "name" attribute from action element
44+
resultMap.put(elementAction.attribute("name").getValue(), action);
45+
46+
// parse "class" attribute from action element
47+
action.setActionClassName(elementAction.attribute("class").getValue());
48+
49+
// parse sub elements in action element
50+
List<Element> elements = elementAction.elements();
51+
Map<String, String> map = new HashMap<>();
52+
for (Element element : elements) {
53+
map.put(element.attribute("name").getValue(), element.getStringValue());
54+
}
55+
action.setAttributes(map);
56+
}
57+
58+
return resultMap;
59+
} catch (DocumentException e) {
60+
throw new IllegalStateException("failed to parse " + STRUTS_XML, e);
61+
} finally {
62+
if (in != null) {
63+
try {
64+
in.close();
65+
} catch (IOException e) {
66+
e.printStackTrace();
67+
}
68+
}
69+
}
70+
}
71+
72+
private static InputStream getStrutsInputStream() {
73+
StrutsParser.class.getPackage().getName();
74+
InputStream in = StrutsParser.class.getClassLoader()
75+
.getResourceAsStream("org/korben/coderising/litestruts/util/" + STRUTS_XML);
76+
if (in == null) {
77+
throw new IllegalStateException(STRUTS_XML + " doesn't exist");
78+
}
79+
80+
return in;
81+
}
82+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<struts>
3+
<action name="login" class="org.korben.coderising.litestruts.LoginAction">
4+
<result name="success">/jsp/homepage.jsp</result>
5+
<result name="fail">/jsp/showLogin.jsp</result>
6+
</action>
7+
<action name="logout" class="org.korben.coderising.litestruts.LogoutAction">
8+
<result name="success">/jsp/welcome.jsp</result>
9+
<result name="error">/jsp/error.jsp</result>
10+
</action>
11+
</struts>

0 commit comments

Comments
 (0)