
1)MVC是一种流行的程序架构,包含三个部分:模型(Model) 、视图(View)、控制器(Control) 。
2)M模型主要由Entity(数据载体),Dao(修改数据),Biz/Service(复杂业务模型)等组成。Dao和Biz负责将数据加载到Entity中,以及将传递过来的Entity(数据载体)更新到数据库(当然也可能是文件)中
3)C控制器主要由一些类组成,负责接收和判断用户输入,调用相应的模型,加载和更新数据,将Entity传递到相应的V视图
4)V视图,可能是特定的窗体或网页,只负责将C传递过来的Entity数据展现给用户
5)3个部分各施其职,互不干扰,低耦合,任何部分发生改动,都不会影响另外部分
MVC模式的优点:
(1)同一模型的多个视图。 将模型和用户界面分离。多视图可以在单一的模型中实现
(2)同步化视图。 变更-传播机制确保了所有加入的观察者可以在正确的时间被告知应用程序的数据变化
(3)可插入的视图和控制器。 允许动态/静态地交换模型的视图和控制器对象。
(4)式样和感觉的可交换性。 模型不依赖于具体的用户界面平台,因此系统的可移植性好。
(5)框架潜力。 可以开发这个模式的应用程序框架。
MVC模式的缺点:
(1)增加了复杂性。 有时获得的灵活性并不大,但是缺增加了复杂性
(2)潜在的过多的更新因素。 有时一个用户动作就导致很多更新。有些更新并不是所有视图都关系
(3)视图和控制器之间的紧密联系。
(4)视图和控制器与模型的紧密耦合。 视图和控制器直接调用模型。模型接口的改变会使得视图和控制器的代码过时
(5)视图中的数据访问的低效率。 数据访问依赖于模型接口。可能过多的访问不必要的数据。
(6)移植时对视图和控制器的修改是不可避免的。 视图和控制器中的软件包含了平台相关的东西。
(7)现代的用户接口工具使用MVC的困难性。 现代的用户接口工具中提供了预制的控制流管理,内部事件的处理等。
自定义WEB-MVC框架的实现
M-javaBean(pojo和dao)负责业务数据模型存取
V—JSP+Html负责生成动态网页
C—Servlet负责生成动态网页
1) 该MVC框架主要由五部分组成:
<1>、ControllerServlet.java:请求分发控制器,解析请求中的动作名字,调用动作工厂对象生成的动作对象处理请求,处理后返回的结果为目的URL,控制器再将请求和应答对象转向目标URL
<2>、ActionFactory.java:该工厂类将请求中的动作名转换成servlet可以用来完成其工作的动作类
<3>、Action.java:接口类,该接口定义所有动作的公共接口
<4>、具体Action的实现:指实现了Action接口的类,会被ActionFactory工厂根据请求中的名字创建,从而调用其具体实现的方法处理Reques\\Response对象后,返回一个URL,由主控servlet转发给用户。可以理解为一个具体的Action实现类用于处理页面上每一种用户点击(请求)
<5>、系统视图View层实现:*.JSP、*.HTML
2) 实现源码:
<1>控制器Servlet实现
Java代码
1.package wxy.MVCDemo.Servlet;
2.
3.import java.io.IOException;
4.import javax.servlet.ServletException;
5.import javax.servlet.http.HttpServlet;
6.import javax.servlet.http.HttpServletRequest;
7.import javax.servlet.http.HttpServletResponse;
8.
9.import wxy.MVCDemo.action.Action;
10.import wxy.MVCDemo.action.ActionFactory;
11.
12./**
13. * 系统控制器实现
14. * 功能:
15. * 1、解析请求中的命令名
16. * 2、根据请求的命令调用工厂对象创建命令处理对象
17. * 3、调用命令对象处理请求和应答对象,返回目标路径名
18. * 4、本控制器将请求和应答转发至目标路径名
19. * Servlet implementation class ControllerServlet
20. */
21.public class ControllerServlet extends HttpServlet {
22. private static final long serialVersionUID = 1L;
23.
24. public ControllerServlet() {
25. super();
26. }
27. /**
28. * 主控servlet分发用户请求的入口
29. */
30. public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
31. try{
32. //得到请求的命令名字:解析出*.do请求中*所指代的字符串,即动作名字
33. String ActionName=getActionName(request);
34. System.out.println("request Action is:"+ActionName);
35. //根据请求的动作名,得到控制器servlet中配置的Action实现类名字
36. String ActionClassName=this.getInitParameter(ActionName);
37. System.out.println("ActionClassName is:"+ActionClassName);
38. //通过工厂类创建命令对象
39. Action action=ActionFactory.getIns().getAction(ActionClassName);
40. //使用动作对象处理动作,返回结果为处理后要输出的目标页面
41. String URL=action.execute(request,response);
42. if(URL!=null){
43. //输出目标页面
44. System.out.println("dest URL is :"+URL);
45. getServletContext().getRequestDispatcher(URL).forward(request, response);
46. }
47. }catch(Exception e){
48. e.printStackTrace();
49. getServletContext().getRequestDispatcher("/error.jsp").forward(request, response);
50. }
51. }
52. /**
53. * 解析到请求中的“命令”字
54. * @param request
55. * @return
56. */
57. protected String getActionName(HttpServletRequest request) {
58. String path=request.getServletPath();
59. return path.substring(1,path.lastIndexOf("."));
60. }
61.}
<2>Action对象工厂类实现
Java代码
1.package wxy.MVCDemo.action;
2./**
3. * 命令对象工厂类实现
4. * 根据命令名字,创建命令对象
5. * ActionFactory是一个单实例类(整个系统只需要使用其一个对象)
6. * @author wxy
7. *
8. */
9.public class ActionFactory {
10. /**
11. * 单实例访问方法
12. * @return 单实例对象
13. */
14. public static ActionFactory getIns(){
15. if(null==ac){
16. ac=new ActionFactory();
17. }
18. return ac;
19. }
20. /**
21. * 根据具体的action类名字创建Action对象
22. * @param actionClass 具体的Action类全名
23. * @return Action类型对象
24. */
25. public Action getAction(String actionClass){
26. Action actionInstance=null;
27. try{
28. Class c=Class.forName(actionClass);
29. actionInstance=(Action)c.newInstance();
30. }catch(Exception e){
31. e.printStackTrace();
32. }
33. return actionInstance;
34. }
35. //不需要创建对象
36. private ActionFactory(){}
37. private static ActionFactory ac=null;
38.}
<3>Action接口类定义
Java代码
1.package wxy.MVCDemo.action;
2.
3.import javax.servlet.http.HttpServletRequest;
4.import javax.servlet.http.HttpServletResponse;
5.
6./**
7. * 系统中的命令处理器接口
8. * @author wxy
9. *
10. */
11.public interface Action {
12. /**
13. * 所有的具体Action实现这个接口
14. * @param request 请求对象
15. * @param reponse 应答对象
16. * @return 结果页面
17. */
18. public String execute(HttpServletRequest request,HttpServletResponse reponse);
19.}
web.xml配置
Java代码
1.
2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
<4>具体的Action实现类
Java代码
1.package wxy.MVCDemo.action;
2.
3.import javax.servlet.http.HttpServletRequest;
4.import javax.servlet.http.HttpServletResponse;
5.
6./**
7. * 由login.jsp输出账户密码,如果账号正确,则在Session中放入用户对象,转向主页;如果错误,转向登录页面
8. * @author wxy
9. *
10. */
11.public class LoginAction implements Action{
12.
13. public String execute(HttpServletRequest request,
14. HttpServletResponse reponse) {
15. String UserName=request.getParameter("UserName");
16. String pwd=request.getParameter("pwd");
17. //数据库操作
18. //..........
19. if(UserName.equals("wxy")&&pwd.equals("wxy")){
20. //将用户对象放入session
21. request.getSession().setAttribute("UserName", UserName);
22. return "/mainPage.jsp";
23. }
24. request.getSession().setAttribute("ERROR_MSG", "账号或者密码输入有误!");
25. return "/login.jsp";
26. }
27.
28.}
RegUserAction.do
DisplayMainPageAction.do
。。。
(记着在web.xml中配置)
<5>系统view层实现
login.jsp
Java代码
1.<%@ page language="java" contentType="text/html; charset=utf-8"
2. pageEncoding="utf-8"%>
3.
4.
5.
6.
7.
8.
9.
10.
15.
16.
mainPage.jsp
Java代码
1.<%@ page language="java" contentType="text/html; charset=utf-8"
2. pageEncoding="utf-8"%>
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
