18.手写实现SpringMVC框架

 

SpringMVC的运行流程

1.用户发送请求至前端控制器DispatcherServlet

2.DispatcherServlet收到请求,调用HandlerMapping处理器映射器

3.HandlerMapping根据请求url找到相应的controller,生成controller对象及处理器拦截器(如果有则生成),一并返回给DispatcherServlet

4.DispatcherServlet通过HandlerAdapter处理器适配器调用controller

5.执行controller

6.controller执行完成返回ModelAndView

7.HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet

8.DispatcherServlet将ModelAndView传给ViewResolver视图解析器

9.ViewResolver解析后返回具体的View

10.DispatcherServlet对View进行渲染(即将模型数据填充至视图中)

11.DispatcherServlet响应用户

从上面可以看出,DispatcherServlet有接收请求、响应结果、转发等作用,DispatcherServlet可以减少组件之间的耦合度。

SpringMVC的九大组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
protected void initStrategies(ApplicationContext context) {
// 用于处理文件上传请求,处理方法是将普通的request包装成MultipartHttpServletRequest,MultipartHttpServletRequest可以直接调用getFile()方法获取file
initMultipartResolver(context);


// SpringMVC主要有两个地方用到了Locale:1.ViewResolver视图解析器,2.国际化资源或主题
initLocaleResolver(context);


// 用于解析主题。SpringMVC中一个主题对应一个properties文件,里面存放着和当前主题相关的所有资源,如图片、css等。SpringMVC的主题也支持国际化
initThemeResolver(context);


// 用来查找Handler
initHandlerMappings(context);


// 从名字上看,它就是一个适配器。Servlet需要的处理方法的结构是固定的,都是以request和response为参数的方法。HandlerAdapter可以让固定的Servlet处理方法调用灵活的Handler来进行处理
initHandlerAdapters(context);


// SpringMVC中专门对异常情况进行处理的方法
initHandlerExceptionResolvers(context);


// 有的Handler处理完后并没有设置View,也没有设置ViewName,这时就需要从request获取ViewName了,RequestToViewNameTranslator可以从request中获取ViewName,
initRequestToViewNameTranslator(context);


// ViewResoler用来将String类型的视图名和Locale解析为View类型的视图。View是用来渲染页面的,也就是将程序返回的参数填入模板里,生成html文件(也可能是其他类型的文件)
initViewResolvers(context);


// 用来管理FlashMap,FlashMap主要用在redirect重定向中传递参数
initFlashMapManager(context);

}

SpringMVC的设计思路

1.读取配置

SpringMVC本质上是一个Servlet,这个Servlet继承自HttpServlet。

FrameworkServlet负责初始化SpringMVC的容器,并将Spring容器设置为父容器。

为了读取web.xml中的配置,需要使用ServletConfig类,它代表当前Servlet在web.xml中的配置信息。

在web.xml中配置加载自定义手写的MyDispatcherServlet和读取配置文件。

2.初始化阶段

SpringMVC的DispatcherServlet的initStrategies()方法会初始化9大组件。自定义的DispatcherServlet会初始化其中最基本的组件,按顺序包括:

(1) 加载配置文件

(2) 扫描用户配置的包下面所有的类

(3) 获取扫描到的类,通过反射机制实例化,并放到IoC容器(Map的键值对beanName-beanInstance)中,beanName默认是首字母小写。

(4) 初始化handlerMapping,这里其实就是把url和method对应起来放在一个Map中,在运行阶段取出

3.运行阶段

每一次请求都将会调用doGet()或doPost()方法,所以运行阶段统一都放在doDispatcher()方法里处理,它会根据请求url去HandlerMapping中匹配到对应的Method,然后利用反射机制调用url对应的controller中的方法,并得到结果返回。按顺序包括以下功能:

(1) 异常的拦截

(2) 获取请求传入的参数并处理参数

(3) 从初始化好的HandlerMapping中拿出url对应的方法,利用反射机制调用相应的方法。

手写实现SpringMVC的项目

项目目录结构:

项目依赖包只需要1个:

servlet-api.jar

核心在于对DispatcherServlet的实现:

1.初始化,读取配置文件,获取注解信息,根据注解信息创建并存贮相应的对象

2.接收并处理用户请求

annotation

@Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.course.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 作用在类上面
@Target(ElementType.TYPE)
// 运行时有效
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {

String value() default "";
}

@RequestMapping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.course.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {

String value() default "";
}

@RequestParam

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.course.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

String value();
}

core: DispatcherServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
package com.course.core;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.course.annotation.Controller;
import com.course.annotation.RequestMapping;
import com.course.util.CommonUtil;

public class DispatcherServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

// 存储配置文件
private Properties properties = new Properties();
// 存储要反射的类名
private List<String> classNameList = new ArrayList<>();
// IoC容器
private Map<String, Object> ioc = new HashMap<>();
// 控制器映射器
private Map<String, Method> handlerMapping = new HashMap<>();
// 控制器对象集合
private Map<String, Object> controllerMap = new HashMap<>();

// 初始化
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);

// 1.加载application.properties
doLoadConfig(config.getInitParameter("contextConfigLocation"));
// 2.扫描用户设定的包下面的所有类
doScanner(properties.getProperty("basePackageScan"));
// 3.将扫描的类通过反射实例化,并放入到IoC容器中,beanName首字母小写
doInstance();
// 4.初始化HandlerMapping,将url与method进行对应
initHandlerMapping();

print();
}

// 1.加载application.properties
private void doLoadConfig(String initParameter) {
System.out.println("initParameter = " + initParameter);
InputStream resourceAsStream = this.getClass().getResourceAsStream("/" + initParameter);
System.out.println("resourceAsStream = " + resourceAsStream);
try {
// 读取配置文件
properties.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
resourceAsStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}

// 2.扫描用户设定的包下面的所有类
public void doScanner(String basePackagePath) {
// 将路径.转换为/
System.out.println("basePackagePath = " + basePackagePath);
String packagePath = basePackagePath.replace(".", "/");
System.out.println("packagePath = " + packagePath);

URL url = this.getClass().getResource("/" + packagePath);
String path = url.getFile();
System.out.println("path = " + path);

File file = new File(path);
File[] listFiles = file.listFiles();
// 递归遍历文件
if (listFiles != null && listFiles.length > 0) {
for (int i = 0; i < listFiles.length; i++) {
File fileTemp = listFiles[i];
if (fileTemp.isDirectory()) {
doScanner(basePackagePath + "." + fileTemp.getName());
} else {
String className = basePackagePath + "." + fileTemp.getName().replace(".class", "");
classNameList.add(className);
}
}
}

}

// 3.将扫描的类通过反射实例化,并放入到IoC容器中,beanName首字母小写
public void doInstance() {
// classNameList判断是否为空
if (classNameList == null || classNameList.size() == 0) {
return;
}

// 反射实例化类
for (String className : classNameList) {
try {
Class<?> clazz = Class.forName(className);
// 判断类是否有某个注解(@Controller)
boolean annotationPresent = clazz.isAnnotationPresent(Controller.class);
// 如果有该注解
if (annotationPresent) {
Object instance = clazz.newInstance();
// key: beanName
String beanName = CommonUtil.convertFirstLetterTolowerCase(clazz.getSimpleName());
System.out.println("beanName = " + beanName);
ioc.put(beanName, instance);
} else {
continue;
}

} catch (Exception e) {
e.printStackTrace();
// 如果出现异常,继续实例化其他类
continue;
}
}
}

// 4.初始化HandlerMapping,将url与method进行对应
public void initHandlerMapping() {
if (ioc == null || ioc.size() == 0) {
return;
}

for (String beanName : ioc.keySet()) {
Object object = ioc.get(beanName);
// 1.解析写在类上的@RequestMapping注解
// requestUrl的前缀,类的url
String baseUrl = "";
// 判断类里是否有@RequestMapping注解
boolean classAnnotationPresent = object.getClass().isAnnotationPresent(RequestMapping.class);
if (classAnnotationPresent) {
// 得到类的@RequestMapping注解对象,并取出@RequestMapping注解的value值
RequestMapping requestMappingAnnotation = object.getClass().getAnnotation(RequestMapping.class);
// 类上的@RequestMapping注解的value值
baseUrl = requestMappingAnnotation.value();

} else {
continue;
}

System.out.println("baseUrl = " + baseUrl);

// 解析类里的方法上的@RequestMapping注解
Method[] methods = object.getClass().getMethods();
if (methods != null && methods.length > 0) {
for (Method method : methods) {
boolean methodAnnotationPresent = method.isAnnotationPresent(RequestMapping.class);
if (methodAnnotationPresent) {
RequestMapping requestMappingAnnotation = method.getAnnotation(RequestMapping.class);
String methodMappingUrl = requestMappingAnnotation.value();
System.out.println("methodMappingUrl="+methodMappingUrl);

String requestMappingUrl = baseUrl + "/" + methodMappingUrl;
System.out.println("requestMappingUrl="+requestMappingUrl);
// url-method
handlerMapping.put(requestMappingUrl, method);
// url-controller
controllerMap.put(requestMappingUrl, object);
}
}
}

}
}

// post请求
@Override
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
doGet(httpServletRequest, httpServletResponse);
}

// get请求
@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
// 请求分发
Object doDispatcher = doDispatcher(httpServletRequest, httpServletResponse);
if (doDispatcher == null) {
// 跳转到错误页面
httpServletRequest.getRequestDispatcher("/Error.jsp").forward(httpServletRequest, httpServletResponse);
} else {
String dispatcherPath = "/" + doDispatcher.toString();
System.out.println("path = " + dispatcherPath);
// 跳转
httpServletRequest.getRequestDispatcher(dispatcherPath).forward(httpServletRequest, httpServletResponse);
}

}

// 请求分发
private Object doDispatcher(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
// 判断handlerMapping是否为空
if (handlerMapping.isEmpty()) {
return null;
}

// 获取请求的url
String requestURI = httpServletRequest.getRequestURI();
String contextPath = httpServletRequest.getContextPath();
System.out.println("requestURI = " + requestURI);
System.out.println("contextPath = " + contextPath);

requestURI = requestURI.replace(contextPath + "/", "");
requestURI = requestURI.substring(0, requestURI.lastIndexOf("."));
System.out.println("requestURI = " + requestURI);

// 根据请求的url从handlerMapping中取处理方法
Method method = handlerMapping.get(requestURI);
// 获取方法的参数列表
Class<?>[] parameterTypes = method.getParameterTypes();
// 获取请求的参数
Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
// 保存参数值
Object[] paramValues = new Object[parameterTypes.length];
// 方法的参数列表
for (int i = 0; i < parameterTypes.length; i++) {
String simpleName = parameterTypes[i].getSimpleName();
if (simpleName.equals("HttpServletRequest")) {
paramValues[i] = httpServletRequest;
continue;
}
if (simpleName.equals("HttpServletResponse")) {
paramValues[i] = httpServletResponse;
continue;
}
if (simpleName.equals("Integer")) {
for (String key : parameterMap.keySet()) {
String[] valueArray = parameterMap.get(key);
String valueStr = Arrays.toString(valueArray);
String paramStr = valueStr.substring(1, (valueStr.length()-1));
// 如果参数值能正常转化为Integer类型,则为Integer类型的参数
try {
Integer paramInteger = Integer.parseInt(paramStr);
paramValues[i] = paramInteger;
System.out.println("Integer value = " + paramInteger);
} catch (NumberFormatException e) {
continue;
}
}
}
if (simpleName.equals("String")) {
for (String key : parameterMap.keySet()) {
String[] valueArray = parameterMap.get(key);
String valueStr = Arrays.toString(valueArray);
String paramStr = valueStr.substring(1, (valueStr.length()-1));
// 如果参数值转化为String类型时抛出异常,则为String类型的参数
try {
Integer.parseInt(paramStr);
continue;
} catch (NumberFormatException e) {
paramValues[i] = paramStr;
System.out.println("String value = " + paramStr);
}
}
}

}

// 使用反射调用方法
Object invoke = null;
try {
// invoke()的第一个参数为方法所在的类的实例
invoke = method.invoke(controllerMap.get(requestURI), paramValues);
} catch (Exception e) {
e.printStackTrace();
}

return invoke;
}

private void print() {
System.out.println("classNameList=" + classNameList);
System.out.println("ioc=" + ioc);
System.out.println("handlerMapping=" + handlerMapping);
System.out.println("controllerMap=" + controllerMap);

}

}

util

1
2
3
4
5
6
7
8
9
10
11
12
package com.course.util;

public class CommonUtil {

public static String convertFirstLetterTolowerCase(String str) {
char[] charArray = str.toCharArray();
// ASCII码转换
charArray[0] += 32;
return String.valueOf(charArray);
}

}

controller

UserController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.course.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.course.annotation.Controller;
import com.course.annotation.RequestMapping;
import com.course.annotation.RequestParam;

@Controller
@RequestMapping("myUser")
public class UserController {

@RequestMapping("addUser")
public String addUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("addUser");
return "addUser.jsp";
}

@RequestMapping("updateUser")
public String updateUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, @RequestParam("id") Integer id, @RequestParam("name") String name) {
System.out.println("updateUser");
System.out.println("controller updateUser() id = " + id);
System.out.println("controller updateUser() name = " + name);
return "updateUser.jsp";
}

@RequestMapping("deleteUser")
public String deleteUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("deleteUser");
return "deleteUser.jsp";
}

@RequestMapping("getUser")
public String getUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("getUser");
return "getUser.jsp";
}

}

DepartmentController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.course.controller.company;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.course.annotation.Controller;
import com.course.annotation.RequestMapping;

@Controller
@RequestMapping("department")
public class DepartmentController {

private String prefixPath = "jsp/company/";

@RequestMapping("addDepartment")
public String addUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("DepartmentController addDepartment()");
return prefixPath + "addDepartment.jsp";
}

@RequestMapping("updateDepartment")
public String updateUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("DepartmentController updateDepartment()");
return prefixPath + "updateDepartment.jsp";
}

@RequestMapping("deleteDepartment")
public String deleteUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("DepartmentController deleteDepartment()");
return prefixPath + "deleteDepartment.jsp";
}

@RequestMapping("getDepartment")
public String getUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("DepartmentController getDepartment()");
return prefixPath + "getDepartment.jsp";
}

}

其他controller与DepartmentController类似

config

application.properties

1
basePackageScan=com.course.controller

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>12_springmvc_manual</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<!-- 配置前端控制器 -->
<servlet>
<servlet-name>myspringmvc</servlet-name>
<servlet-class>com.course.core.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>application.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>myspringmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

</web-app>
``

### jsp

addUser.jsp

``` jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
add User
</body>
</html>

updateUser.jsp

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
update User
</body>
</html>

addDepartment.jsp

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Add Department
</body>
</html>

Error.jsp

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Error page
</body>
</html>

其他jsp类似

运行结果

项目启动时的初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
initParameter = application.properties
resourceAsStream = java.io.ByteArrayInputStream@1f4fe729
basePackagePath = com.course.controller
packagePath = com/course/controller
path = /E:/Tomcat_8.5/program/apache-tomcat-8.5.60/webapps/12_springmvc_manual/WEB-INF/classes/com/course/controller/
basePackagePath = com.course.controller.company
packagePath = com/course/controller/company
path = /E:/Tomcat_8.5/program/apache-tomcat-8.5.60/webapps/12_springmvc_manual/WEB-INF/classes/com/course/controller/company/
basePackagePath = com.course.controller.school
packagePath = com/course/controller/school
path = /E:/Tomcat_8.5/program/apache-tomcat-8.5.60/webapps/12_springmvc_manual/WEB-INF/classes/com/course/controller/school/
beanName = departmentController
beanName = employeeController
beanName = studentController
beanName = teacherController
beanName = userController
baseUrl = myUser
methodMappingUrl=getUser
requestMappingUrl=myUser/getUser
methodMappingUrl=updateUser
requestMappingUrl=myUser/updateUser
methodMappingUrl=deleteUser
requestMappingUrl=myUser/deleteUser
methodMappingUrl=addUser
requestMappingUrl=myUser/addUser
baseUrl = department
methodMappingUrl=getDepartment
requestMappingUrl=department/getDepartment
methodMappingUrl=updateDepartment
requestMappingUrl=department/updateDepartment
methodMappingUrl=deleteDepartment
requestMappingUrl=department/deleteDepartment
methodMappingUrl=addDepartment
requestMappingUrl=department/addDepartment
baseUrl = employee
methodMappingUrl=getEmployee
requestMappingUrl=employee/getEmployee
methodMappingUrl=updateEmployee
requestMappingUrl=employee/updateEmployee
methodMappingUrl=deleteEmployee
requestMappingUrl=employee/deleteEmployee
methodMappingUrl=addEmployee
requestMappingUrl=employee/addEmployee
baseUrl = teacher
methodMappingUrl=getTeacher
requestMappingUrl=teacher/getTeacher
methodMappingUrl=updateTeacher
requestMappingUrl=teacher/updateTeacher
methodMappingUrl=deleteTeacher
requestMappingUrl=teacher/deleteTeacher
methodMappingUrl=addTeacher
requestMappingUrl=teacher/addTeacher
baseUrl = student
methodMappingUrl=getStudent
requestMappingUrl=student/getStudent
methodMappingUrl=updateStudent
requestMappingUrl=student/updateStudent
methodMappingUrl=deleteStudent
requestMappingUrl=student/deleteStudent
methodMappingUrl=addStudent
requestMappingUrl=student/addStudent
classNameList=[com.course.controller.company.DepartmentController, com.course.controller.company.EmployeeController, com.course.controller.school.StudentController, com.course.controller.school.TeacherController, com.course.controller.UserController]
ioc={userController=com.course.controller.UserController@184658fc, departmentController=com.course.controller.company.DepartmentController@36a730b2, employeeController=com.course.controller.company.EmployeeController@5da2d806, teacherController=com.course.controller.school.TeacherController@280dd7fa, studentController=com.course.controller.school.StudentController@226fbbf}
handlerMapping={employee/getEmployee=public java.lang.String com.course.controller.company.EmployeeController.getUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), myUser/updateUser=public java.lang.String com.course.controller.UserController.updateUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.Integer,java.lang.String), department/getDepartment=public java.lang.String com.course.controller.company.DepartmentController.getUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), department/deleteDepartment=public java.lang.String com.course.controller.company.DepartmentController.deleteUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), student/addStudent=public java.lang.String com.course.controller.school.StudentController.addUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), teacher/updateTeacher=public java.lang.String com.course.controller.school.TeacherController.updateUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), department/addDepartment=public java.lang.String com.course.controller.company.DepartmentController.addUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), myUser/getUser=public java.lang.String com.course.controller.UserController.getUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), department/updateDepartment=public java.lang.String com.course.controller.company.DepartmentController.updateUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), student/getStudent=public java.lang.String com.course.controller.school.StudentController.getUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), student/updateStudent=public java.lang.String com.course.controller.school.StudentController.updateUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), teacher/deleteTeacher=public java.lang.String com.course.controller.school.TeacherController.deleteUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), myUser/deleteUser=public java.lang.String com.course.controller.UserController.deleteUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), employee/addEmployee=public java.lang.String com.course.controller.company.EmployeeController.addUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), teacher/getTeacher=public java.lang.String com.course.controller.school.TeacherController.getUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), employee/updateEmployee=public java.lang.String com.course.controller.company.EmployeeController.updateUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), student/deleteStudent=public java.lang.String com.course.controller.school.StudentController.deleteUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), employee/deleteEmployee=public java.lang.String com.course.controller.company.EmployeeController.deleteUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), myUser/addUser=public java.lang.String com.course.controller.UserController.addUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse), teacher/addTeacher=public java.lang.String com.course.controller.school.TeacherController.addUser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)}
controllerMap={employee/getEmployee=com.course.controller.company.EmployeeController@5da2d806, myUser/updateUser=com.course.controller.UserController@184658fc, department/getDepartment=com.course.controller.company.DepartmentController@36a730b2, department/deleteDepartment=com.course.controller.company.DepartmentController@36a730b2, student/addStudent=com.course.controller.school.StudentController@226fbbf, teacher/updateTeacher=com.course.controller.school.TeacherController@280dd7fa, department/addDepartment=com.course.controller.company.DepartmentController@36a730b2, myUser/getUser=com.course.controller.UserController@184658fc, department/updateDepartment=com.course.controller.company.DepartmentController@36a730b2, student/getStudent=com.course.controller.school.StudentController@226fbbf, student/updateStudent=com.course.controller.school.StudentController@226fbbf, teacher/deleteTeacher=com.course.controller.school.TeacherController@280dd7fa, myUser/deleteUser=com.course.controller.UserController@184658fc, employee/addEmployee=com.course.controller.company.EmployeeController@5da2d806, teacher/getTeacher=com.course.controller.school.TeacherController@280dd7fa, employee/updateEmployee=com.course.controller.company.EmployeeController@5da2d806, student/deleteStudent=com.course.controller.school.StudentController@226fbbf, employee/deleteEmployee=com.course.controller.company.EmployeeController@5da2d806, myUser/addUser=com.course.controller.UserController@184658fc, teacher/addTeacher=com.course.controller.school.TeacherController@280dd7fa}

接收用户请求:

addUser:

http://localhost:8080/12_springmvc_manual/myUser/addUser.do

1
2
3
4
5
requestURI = /12_springmvc_manual/myUser/addUser.do
contextPath = /12_springmvc_manual
requestURI = myUser/addUser
addUser
path = /addUser.jsp

updateUser:

http://localhost:8080/12_springmvc_manual/myUser/updateUser.do?id=20&name=xiaoming

http://localhost:8080/12_springmvc_manual/myUser/updateUser.do?name=xiaoli&id=10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
requestURI = /12_springmvc_manual/myUser/updateUser.do
contextPath = /12_springmvc_manual
requestURI = myUser/updateUser
Integer value = 20
String value = xiaoming
updateUser
controller updateUser() id = 20
controller updateUser() name = xiaoming
path = /updateUser.jsp

requestURI = /12_springmvc_manual/myUser/updateUser.do
contextPath = /12_springmvc_manual
requestURI = myUser/updateUser
Integer value = 10
String value = xiaoli
updateUser
controller updateUser() id = 10
controller updateUser() name = xiaoli
path = /updateUser.jsp

addDepartment:

http://localhost:8080/12_springmvc_manual/department/addDepartment.do

1
2
3
4
5
requestURI = /12_springmvc_manual/department/addDepartment.do
contextPath = /12_springmvc_manual
requestURI = department/addDepartment
DepartmentController addDepartment()
path = /jsp/company/addDepartment.jsp

其他url用户请求类似