Skip to content

Commit 6ffcefd

Browse files
author
vison.cao
committed
annotation dispatch
1 parent 682b553 commit 6ffcefd

File tree

11 files changed

+181
-68
lines changed

11 files changed

+181
-68
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
<artifactId>tomcat-websocket</artifactId>
5151
<version>${tomcat.version}</version>
5252
</dependency>
53+
<dependency>
54+
<groupId>org.reflections</groupId>
55+
<artifactId>reflections</artifactId>
56+
<version>0.9.12</version>
57+
</dependency>
5358
</dependencies>
5459

5560
<build>

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.vison.webmvc;
2+
3+
import java.lang.reflect.Method;
4+
5+
/**
6+
*
7+
* @author vison.cao <visonforcoding@gmail.com>
8+
*/
9+
public class Test {
10+
11+
public static void main(String[] args) throws Exception {
12+
Class stdClass = Student.class;
13+
Method method = stdClass.getMethod("getScore", String.class);
14+
Object obj = stdClass.getDeclaredConstructor().newInstance();
15+
System.out.print(method.invoke(obj, "888"));
16+
}
17+
18+
}
19+
20+
class Student extends Person {
21+
22+
public int getScore(String type) {
23+
return 99;
24+
}
25+
26+
private int getGrade(int year) {
27+
return 1;
28+
}
29+
}
30+
31+
class Person {
32+
33+
public String getName() {
34+
return "Person";
35+
}
36+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.vison.webmvc.controller;
2+
3+
import com.vison.webmvc.framework.GetMapping;
4+
import javax.servlet.http.HttpServletRequest;
5+
import javax.servlet.http.HttpServletResponse;
6+
7+
/**
8+
*
9+
* @author vison.cao <visonforcoding@gmail.com>
10+
*/
11+
public class UserController {
12+
13+
public UserController() {
14+
}
15+
16+
@GetMapping(path = "/user/profile")
17+
public String profile(HttpServletRequest request, HttpServletResponse response) {
18+
return "i am user profile";
19+
}
20+
21+
}
Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package com.vison.webmvc.framework;
22

33
import java.io.IOException;
4-
import java.io.PrintWriter;
5-
import java.util.HashMap;
6-
import java.util.Map;
4+
import java.lang.reflect.Method;
5+
import java.lang.reflect.Parameter;
6+
import java.util.Set;
77
import javax.servlet.ServletException;
88
import javax.servlet.annotation.WebServlet;
99
import javax.servlet.http.HttpServlet;
1010
import javax.servlet.http.HttpServletRequest;
1111
import javax.servlet.http.HttpServletResponse;
12+
import javax.servlet.http.HttpSession;
13+
import org.reflections.Reflections;
14+
import org.reflections.scanners.MethodAnnotationsScanner;
15+
import org.reflections.util.ClasspathHelper;
16+
import org.reflections.util.ConfigurationBuilder;
17+
import org.reflections.util.FilterBuilder;
18+
import org.apache.logging.log4j.Logger;
19+
import org.apache.logging.log4j.LogManager;
1220

1321
/**
1422
*
@@ -17,9 +25,7 @@
1725
@WebServlet(name = "DispatchServlet", urlPatterns = {"/"})
1826
public class DispatchServlet extends HttpServlet {
1927

20-
private Map<String, GetDispatcher> getMappings = new HashMap<>();
21-
private Map<String, PostDispatcher> postMappings = new HashMap<>();
22-
private ViewEngine viewEngine;
28+
private static final Logger log = LogManager.getLogger(DispatchServlet.class.getName());
2329

2430
@Override
2531
public void init() throws ServletException {
@@ -31,10 +37,81 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
3137
resp.setContentType("text/html");
3238
resp.setCharacterEncoding("UTF-8");
3339
String path = req.getRequestURI().substring(req.getContextPath().length());
34-
log(path);
35-
resp.getWriter().write(path);
40+
Object res = dispatch(path, req, resp);
41+
String responseBody = this.handInvokeRes(res);
42+
resp.getWriter().write(responseBody);
3643
resp.getWriter().flush();
37-
// 根据路径查找GetDispatcher:
38-
// 调用Controller方法获得返回值:
44+
}
45+
46+
private Object dispatch(String path, HttpServletRequest request, HttpServletResponse response) {
47+
Method method = this.getMaps(path);
48+
log.info(method);
49+
Object res = null;
50+
if (method != null);
51+
{
52+
Parameter[] parameters = method.getParameters();
53+
Object[] arguments = new Object[parameters.length];
54+
for (int i = 0; i < parameters.length; i++) {
55+
Parameter parameter = parameters[i];
56+
log.info(parameter.getType());
57+
Class<?> parameterClass = parameter.getType();
58+
String parameterName = parameter.getName();
59+
if (parameterClass == HttpServletRequest.class) {
60+
arguments[i] = request;
61+
} else if (parameterClass == HttpServletResponse.class) {
62+
arguments[i] = response;
63+
} else if (parameterClass == HttpSession.class) {
64+
arguments[i] = request.getSession();
65+
} else if (parameterClass == int.class) {
66+
arguments[i] = Integer.valueOf(getOrDefault(request, parameterName, "0"));
67+
} else if (parameterClass == long.class) {
68+
arguments[i] = Long.valueOf(getOrDefault(request, parameterName, "0"));
69+
} else if (parameterClass == boolean.class) {
70+
arguments[i] = Boolean.valueOf(getOrDefault(request, parameterName, "false"));
71+
} else if (parameterClass == String.class) {
72+
arguments[i] = getOrDefault(request, parameterName, "");
73+
} else {
74+
throw new RuntimeException("Missing handler for type: " + parameterClass);
75+
}
76+
}
77+
Object obj;
78+
try {
79+
obj = method.getDeclaringClass().getDeclaredConstructor().newInstance();
80+
res = method.invoke(obj, arguments);
81+
} catch (Exception e) {
82+
log.error("方法invoke失败", e);
83+
}
84+
}
85+
return res;
86+
}
87+
88+
private String getOrDefault(HttpServletRequest request, String name, String defaultValue) {
89+
String s = request.getParameter(name);
90+
return s == null ? defaultValue : s;
91+
}
92+
93+
private String handInvokeRes(Object obj) {
94+
if (obj instanceof String) {
95+
return (String) obj;
96+
}
97+
return "";
98+
}
99+
100+
private Method getMaps(String path) {
101+
String packageName = "com.vison.webmvc.controller";
102+
ConfigurationBuilder config = new ConfigurationBuilder();
103+
config.filterInputsBy(new FilterBuilder().includePackage(packageName));
104+
config.addUrls(ClasspathHelper.forPackage(packageName));
105+
config.setScanners(new MethodAnnotationsScanner());
106+
Reflections f = new Reflections(config);
107+
Set<Method> resources = f.getMethodsAnnotatedWith(GetMapping.class);
108+
109+
for (Method method : resources) {
110+
GetMapping annotation = method.getAnnotation(GetMapping.class);
111+
if (path.equals(annotation.path())) {
112+
return method;
113+
}
114+
}
115+
return null;
39116
}
40117
}

src/main/java/com/vison/webmvc/framework/GetDispatcher.java

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.vison.webmvc.framework;
2+
3+
import java.lang.annotation.*;
4+
5+
/**
6+
*
7+
* @author vison.cao <visonforcoding@gmail.com>
8+
*/
9+
@Target({ElementType.METHOD, ElementType.TYPE})
10+
@Retention(RetentionPolicy.RUNTIME)
11+
@Documented
12+
@Inherited
13+
public @interface GetMapping {
14+
15+
String path() default "";
16+
17+
}

src/main/java/com/vison/webmvc/framework/ModelAndView.java

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/main/java/com/vison/webmvc/framework/PostDispatcher.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/main/java/com/vison/webmvc/framework/ViewEngine.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/main/resources/log4j2.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Configuration status="WARN">
3+
<Appenders>
4+
<Console name="Console" target="SYSTEM_OUT">
5+
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
6+
</Console>
7+
</Appenders>
8+
9+
<Loggers>
10+
<Root level="info">
11+
<AppenderRef ref="Console" />
12+
</Root>
13+
</Loggers>
14+
</Configuration>

0 commit comments

Comments
 (0)