MVC結構總結

  學習MVC已有一段時間,之前對MVC的理解比較凌亂,最近開始着手做web項目,考慮到MVC的重要性,覺得有必要把MVC的知識點綜合總結一下,也算是對自己學習的一個檢測吧。
  MVC是一個設計模式,是model-view-control結構。它強制性的使應用程序的輸入、處理和輸出分開。MVC應用程序被分成三個核心部件:模型(model)、視圖(view)、控制器(controller)。它們各自處理自己的任務。MVC模式的目的就是實現Web系統的職能分工。
  Model層:
    實現系統中的業務邏輯,通常可以用JavaBean或EJB來實現。模型表示企業數據和業務規則。在MVC的三個部件中,模型擁有最多的處理任務。一個模型能爲多個視圖提供數據。模型分爲數據模型和業務邏輯模型。
  View層:
    負責展示數據對象給用戶的界面層,用於與用戶的交互,通常用JSP來實現。是用戶看到並與之交互的界面。
  Controller層:
    是Model與View之間溝通的橋樑,是根據界面反饋處理業務邏輯的控制層,可以分派用戶的請求並選擇恰當的視圖以用於顯示,同時它也可以解釋用戶的輸入並將它們映射爲模型層可執行的操作。

  簡單地說,MVC就是一個HTML/JSP+Servlet+javaBean結構:
  HTML/JSP負責生成動態網頁;
  Servlet負責流程轉發至對應胡Action實現
  javabean(pojo和dao)負責業務數據模型存取

  控制器接受用戶的輸入並調用模型和視圖去完成用戶的需求。所以當單擊Web頁面中的超鏈接和發送HTML表單時,控制器本身不輸出任何東西和做任何處理。它只是接收請求並決定調用哪個模型構件去處理請求,然後用確定用哪個視圖來顯示模型處理返回的數據。最重要的一點是多個視圖能共享一個模型,現在需要用越來越多的方式來訪問你的應用程序。對此,其中一個解決之道是使用MVC,無論用戶想要Flash界面或是WAP界面,用一個模型就能處理它們。由於已經將數據和業務規則從表示層分開,所以可以最大化的重用代碼了。

MVC特點:
  低耦合性
  高重用性和可適用性
  較低的生命週期成本
  快速部署
  可維護性
  有利於軟件工程化管理
  並不適合小型甚至中等規模的應用程序,花費大量時間將MVC應用到規模並不是很大的應用程序通常會得不償失。

model1與model2的概念:
  在使用JAVA技術建立Web應用的實例中,由於JSP技術的發展,很快這種便於掌握和可實現快速開發的技術就成了創建Web應用的主要技術。JSP頁面中可以非常容易地結合業務邏輯(jsp:useBean)、服務端處理過程(jsp:let)和HTML(),在JSP頁面中同時實現顯示,業務邏輯和流程控制,從而可以快速地完成應用開發。現在很多的Web應用就是由一組JSP頁面構成的。這種以JSP爲中心的開發模型我們可以稱之爲Model1。
  Model 2表示的是基於MVC模式的框架。MVC是Model-View-Controller的簡寫。“Model”代表的是應用的業務邏輯(通過JavaBean,EJB組件實現),“View”是應用的表示面(由JSP頁面產生),“Controller”是提供應用的處理過程控制(一般是一個Servlet),通過這種設計模型把應用邏輯,處理過程和顯示邏輯分成不同的組件實現。這些組件可以進行交互和重用。從而彌補了Model1的不足。

MVC框架結構:
  ControlServlet:請求控制器,解析請求中的動作名字,調用動作工廠對象生成的動作對象處理請求,處理後返回的結果即爲目標url。
  ActionFactory:工廠類,根據請求中的動作名創建命令對象action。
  Action:接口,定義所有動作的接口。
  具體Action:是實現了Action接口的類,調用其具體實現的方法處理Request或Response對象,返回一個url,再由Servlet負責轉發到界面上。
  user:用戶類,一個最基本的單元,用來實現動作的對象。
  Dao:負責連接數據庫,將數據庫中的數據導入到具體的Action中。

java實例:
1.設計控制器Servlet:
  創建一個動態web工程後,首先定義一個ControlServlet,用戶的所有請求都提交給這個Servlet,爲了便於系統擴展,可以對Servlet的請求路徑在web.xml中進行模糊配置。
<servlet-mapping>
  <servlet-name>ControlServlet</servlet-name>
  <url-pattern>*.netjava</url-pattern>
</servlet-mapping>

ControlServlet:
protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try{
            //得到請求的命令名字,解析出*.netjava請求中*所指代的字符串,即動作名字        
              String actionName = getActionName(request);
  //根據請求的動作名,得到控制器servlet中配置的Action實現類名字
   String actionClassName = this.getInitParameter(actionName);

  //通過工廠類創建命令對象
   Action action = ActionFactory.getIns().getAction(actionClassName);

  //使用動作對象處理動作,返回結果爲處理後要輸出的目標頁面
   String url = action.execute(request, response);
   if(url != null){
   //輸出目標頁面
            getServletContext().getRequestDispatcher(url).forward(request, response);
            }
}catch(Exception e){
   e.printStackTrace();
//出錯則輸出錯誤頁面
getServletContext().getRequestDispatcher("/error.jsp").forward(request, response);
}
}

//解析得到請求中的命令字
protected String getActionName(HttpServletRequest request){
String path = request.getServletPath();
return path.substring(1, path.lastIndexOf("."));
}

ActionFactory:
public class ActionFactory {

private static ActionFactory af = null;
//單實例訪問方法
public static ActionFactory getIns(){
if(af == null){
af = new ActionFactory();
}
return af;
}

//根據具體的Action類名字創建Action對象
public Action getAction(String actionClassName){
Action actionInstance = null;
try{
Class c = Class.forName(actionClassName);
actionInstance = (Action)c.newInstance();
}catch(Exception e){
e.printStackTrace();
}
return actionInstance;
}
}

Action接口:
public interface Action {

public String execute(HttpServletRequest request, HttpServletResponse response);
}

具體Action:
public class LoginAction implements Action{

public String execute(HttpServletRequest request, HttpServletResponse response){
response.setContentType("text/html; charset=UTF-8");
String userName = request.getParameter("userName");
String userPwd = request.getParameter("userPwd");

//到數據庫中查找用戶
User user = new UserDao().findUser(userName, userPwd);

//判斷用戶是否存在
if(userName.equals(user.getName()) &&
userPwd.equals(user.getPwd())){
request.getSession().setAttribute("USER", user);
return "/mainPage.jsp";
}else{
request.setAttribute("ERROR", "賬號或密碼不正確!");
return "/Login.html";
}
}
}

web.xml配置:
  <servlet>
    <description></description>
    <display-name>ControlServlet</display-name>
    <servlet-name>ControlServlet</servlet-name>
    <servlet-class>cn.netjava.servlet.ControlServlet</servlet-class>
    <init-param>
      <param-name>LoginAction</param-name>
      <param-value>cn.netjava.action.LoginAction</param-

value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>ControlServlet</servlet-name>
    <url-pattern>/*.netjava</url-pattern>
  </servlet-mapping>

Login.jsp:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;

charset=UTF-8">
<title>登陸界面</title>
</head>
<body>

<form name="testForm" method="get"

action="LoginAction.netjava">
<br>用戶名:<input type="text" name="userName"/>
<br>密     碼:<input type="password" name="userPwd"/>
<%
String msg = (String)request.getAttribute("ERROR");
if(msg != null){
out.print("<br>"+msg);
}
%>
<input type="submit" name="submit" value="登陸"/>
</form>
<a href="Register.jsp">註冊用戶</a>
</body>
</html>

開啓服務器,在IE瀏覽器上測試結果:

http://localhost:8080/MVCTest/Login.jsp
注意:最好是使用IE瀏覽器,因爲有的瀏覽器並不完全兼容tomcat,可能會出現異常。
  在界面上輸入用戶名和密碼,點擊登陸按鈕,jsp將請求交給Servlet,Servlet再根據提交的動作得到具體的Action對象,然後通過Factory創建命令動作對象,處理Servlet中的動作,返回目標url,即得到登陸成功的界面。
  這就是MVC構架的一個大致流程。爲系統的擴展爲了充分的準備,利用一個Servlet可以實現用戶多個不同動作的響應。以上也是我對MVC的一點粗略的理解。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章