1. 程式人生 > >深入分析JavaWeb Item18 -- JavaWeb的兩種常用開發模式

深入分析JavaWeb Item18 -- JavaWeb的兩種常用開發模式

SUN公司推出JSP技術後,同時也推薦了兩種web應用程式的開發模式,一種是JSP+JavaBean模式,一種是Servlet+JSP+JavaBean模式。

一、JSP+JavaBean開發模式

1.1、jsp+javabean開發模式架構

  jsp+javabean開發模式的架構圖如下圖所示

這裡寫圖片描述

  在jsp+javabean架構中,JSP負責控制邏輯、表現邏輯、業務物件(javabean)的呼叫。

  JSP+JavaBean模式適合開發業務邏輯不太複雜的web應用程式,這種模式下,JavaBean用於封裝業務資料,JSP即負責處理使用者請求,又顯示資料。

1.2、JSP+JavaBean開發模式編寫計算器

  首先分析一下jsp和javabean各自的職責,jsp負責顯示計算器(calculator)頁面,供使用者輸入計算資料,並顯示計算後的結 果,javaBean負責接收使用者輸入的計算資料並且進行計算,JavaBean具有firstNum、secondNum、result、 operator屬性,並提供一個calculate方法。

  1、編寫CalculatorBean,負責接收使用者輸入的計算資料並且進行計算

  CalculatorBean程式碼如下:

package me.gacl.domain;

import java.math.BigDecimal;

/**
 * @author
gacl * CalculatorBean用於接收輸入引數和計算 */
public class CalculatorBean { //使用者輸入的第一個數 private double firstNum; //使用者輸入的第二個數 private double secondNum; //使用者選擇的操作運算子 private char operator = '+'; //運算結果 private double result; public double getFirstNum() { return firstNum; } public
void setFirstNum(double firstNum) { this.firstNum = firstNum; } public double getSecondNum() { return secondNum; } public void setSecondNum(double secondNum) { this.secondNum = secondNum; } public char getOperator() { return operator; } public void setOperator(char operator) { this.operator = operator; } public double getResult() { return result; } public void setResult(double result) { this.result = result; } /** * 用於計算 */ public void calculate() { switch (this.operator) { case '+': { this.result = this.firstNum + this.secondNum; break; } case '-': { this.result = this.firstNum - this.secondNum; break; } case '*': { this.result = this.firstNum * this.secondNum; break; } case '/': { if (this.secondNum == 0) { throw new RuntimeException("被除數不能為0!!!"); } this.result = this.firstNum / this.secondNum; // 四捨五入 this.result = new BigDecimal(this.result).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); break; } default: throw new RuntimeException("對不起,傳入的運算子非法!!"); } } }

  2、編寫calculator.jsp,負責顯示計算器(calculator)頁面,供使用者輸入計算資料,並顯示計算後的結果

  calculator.jsp頁面程式碼如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%--使用me.gacl.domain.CalculatorBean --%>
<jsp:useBean id="calcBean" class="me.gacl.domain.CalculatorBean"/>
<%--接收使用者輸入的引數 --%>
<jsp:setProperty name="calcBean" property="*"/>
<% 
//使用CalculatorBean進行計算
 calcBean.calculate();
%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>使用【jsp+javabean開發模式】開發的簡單計算器</title>
  </head>

  <body>
     <br/>
    計算結果是:
    <jsp:getProperty name="calcBean" property="firstNum"/>
    <jsp:getProperty name="calcBean" property="operator"/>
    <jsp:getProperty name="calcBean" property="secondNum"/>
      =
    <jsp:getProperty name="calcBean" property="result"/>

     <br/><hr> <br/>
    <form action="${pageContext.request.contextPath}/calculator.jsp" method="post">
        <table border="1px">
            <tr>
                <td colspan="2">簡單的計算器</td>
            </tr>
            <tr>
                <td>第一個引數</td>
                <td><input type="text" name="firstNum"></td>
            </tr>
            <tr>
                <td>運算子</td>
                <td><select name="operator">
                        <option value="+">+</option>
                        <option value="-">-</option>
                        <option value="*">*</option>
                        <option value="/">/</option>
                </select></td>
            </tr>
            <tr>
                <td>第二個引數</td>
                <td><input type="text" name="secondNum"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="計算"></td>
            </tr>
        </table>
    </form>
</body>
</html>

執行結果如下:

  這裡寫圖片描述

二、Servlet+JSP+JavaBean開發模式

  在平時的JavaWeb專案開發中,在不使用第三方mvc開發框架的情況下,通常會選擇Servlet+JSP+JavaBean開發模式來開發JavaWeb專案,Servlet+JSP+JavaBean組合開發就是一種MVC開發模式了,控制器(Controller)採用Servlet、模型(Model)採用JavaBean、檢視(View)採用JSP。在講解Servlet+JSP+JavaBean開發模式之前,先簡單瞭解一下MVC開發模式。

2.1、Web開發中的請求-響應模型

這裡寫圖片描述

  在Web世界裡,具體步驟如下:

  2、Web伺服器(如Tomcat)接收請求,處理請求(比如使用者新增,則將把使用者儲存一下),最後產生響應(一般為html)。

  3、web伺服器處理完成後,返回內容給web客戶端(一般就是我們的瀏覽器),客戶端對接收的內容進行處理(如web瀏覽器將會對接收到的html內容進行渲染以展示給客戶)。

  因此,在Web世界裡:都是Web客戶端發起請求,Web伺服器接收、處理併產生響應。

  一般Web伺服器是不能主動通知Web客戶端更新內容。雖然現在有些技術如伺服器推(如Comet)、還有現在的HTML5 websocket可以實現Web伺服器主動通知Web客戶端。

  到此我們瞭解了在web開發時的請求/響應模型,接下來我們看一下標準的MVC模型是什麼。

2.2、標準MVC模型概述

  MVC模型:是一種架構型的模式,本身不引入新功能,只是幫助我們將開發的結構組織的更加合理,使展示與模型分離、流程控制邏輯、業務邏輯呼叫與展示邏輯分離。如下圖所示:

這裡寫圖片描述

2.3、MVC(Model-View-Controller)的概念

  首先讓我們瞭解下MVC(Model-View-Controller)的概念:

  Model(模型):資料模型,提供要展示的資料,因此包含資料和行為,可以認為是領域模型(domain)或JavaBean元件(包含資料和行為),不過現在一般都分離開來:Value Object(資料) 和 服務層(行為)。也就是模型提供了模型資料查詢和模型資料的狀態更新等功能,包括資料和業務。

  View(檢視):負責進行模型的展示,一般就是我們見到的使用者介面,客戶想看到的東西。

  Controller(控制器):接收使用者請求,委託給模型進行處理(狀態改變),處理完畢後把返回的模型資料返回給檢視,由檢視負責展示。 也就是說控制器做了個排程員的工作。

  從圖中我們還看到,在標準的MVC中模型能主動推資料給檢視進行更新(觀察者設計模式,在模型上註冊檢視,當模型更新時自動更新檢視),但在Web開發中模型是無法主動推給檢視(無法主動更新使用者介面),因為在Web開發是請求-響應模型。

  那接下來我們看一下在Web裡MVC是什麼樣子,我們稱其為 Web MVC 來區別標準的MVC。

2.4.Web MVC概述

  Web MVC中的M(模型)-V(檢視)-C(控制器)概念和標準MVC概念一樣,我們再看一下Web MVC標準架構,如下圖所示:

這裡寫圖片描述

  在Web MVC模式下,模型無法主動推資料給檢視,如果使用者想要檢視更新,需要再發送一次請求(即請求-響應模型)。

2.5、Servlet+JSP+JavaBean開發模式介紹

    Servlet+JSP+JavaBean架構其實可以認為就是我們所說的Web MVC模型,只是控制器採用Servlet、模型採用JavaBean、檢視採用JSP,如圖

這裡寫圖片描述

具體示例程式碼:

1、模型(model)

  這裡寫圖片描述

2、檢視(View)

  這裡寫圖片描述

3、控制器(controller)

  這裡寫圖片描述

  從Servlet+JSP+JavaBean(Web MVC)架構可以看出,檢視和模型分離了,控制邏輯和展示邏輯分離了。

三、Servlet+JSP+JavaBean開發模式的缺點

  Servlet+JSP+JavaBean(Web MVC)架構雖然實現了檢視和模型分離以及控制邏輯和展示邏輯分離,但也有一些比較嚴重的缺點

3.1、Servlet作為控制器的缺點

  此處的控制器使用Servlet,使用Servlet作為控制器有以下幾個缺點:

  1、控制邏輯可能比較複雜,其實我們可以按照規約,如請求引數submitFlag=toLogin,我們其實可以直接呼叫toLogin方法,來簡化控制邏輯;而且每個模組基本需要一個控制器,造成控制邏輯可能很複雜。現在流行的Web MVC框架(如Struts2)都支援”請求引數submitFlag=toAdd,就可以直接呼叫toAdd方法”這樣的處理機制,在Struts2中類似這樣的處理機制就稱為”動態方法呼叫”

  2、請求引數到模型的封裝比較麻煩,如果能交給框架來做這件事情,我們可以從中得到解放。

  請求引數到模型的封裝程式碼:

// 1收集引數
String username = req.getParameter("username");
String password = req.getParameter("password");
// 2封裝引數
UserBean user = new UserBean();
user.setUsername(username);
user.setPassword(password);

  當有幾十個甚至上百個引數需要封裝到模型中時,這樣寫恐怕就痛苦萬分了,要寫幾十次甚至上百次這樣的程式碼,估計寫到吐了,所以現在流行的Web MVC框架(如Struts2)都提供了非常方便的獲取引數,封裝引數到模型的機制,減少這些繁瑣的工作。

  3、選擇下一個檢視,嚴重依賴Servlet API,這樣很難或基本不可能更換檢視。

例如:使用Servlet API提供的request物件的getRequestDispatcher方法選擇要展示給使用者看的檢視

private void toLogin(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
    //使用Servlet API提供的request物件的getRequestDispatcher方法選擇檢視
     // 此處和JSP檢視技術緊密耦合,更換其他檢視技術幾乎不可能 
    request.getRequestDispatcher("/mvc/login.jsp").forward(request, response);
}

  4、給檢視傳輸要展示的模型資料,也需要使用Servlet API,更換檢視技術也要一起更換,很麻煩。

例如:使用Servlet API提供的request物件給檢視傳輸要展示的模型資料

//使用Servlet API提供的request物件給檢視login.jsp傳輸要展示的模型資料(user)
request.setAttribute("user", user);
request.getRequestDispatcher("/mvc/login.jsp").forward(request, response)

3.2、JavaBean作為模型的缺點

  此處模型使用JavaBean,JavaBean元件類既負責收集封裝資料,又要進行業務邏輯處理,這樣可能造成JavaBean元件類很龐大,所以一般現在專案都是採用三層架構,而不直接採用JavaBean。

這裡寫圖片描述

3.3、檢視的缺點

  現在被繫結在JSP,很難更換檢視,比如Velocity、FreeMarker;比如我要支援Excel、PDF檢視等等。

  關於JavaWeb的兩種開發模式的講解就介紹到這裡,下一篇將使用servlet+jsp+javabean來開發一個使用者登入註冊功能,以此來加深servlet+jsp+javabean開發模式的理解。

四、專案開發部署

這裡寫圖片描述