前言:上次与大家分享了通用分页,只要记住通用分页核心思想,沿着核心思想来写通用分页。今天与大家分享的是自定义MVC和框架。接下来通过思维导图来讲解今天的知识。

?一、自定义MVC
? ? ? ? ? ? 1、自定义MVC的概念:MVC全称名是Model(模型层) View(视图层) control(控制层),可以这样理解,自定义MVC同时具有可以建造模型,看结果,以及控制,同时也具有高类聚,低耦合的特点。
? ? ? ? ? ? ?2、自定义MVC的作用:节省时间和代码。比如说:我们在写一个项目时,都是从无到有的,创建的过程要写好多代码,以及花费好多时间。所以我们会写一个MVC来继承它,从而得到通用的效果,以至于有更多的时间与精力去完成自己的项目。
? ? ? ? ? ? ? 3、为什么会有自定义MVC:我将用一张我自己写的思维导图来讲解为什么会有自定义MVC。

?如上图所示,当我们自己项目要去写这么多servlet以及dao包中的方法时,往往都会出现一个共同的问题,那就是代码思路基本重复,从而就诞生了自定义MVC。
? ? ? ? ? ? ? ?4、演绎过程:(演绎过程为处理servlet时的代码以及运行结果)
? ? ? ? ? ? ? ? ? ? ? ? 4.1:写4个servlet类(大多数人使用的情况):


?而servlet中的代码就有如下这么多,但其中doget()方法没有实际用处。
? ?运行结果:(只显示来增加方法的结果,其他三种的servlet都是会显示结果的,只是打印语句不一样)
? ? ? ? ? ? ? ? ? ? ? ??4.2:写一个BookServlet来写四种方法:
BookServlet:

?jsp界面代码:(Index):

?运行结果:(可以看到显示出了add,在web页面中点击其他连接也会显示出结果)

?web网页效果:

? ? ? ? ? ? ? ? ? ? ? ??4.3:用反射来解决Servlet类繁多问题:
BookServlet:(其中为反射的代码)

? 上图为显示结果时的打印代码
? ?jsp界面代码:(Index):

?运行结果:

二、自定义MVC框架:

? ? ? ? ? 如上图所示:自定义MVC工作原理图,图中actionservlet是中央控制器,action是子控制器,excute为子控制器中的方法。
1、优化子控制器:(在自己创建的类中,用action来命名)

? ? ? ? 首先跟大家申明各个类的用处:
? ? ? ? ? ? ? Action类:是子控制器的代表类(是一个接口,里面只有一个方法,就是excute方法,这个方法是一个抽象方法)

? ? ? ? ? ? ? Actionsupport类:是Action类的实现类,里面只要反射出要用的哪一个对象,同时反射出要用到什么方法(methodname)

? ? ? ? ? ? ? BookAction类:是子控制器下的最底层,这个类只专注做一件事,就是处理浏览器发送过来的请求,可以节约大量的时间。

?2、优化中央控制器:
? ? ? ? 2.1中央控制器的作用:将浏览器材和子控制器关联起来,就好比顾客到饭店去吃饭,不能直接和后台工作的厨师进行交流,而是先通过前台服务员进行交流,再由前台服务员告诉后台厨师,顾客点了什么菜。
? ? ? ? 2.2联系浏览器(顾客)
@WebServlet("*.action")
? ? ? ? ?2.3联系子控制器:? ? ? ? ?
? ? ? ? ? ? ?思路:? ? ? ? ? ? ? ? ? ? ? ?1、先通过uri来获取到要进行选哪个部门, ? ? ? ? ? ? ? ? ? ? ? ? ? ??例如:https://localhost:/book.action?methodname=add ? ? ? ? ? ? ? ? ? ? ? ? ? ??uri--->book ? ? ?? ? ? ? ? ? ? ? 2、通过book字符串来从actions这个集合中去找到bookaction ? ? ? ? ? ? ? ? ? ???3、通过bookaction来找到最后要用的方法
? ? ? ? ? ? ? ?代码:
String url = req.getRequestURI();
//拿到book
url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
ActionSupport action = actions.get(url);
action.excute(req, resp);
? ? ? ?? ? ??
? ? ? ? ? ? 2.4展示效果:?

? jsp页面展示效果:

?在Bookaction中的方法:
展示效果:(已展现效果,说明优化子控制器和中央控制器成功)

? ? ? ? ? ? 2.5 缺陷:在每一次顾客访问前台时,有很多个部门,比如说料理部门,财务部门,,每当访问一次要new一个此类,代码如下:
public void init() throws ServletException {
actions.put("/book", new BookAction());
actions.put("/goods", new GoodsAction());
}
? ? ? ? ? ?2.1 解决方案:通过建模的知识,到config文件进行操作:目的:使代码更加灵活

? ? ? ? ? 中央控制器中改进代码:
? ? ? ? ? ? ? ? ? 以前:
String url = req.getRequestURI();
//拿到book
url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
ActionSupport action = actions.get(url);
action.excute(req, resp);
? ? ? ? ? ? ? ? ? ?现在改进代码:
/**
* 1、通过url来找到config文件中对应的action对象
* 2、然后通过该对象来取到路径名servlet.BookAction
* 3、然后找到对应的方法执行
*/
String url = req.getRequestURI();
url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
ActionModel actionmodel=configModel.pop(url);
String type = actionmodel.getType();
ActionSupport action=null;
try {
action = (ActionSupport) Class.forName(type).newInstance();
action.excute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
? ? ? ? ? ? ? ? ? 改进思路:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1、通过url来找到config文件中对应的action对象 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2、然后通过该对象来取到路径名servlet.BookAction ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3、然后找到对应的方法执行
? ? ? ? ? ? ? ? 2.2:展示效果:(当自己点击列表删除时,出现了bookDao.delete()...中央控制器和子控制器优化效果在这效果,说明用建模的知识去优化中央控制器成功)?

三:解决上次遗留的两个问题
? ? ? ? ? 问题一:解决参数冗余问题:由于在做项目过程中,在servlet类中需要接受很多个参数值,所以就想到要解决当前参数冗余问题。比如:一个实体类Book当中有五个属性,那么你在进行修改时就要接受五个值,虽然每次接受语句中的属性值不一样,但从根本上来讲,性质是一样,要接收属性。如下所示:(当时此类没有实现Moderdriver接口)?

? ? ?运行效果:? ? ? ?
解决方案:建一个模型驱动接口,使Bookaction实现该接口,在中央控制器中将所有要接收的参数封装到模型接口中,从而达到简便的效果。
? ? ? ? ? ? ModelDriver类(驱动接口类):?

? ? ? ? ? ? ?中央控制器类:

? ? ? ? ? ? ?Bookaction类:(注意观察,在上一张同一个类图片,没有实现ModelDriver接口,而如下bookaction类实现了ModelDriver接口,把接受参数的五个属性值语句注释,达到了简便的效果)


? ? ? ? ? ? ?其中关于解决参数冗余问题关键代码是:
BeanUtils.populate(bean, req.getParameterMap());//将该对象要接受的参数值封装到对应的对象中
? ? ? ? ? ?问题二:解决跳转方式问题:在我们跳转到另一个界面时,需要许很多关于跳转方式的代码,有重定向,有转发,例如:
? ? ? ? ? ?重定向:resp.sendRedirect(path);
? ? ? ? ? ?转发: req.getRequestDispatcher(path).forward(req, resp);
这些代码往往要写很多次,因此通过配置config文件来解决此类问题;例如这一次我跳转增加页面时是转发,跳转编辑界面是重定向,

?在index界面的代码如下:
<hr>
解决遗留问题二
<a href="book.action?methodname=addB">增加</a>
<a href="book.action?methodname=toEdit">编辑</a>
思路:
? ? ? ? 1、当点击增加或者编辑时,首先跳转的是中央控制器类(DispatchServlet):? ? ? ? ? ? ? ? ? 获取到url,url将决定要跳到哪一个实体类,
? ? ? ? 2、之后进入ActionSupprot(子控制器接口实现类)通过methodname要调用什? ? ? ? ? ? ? ?么方法,
? ? ? ? 3、再然后进入到BookAction中调用methodname方法,找到对应的返回值,
? ? ? ? 4、通过返回值在进入到config文件找到path属性,之后在中央控制器中进行判? ? ? ? ? ? ? ? ? ? 断,来决定是重定向还是转发。
中央控制器(DispatchServlet):?

ActionSupprot(子控制器接口实现类):?

?BookAction(图中标记的为返回值):

?config文件(图中name为返回值,path为要跳转的界面路径名,redirect为跳转方式):

?bookAdd界面:

bookEdit界面:?

?运行结果:
? ? ? ?1、当点击增加时,跳转到bookAdd界面,显示效果如下(运行成功):

? ? ? 2.当点击编辑时,跳转到bookEdit界面,显示效果如下:

? ? ? ? ?报错原因:由上图所示,很明显丢失了路径名,丢失路径名为(T269_ZJ_MVC)因为重定向和转发的语句和方式不一样,所以导致报错;
? ? ? ? ?解决方案:在重定向语句中加入转发路径语句。
? ? ? ? ?原代码:

? ? ? ? ? 改进代码:

? ? ? ? ? ?改进代码之后的运行效果:

?上图所示:改进代码后(加入req.getContextPath())就运行成功了。
四:思维导图:同时在学知识的过程以自己的理解来绘制了一副思维导图:

?总结:在学习自定义MVC框架时,掌握自定义MVC工作原理图很重要,几乎所有的点都可以围绕这原理来讲,把原理图熟记于心,掌握自定义MVC框架就不远了。最后,如博客中有错误以及疏忽,请大神加以指点,祝大家生活愉快。
? ? ?
?
? ? ??
? ? ??
|