再战MVC(二)

转载 2007年09月22日 08:58:00
MVC模式在J2EE技术中的应用
  MVC模式并不能自动 保证一个结构设计是正确的,如何在一个系统的设计中正确地使用MVC架构模式与系统使用的技术有密切的关系。2EE中有几个核心的技术:JSP, JavaBean,Servlet,EJB,SessionBean,EntityBean构成了J2EE构架的基石,但是对于一个基于J2EE技术的 Web应用来说,如何正确地使用MVC模式不是一句话就能得出结论的。
一般而言,一个J2EE系统应当适当地划分接收请求,根据请求采取行动,并将结果显示给用户等责任。因此也就有了开发Web应用时经常提到的一个概念Model 1/Model 2,它是对采用JSP技术构成Web应用的不同模型的描述。
   Model 1架构
   <<Java与模式>>提到模型一又称做以JSP为中心(JSP Centric)的设计模型,它的架构图如下图所示:
 
从上图可以看出来,JSP是整个应用系统的门户。它身兼三职啊。1 负责与客户 端的所有通信 2处理所有的请求 3处理所有的答复。在处理答复的时候,从数据库中存取数据有两种方式,可以它自己直接去存取,也可以让一些 JavaBean来完成。因为JavaBean可以被放在一个请求上下文或者用户会话中,这样就可以在不同的JSP之间通信。当然这种模式在进行快速和需 求不是很复杂,规模较小的 Web应用是有很大的优势的,比如说:JSP页面可以非常容易地结合业务逻辑(jsp:useBean)、服务端处理过程(jsp:scriplet)和 HTML(<html>),在JSP页面中同时实现显示,业务逻辑和流程控制,从而可以快速地完成应用开发。
但是从工程化的角度考虑,它也有一些不足之处:把表现层和业务逻辑层柔和在一起,不利于以后的维护工作以及开发角色的分配,所以这种模式只能适合于小的系统开发。
Model 2架构
 Servlet/JSP 规范的0.92版描述了在一个应用中使用servlet 和 JSP 的架构。在其后的规范中,Model 2 这个叫法消失了,但它已经在Java web 开发人员中非常通用了。 <<Java与模式>>提到模型二又称做以Servlet为中心(Servlet Centric)的设计模型, 它的架构图如下图所示:
对比这个图跟Model 1的结构图,从 JSP这个角度来看,JSP页面至少少了二个任务即获取跟处理用户的请求,因为Servlet相当于控制器(Controller)角色,它负责接收客户 端请求并处理此请求,将它传递给合适的JSP,而JSP则显示给用户。所以JSP页面这时候主要做两件事情: JavaBean直接与数据库打交道取得数据后,JSP从JavaBean中读取数据,这是第一,第二件事情就是把结果返回给客户端。
根据Model 2,servlet 处理数据存取和导航流, JSP处理表现。Model 2 使Java 工程师和HTML设计者分别工作于它们所擅长和负责的部分。Model 2应用的一部分发生改变并不强求其他部分也跟着发生改变。HTML 开发人员可以改变程序的外观和感觉,并不需要改变后端servlet的工作方式。
网上找到了一个很好的例子来说声明:JSP能够生成HTML,WML甚至 XML,它对应于Web应用程序中的View部分。EJB作为数据库与应用程序的中介,提供了对数据的封装。一般SessionBean封装的是数据, EntityBean是封装对数据的操作。这两个部分合起来,对应于Web应用程序的Model部分。在技术上,JSP能够直接对EJB进行存取,但这并 不是好办法,那样会混淆程序中的显示逻辑和控制逻辑,使得JSP的重用性能降低。这时候有两种解决方法,通过JavaBean或者Servlet作为中介 的控制逻辑,对EJB所封装的数据进行存取。这时,JavaBean或者Servlet对应于Web引用程序中的Controller部分。两种类型的 Controller各有其优缺点:JSP同Servlet的交互不容易规范化,使得交互的过程变得复杂,但是Servlet可以单独同用户交互,实际上 JSP的运行时状态就是Servlet;而由于JavaBean的规范性,JSP同JavaBean的交互很容易,利用JavaBean的get/set 方法,JSP不需要过多的语句就可以完成数据的存取,这能够让JSP最大限度的集中在其视图功能上,而且,在桌面应用程序中使用JavaBean也很容 易,而用Servlet就相对麻烦许多。根据不同的问题背景,可以选取不同的Controller,有时候也可以两者混合使用,或者直接在Servlet 中调用JavaBean。
   任何一种解决方案都是双刃剑,在我们获得的同时必须有一定的付出。这种模式也带来了如下一些实际的问题:1. 必须基于MVC组件的方式重新思考和设计应用结构。原来通过建立一个简单的JSP页面就能实现的应用现在变成了多个步骤的设计和实现过程。 2.所有的页面和组件必须在MVC框架中实现,所以必须进行附加地开发工作。
对于用原生的Servlet API来开发Model 2的程序的例子我将转载JavaResearch论坛上的文章,研究下对MVC模式在J2EE系统中的应用有很大帮助的。
(转载自“用实例学习MVC模式 nepalon 原作 
下面以J2EE开发进行介绍。
Model
层实现系统中的业务逻辑,通常可以用JavaBeanEJB来实现。
View
层用于与用户的交互,通常用JSP来实现。
Controller
层是ModelView之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。
现在来看一个例子,看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-bTest.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">
<a href="/simplestruts/servlet/control/Controller?command=showarticle">
显示文章</a>
</div></td>
  </tr>
</table>
</body>
</html>
在这个JSP中,我们并没有直接去调用JSPJavaBean,而是把请求分送到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() {}

    /** 
用于处理HTTPGETPOST请求的函数
    * @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 Contribute
{
    public Contribute() {}
    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-eshowallarticle.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.1.2
 实例分析
首先,我们看一下这个例子的序列图
 
1.1.2-1
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本身就是一个非常复杂的系统,所以采用MVC实现Web应用时,如果采用现成的MVC框架,在此之下进行开发,能够达到事半功倍的效果。 

相关文章推荐

再战MVC(二)

MVC模式在J2EE技术中的应用  MVC模式并不能自动保证一个结构设计是正确的,如何在一个系统的设计中正确地使用MVC架构模式与系统使用的技术有密切的关系。2EE中有几个核心的技术:JSP,Java...

unity再战PBR材质流程与材质制作实践

这篇在上一篇的基础上增加了对PBR的认识,主要包括了金属度和粗糙度(光滑度)的测试 unity里PBR流程,PBR材质属性具体分析 传统模型到PBR的流程,一些PBR制作转换工具介绍 以前这篇http...

再战浏览器兼容

也许你也喜欢用document.all.*的写法来取得一个页面元素的引用,那么这个习惯是很糟糕的,这个语法只有IE支持,火狐里面是不行的。两者都支持的方法是:document.getElementBy...

来年再战

今年的最后一场战役,长春站结束了。累计至今日,已连续翘了物理课三个礼拜,模电课四个礼拜,c++课四个礼拜,数据结构课一学期。     先简单的回顾下比赛吧。今年与囧king,范总两位学长组队打了两场...

Intel以无线充电再战ARM移动市场地位?

英特尔公司(Intel)日前宣布采用Integrated Device Technology (IDT)的发射器与接收器晶片,用于实现其无线共振能量链接( WREL )技术,并计划进一步使这项无线充电...
  • safrans
  • safrans
  • 2012年09月06日 00:00
  • 729

欲与青龙重得水,来年再战不周山

16号,在都百特的时候我没再使用过,因为我老板和16号情有独钟。 回到家了,我又成为了当初的小泥鳅,16号攻击后卫。 感怀下呗,俺也没办法。身体越差,越向往强壮的年代!大概是天性吧!有些时候失去的...

滴滴出行跨出国门,再战Uber胜算有多大?

11月15日消息,滴滴出行宣布与安飞士巴吉集团(Avis Budget Group)达成战略合作协议,双方将为超过3亿中国用户在近175个国家和地区提供境外安飞士(Avis)以及巴吉(Budget)租...

linux 3.4.103 内核移植到 S3C6410 开发板 移植失败 (问题总结,来日再战!)

linux 3.4.103 内核移植到 S3C6410 开发板 这个星期几乎就搭在这里面了,一开始感觉很不值得,移植这种浪费时间的事情,想立马搞定,然后安安静静看书 & coding...

面试归来,感觉无望,下次再战

今天去面阿里校招研发岗,同去的还有同班的同学,去之前,我看了自己的简历,感觉写得还不算很花俏,因为之前有很多面经都提示,在简历技能那里写上熟悉时,你得考虑面试官会问你什么。慎重。           ...
  • kamsau
  • kamsau
  • 2014年09月18日 00:06
  • 1950

20140330 这几天想做一个安卓的游戏,我还起名字叫"再战" step_1

于是乎.. 我就写了一些想法下来.. 1.        设计: a)        人物具有 “金,木,水,火,土”属性,相互克制 b)       人物有不同职业:战士,弓...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再战MVC(二)
举报原因:
原因补充:

(最多只允许输入30个字)