review:
会使用框架,但不知来龙去脉,要掌握下面的代码逻辑递进
1.最初的做法是:一个请求对应一个Servlet,存在太多servlet
2.把一系列的请求对应一个Servlet,IndexServlet、AddServlet、EditServlet、DelServlet、UpdateServlet
通过operate的值来决定调用哪一个 ___Servlet
优化一:
String operate = request.getParameter("operate");
if (StringUtil.isEmpty(operate)) {
operate = "index";
}
switch (operate) {
case "index":
index(request, response);
break;
case "add":
add(request, response);
break;
case "del":
del(request, response);
break;
case "edit":
edit(request, response);
break;
case "update":
update(request, response);
break;
default:
throw new RuntimeException("operate非法");
}
3.再上一个版本中,switch case语句随着项目业务扩大,servlet跟随变多而增加,出现代码冗余,
因此使用反射技术,规定operate的值与方法名一致,那么接受到的值是什么就表明我们需要调用对应的方法进行响应,
如果找不到,则抛出异常
优化二:
String operate = request.getParameter("operate");
if (StringUtil.isEmpty(operate)) {
operate = "index";
}
//获取当前类中所有的方法
Method[] methods = this.getClass().getDeclaredMethods();
for (Method m : methods) {
String methodName = m.getName();
if (operate.equals(methodName)) {
try {
//找到和operate同名的方法,通过反射技术调用它
m.invoke(this, request, response);
return ;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
throw new RuntimeException("operate非法");
4.再上一个版本中,我们使用了反射技术,但其实还是存在一定的问题,但是每一个servlet中都有类似的反射技术的代码,
因此继续抽取,设计了中央控制器类:DispatcherServlet
DispatcherServlet这个类的有两个作用:
1.从url定位到能够处理这个请求的controller组件:
1)从url中提取servletpath: /fruit.do -> fruit
2)根据fruit找到对应的组件:FruitController,这个对应的关系依据,存储在applicationContext.xml中
<bean id="fruit" class="com.yehuw.fruit.controllers.FruitController"></bean>
通过DOM技术我们去解析xml文件,在中央控制器中形成一个beanMap容器,用来存放所有的Controller组件
3)根据获取到的operate的值定位到我们FruitController中需要调用的方法
2.调用Controller组件中的方法:
1)获取参数
获取即将要调用的方法的参数签名信息:Parameter[] parameters = method.getParameters();
通过parameter.getName()获取参数的名称;
准备了Object[] parameterValues 这个数组用来存放对应的参数的参数值,
另外,我们需要考虑参数的类型问题,需要做类型转换,通过getType()获取参数的类型;
2)执行方法
method.setAccessible(true);
Object returnObj = method.invoke(controllerBeanObj, parameterValues);\
3)视图处理
String methodReturnStr = (String) returnObj;
if (methodReturnStr.startsWith("redirect:")) {
String redirectStr = methodReturnStr.substring("redirect:".length());
response.sendRedirect(redirectStr);
} else {
super.processTemplate(methodReturnStr, request, response);//比如: "edit"
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!