用实例学习MVC模式 (from 塞迪网)

1.1 MVC模式

MVC是三个单词的缩写,这三个单词分别为:模型(Model)、视图(View)和控制(Controller)。MVC模式的目的就是实现Web系统的职能分工。下面以J2EE开发进行介绍。

Model层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。View层用于与用户的交互,通常用JSP来实现。Controller层是Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。现在来看一个例子,看MVC模式是怎样工作的。

1.1.1 一个实例

例1-a:

< servlet >
      
< servlet-name > Controller </ servlet-name >
      
< servlet-class > nepalon.simplestruts.Controller </ servlet-class >
</ servlet >   
< servlet-mapping >
    
< servlet-name > Controller </ servlet-name >
    
< url-pattern > /simplestruts/servlet/control/Controller </ url-pattern >
</ servlet-mapping >

 上面是web.xml文件的片段,在这里定义了一个servlet用于处理请求。

例1-b(Test.jsp文件)

< html >
<% @ page contentType="text/html;charset=gb2312" %>  
< head >
< meta  http-equiv ="Content-Type"  content ="text/html; charset=gb2312" >
< title > 实例首页 </ title >
</ head >
< body >   
< table  border ="0"  width ="100%" >
  
< tr >  
< td >< div  align ="center" >
< href ="/simplestruts/servlet/control/Controller?command=showarticle" > 显示文章 </ a >
</ div ></ td >
  
</ tr >
</ table >
</ body >
</ html >

在这个JSP中,我们并没有直接去调用JSP或JavaBean,而是把请求分送到Servlet中。下面,我们来看看Servlet的代码。

例1-c:

package  nepalon.simplestruts;
/**
 * <p>Title: MVC framework</p>
 * <p>Description: Controller<p>
 * <p>Copyright: R2003</p>
 * 
@author Nepalon
 * 
@version 1.0
 
*/


import  javax.servlet. * ;
import  javax.servlet.http. * ;
import  java.io. * ;
import  java.util. * ;


public   class  Controller  extends  HttpServlet  
{

    
public void init(ServletConfig config) throws ServletException 
    
{
        
super.init(config);
    }


    
public void destroy() {}

    
/** 用于处理HTTP的GET和POST请求的函数
    * 
@param request servlet request
    * 
@param response servlet response
    
*/

    
protected void processRequest(HttpServletRequest request,HttpServletResponse response)
        
throws ServletException, java.io.IOException 
    
{        
        
//代码(1)通过if来实现对不同请求的分发 
        if(request.getParameter("command").equals("showarticle"))
        
{
            ArticleCommand command 
= new ArticleCommand();
            next 
= command. getAllArticle (request, response);
        }

        
//代码(2)
        dispatch(request, response, next);
    }

    
    
protected void doGet(HttpServletRequest request,
                        HttpServletResponse response)
        
throws ServletException, java.io.IOException 
    
{
        processRequest(request, response);
    }

    
    
protected void doPost(HttpServletRequest request,
                         HttpServletResponse response)
        
throws ServletException, java.io.IOException 
    
{
        processRequest(request, response);
    }


    
/** 一个实现了分发者模式的函数
    * 
@param request servlet request
    * 
@param response servlet response
    
*/

    
protected void dispatch(HttpServletRequest request,
                           HttpServletResponse response,
                           String page)
        
throws  javax.servlet.ServletException, java.io.IOException 
    
{
        RequestDispatcher dispatcher 
=
            getServletContext().getRequestDispatcher(page);
        dispatcher.forward(request, response);
    }

}

在Servlet中并没有直接处理所提交的请求,而是把请求的处理推后到ArticleCommand类中,通过ArticleCommand对象来执行,如代码(1)。在处理完请求后,转到相应的页面中,如代码(2)。下面,我们看一下ArticleCommand类的代码。

例1-d:

package  nepalon.simplestruts;

/**
 * <p>Title: MVC framework</p>
 * <p>Description: 文章业务类<p>
 * <p>Copyright: R2003</p>
 * 
@author Nepalon
 * 
@version 1.0
 
*/


import  java.util. * ;
import  javax.servlet. * ;
import  java.io. * ;
import  java.lang. * ;
import  java.sql. * ;
import  javax.sql. * ;

public   class  ArticleCommand
{
    
public ArticleCommand() {}
    
public String getAllArticle(HttpServletRequest request, HttpServletResponse response)
          
throws javax.servlet.ServletException, java.io.IOException
    
{
         Connection conn
=null;
        String con_user 
= "example1";
        String con_password 
= "example1";
        String con_dburl 
= "jdbc:oracle:thin:@localhost:iasdb";
        String con_driver 
= "oracle.jdbc.driver.OracleDriver";
        PreparedStatement pstmt
=null;
        ResultSet rsComment
=null;    
        Vector vectorComment 
= new Vector();
        String selectSQL
= "SELECT content, time FROM article ORDER BY time DESC";
        
try
        
{
             DriverManager.registerDriver(
new oracle.jdbc.driver.OracleDriver());
             Class.forName(con_driver);
             conn 
= DriverManager.getConnection(con_dburl,con_user,con_password);
             pstmt
=conn.prepareStatement(selectSQL);
             rsComment
=pstmt.executeQuery();
             
while(rsComment.next()) 
             
{
                   CommentItem commentItem 
= new CommentItem();
                commentItem.setContent(rsComment.getString(
1));
                commentItem.setTime(rsComment.getDate(
2));
                vectorComment.add(commentItem);
             }

             vectorComment.trimToSize();
          }

        
catch (Exception e){//做相应的处理}
        
//代码(1)保存处理结果并返回跳转页面
        request.setAttribute("vectorComment ", vectorComment);
        
return "/simplestruts/showallarticle.jsp";
}

……
public String getNewArticle(HttpServletRequest request, HttpServletResponse response)
          
throws javax.servlet.ServletException, java.io.IOException
    
{…}
}
在这个类中进行的是取得所有文章的业务,最后返回如果成功执行操作后要跳转到的页面。当然,这个类中可能还有别的业务的相应函数,读者可自己实现。下面看一下要跳转到的页面的代码。

 

例1-e(showallarticle.jsp文件):

< html >
<% @ page contentType="text/html;charset=gb2312" %>  
<% @ page import="java.util.*, java.lang.*" %>
< jsp:useBean  id ="vectorComment"  type ="java.util.Vector"  scope ="request" />
< head >
< meta  http-equiv ="Content-Type"  content ="text/html; charset=gb2312" >
< title > 显示文章 </ title >
</ head >
< body >   
< table  border ="0"  width ="100%" >
    
  
< tr >  
    
< td > 发表时间 </ td >
        
< td > 文章内容 </ td >
  
</ tr >
<%        
    
if (vectorComment!=null && vectorComment.size()>0
    {        
        
int counter=vectorComment.size();    
        CommentItem commentlist 
= null;    
        
for (int i=0;i<counter;i++)
        {                                                             
             commentlist
=null;        
             commentlist
=(CommentItem)(vectorComment.get(i));     
%>  
  
< tr >  
    
< td > <% = commentlist.getCmTime() %> </ td >
        
< td > <% = commentlist.getCmContent() %> </ td >
  
</ tr >
<%
        }
    }
%>
</ table >
</ body >
</ html >

在这个JSP中我们要做的只是取得结果并显示,没有涉及到相应的业务逻辑。

实例分析

首先,我们看一下这个例子的序列图

1) 首先在Veiw层的test.jsp中提交一个请求/simplestruts/servlet/control/Controller?command=showarticle;

2) 在Controller层的Controller对象中,根据请求的类型来调用相应的业务处理类,在这里,command值为showarticle的请求的业务处理类为ArticleCommand类,所以调用该类的对象的相应函数;

3) 在Model层的ArticleCommand类主要实现请求的取得所有文章的业务功能,把结果保存在request中,并返回跳转页面作为返回值;

4) 回到Controller层的Controller对象,根据上一步骤的返回值进行页面转发。

5) 转发到View层的showallarticle.jsp页面,这个页面从request中取得结果并进行显示。在这个JSP中虽然也有Java代码,但这些代码只是用于显示结果,并没有涉及到任何业务逻辑。

MVC模式的好处

本来这样一个简单的功能我们只需要2个JSP文件就能实现了,为什么要这么麻烦把它分到几个类中去实现呢?现在就来看一下MVC模式带来的好处。

1) 各施其职,互不干涉
在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。假如业务发生了变化,如在取文章时可能webmaster把一些文章作了无效标志,不能直接把所有文章取出来,只能取出有效的文章,这时业务就发生了改变。再设想一下,如果这个业务逻辑在100个页面中都要用到,那么MVC模式就体现了它的灵活性。我们可以不更改任何JSP,只要更改model层中的相应类中的SQL语句即可。

2) 有利于开发中的分工
在MVC模式中,由于按层把系统开,那么就能更好的实现开发中的分工。网页设计人员可以进行开发视图层中的JSP,对业务熟悉的开发人员可开发业务层,而其它开发人员可开发控制层。

3) 有利于组件的重用
分层后更有利于组件的重用。如控制层可独立成一个能用的组件,视力层也可做成通用的操作界面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值