![[mvc01.png]]
变成
再变成
-
首先将多个servlet类合并成一个servlet类,原先的servlet类的功能成为这个servlet类的方法,统一由一个servlet根据请求调用
-
将switch选择调用方法的模式,改为利用反射获得method【】调用,避免了方法过多而导致switch的选项过长的短板
-
之后只会留一个DisptcherServlet,其他servlet全部变成…Controller,Servlet接受请求调用Controller,这里要用到一个新的配置文件[[XML]]
-
为了能够让Controller能够处理对应的请求,比如fruiltController操作与fruilt相关的请求 我们这里要用到 [[DocumentBuilderFactory]]
-
现在我总结一下这个流程p41-p42
- 首先在DisptcherServlet中获得请求路径
- 然后解析路径获得一个id
- 这个id通常是一个类的对应id,他完成了请求想要的功能
- 通过beanMap用id获得Controller类对象
- 再调用Controller类的方法
然后会变成这样
- 继续优化,因为在一个Controller中有多个方法最终都有resq.sendRedirect这个方法,这个可以整合,也就是提取视图资源,我们让方法放回一个字符串给中央控制器(DispatcherServlet),这个字符串中就是"redirect:xxx",中央控制器收到后,判断方法返回字符串中是否有redirect:,截取出这个字符串中xxx的部分,由中央控制器完成redirect跳转,这样其他控制器就不用管理页面的跳转了,这样Controller就不要reponse参数了,降低了耦合度,如果controller继续优化,连request参数也不要,那么Controller就不需要继承httpServlet了,已经完全变成了一个普通类
- 继续优化,下一步剔除Controller中的request参数,因为我们大部分都是用request来获取请求中的参数,所以我们让中央控制器来接收请求,由它获取参数传递给Controller,这个则是由反射实现,java8中的新特性让我们在用反射获取方法的参数列表时,可以直接得到参数的名字,然后再用反射调用方法,传入该方法的参数,完成业务
- 这样就完成了Controller只是作为一个普通类,而Controller中的方法用来完成功能
- 以上是我自己的思路想法,也是mvc优化的核心
老师总结
- 最初的做法:一个请求对应一个servlet,这样存在的问题是servlet太多了
- 把一系列请求都对应一个servlet,IndexServlet/AddServlet/… -> 合并为fruiltServlet,通过一个operate的值来决定调用FruiltServlet中的哪一个方法
- 在上一个版本中,servlet中充斥着大量的switch-case ,想一下,如果业务规模大,那么有很多servlet,servlet中又有很多switch,造成代码冗余因此我们采用反射技术,我们规定operate的值和方法名一致,那接收到的operate的值是什么就表明我们需要调用什么方法
- 在上一个版本中我们使用了反射技术,但还是存在一定问题:每一个servlet都有类似的反射技术的代码。因此继续抽取,设计了中央控制器DispacherServlet,这个类的工作分为两大部分
- 根据url定位到能够处理这个请求的Controller组件:
- 从url中提取servletpath : /fruilt.do -> fruilt
- 根据fruilt找到对应组件:fruiltController,这个依据我们储存在applicationContext.xml中
<bean id="fruilt" class="fruiltController">
,通过DOM技术我们解析xml文件,在控制器中形成一个beanMap容器来存放所有的Controller组件 - 根据获取到的operate的值定位到我们FruiltController中需要调用的方法
- 调用Controller中的方法
- 获取参数
- 获取即将要调用方法的参数签名信息:Parameter[] parameters = method.getParameters();
- 通过parameter.getName()获取参数的名称,通过parameter.getType()来获取参数类型
- 准备了Object[] parameterValues 这个数组来存放对应参数的参数值,另外需要做类型转化的工作
- 执行方法
- Object returnobj = method.invoke(ControllerBean,parameterValues);
- 视图处理
- String returnStr = (String)returnObj;
- if(returnStr.StartWith(“redirect:”)){…} 来实现页面跳转
- 获取参数
- 根据url定位到能够处理这个请求的Controller组件: