深入分析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開發模式的理解。