SUN公司推出JSP技術後,同時也推薦了兩種web應用程序的開發模式,一種是JSP+JavaBean模式,一種是Servlet+JSP+JavaBean模式。html
jsp+javabean開發模式的架構圖以下圖(圖1-1)所示java
圖1-1web
在jsp+javabean架構中,JSP負責控制邏輯、表現邏輯、業務對象(javabean)的調用。設計模式
JSP+JavaBean模式適合開發業務邏輯不太複雜的web應用程序,這種模式下,JavaBean用於封裝業務數據,JSP即負責處理用戶請求,又顯示數據。瀏覽器
首先分析一下jsp和javabean各自的職責,jsp負責顯示計算器(calculator)頁面,供用戶輸入計算數據,並顯示計算後的結 果,javaBean負責接收用戶輸入的計算數據而且進行計算,JavaBean具備firstNum、secondNum、result、 operator屬性,並提供一個calculate方法。服務器
CalculatorBean代碼以下:websocket
1 package me.gacl.domain; 2 3 import java.math.BigDecimal; 4 5 /** 6 * @author gacl 7 * CalculatorBean用於接收輸入參數和計算 8 */ 9 public class CalculatorBean { 10 11 //用戶輸入的第一個數 12 private double firstNum; 13 //用戶輸入的第二個數 14 private double secondNum; 15 //用戶選擇的操做運算符 16 private char operator = '+'; 17 //運算結果 18 private double result; 19 20 public double getFirstNum() { 21 return firstNum; 22 } 23 24 public void setFirstNum(double firstNum) { 25 this.firstNum = firstNum; 26 } 27 28 public double getSecondNum() { 29 return secondNum; 30 } 31 32 public void setSecondNum(double secondNum) { 33 this.secondNum = secondNum; 34 } 35 36 public char getOperator() { 37 return operator; 38 } 39 40 public void setOperator(char operator) { 41 this.operator = operator; 42 } 43 44 public double getResult() { 45 return result; 46 } 47 48 public void setResult(double result) { 49 this.result = result; 50 } 51 52 /** 53 * 用於計算 54 */ 55 public void calculate() { 56 57 switch (this.operator) { 58 case '+': { 59 this.result = this.firstNum + this.secondNum; 60 break; 61 } 62 case '-': { 63 this.result = this.firstNum - this.secondNum; 64 break; 65 } 66 case '*': { 67 this.result = this.firstNum * this.secondNum; 68 break; 69 } 70 case '/': { 71 if (this.secondNum == 0) { 72 throw new RuntimeException("被除數不能爲0!!!"); 73 } 74 this.result = this.firstNum / this.secondNum; 75 // 四捨五入 76 this.result = new BigDecimal(this.result).setScale(2, 77 BigDecimal.ROUND_HALF_UP).doubleValue(); 78 break; 79 } 80 default: 81 throw new RuntimeException("對不起,傳入的運算符非法!!"); 82 } 83 } 84 }
calculator.jsp頁面代碼以下:架構
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%--使用me.gacl.domain.CalculatorBean --%> 3 <jsp:useBean id="calcBean" class="me.gacl.domain.CalculatorBean"/> 4 <%--接收用戶輸入的參數 --%> 5 <jsp:setProperty name="calcBean" property="*"/> 6 <% 7 //使用CalculatorBean進行計算 8 calcBean.calculate(); 9 %> 10 <!DOCTYPE HTML> 11 <html> 12 <head> 13 <title>使用【jsp+javabean開發模式】開發的簡單計算器</title> 14 </head> 15 16 <body> 17 <br/> 18 計算結果是: 19 <jsp:getProperty name="calcBean" property="firstNum"/> 20 <jsp:getProperty name="calcBean" property="operator"/> 21 <jsp:getProperty name="calcBean" property="secondNum"/> 22 = 23 <jsp:getProperty name="calcBean" property="result"/> 24 25 <br/><hr> <br/> 26 <form action="${pageContext.request.contextPath}/calculator.jsp" method="post"> 27 <table border="1px"> 28 <tr> 29 <td colspan="2">簡單的計算器</td> 30 </tr> 31 <tr> 32 <td>第一個參數</td> 33 <td><input type="text" name="firstNum"></td> 34 </tr> 35 <tr> 36 <td>運算符</td> 37 <td><select name="operator"> 38 <option value="+">+</option> 39 <option value="-">-</option> 40 <option value="*">*</option> 41 <option value="/">/</option> 42 </select></td> 43 </tr> 44 <tr> 45 <td>第二個參數</td> 46 <td><input type="text" name="secondNum"></td> 47 </tr> 48 <tr> 49 <td colspan="2"><input type="submit" value="計算"></td> 50 </tr> 51 </table> 52 </form> 53 </body> 54 </html>
運行結果以下:mvc
在平時的JavaWeb項目開發中,在不使用第三方mvc開發框架的狀況下,一般會選擇Servlet+JSP+JavaBean開發模式來開發JavaWeb項目,Servlet+JSP+JavaBean組合開發就是一種MVC開發模式了,控制器(Controller)採用Servlet、模型(Model)採用JavaBean、視圖(View)採用JSP。在講解Servlet+JSP+JavaBean開發模式以前,先簡單瞭解一下MVC開發模式。框架
圖2-1
在Web世界裏,具體步驟以下:
一、Web瀏覽器(如IE)發起請求,如訪問http://www.iteye.com/
二、Web服務器(如Tomcat)接收請求,處理請求(好比用戶新增,則將把用戶保存一下),最後產生響應(通常爲html)。
三、web服務器處理完成後,返回內容給web客戶端(通常就是咱們的瀏覽器),客戶端對接收的內容進行處理(如web瀏覽器將會對接收到的html內容進行渲染以展現給客戶)。
所以,在Web世界裏:都是Web客戶端發起請求,Web服務器接收、處理併產生響應。
通常Web服務器是不能主動通知Web客戶端更新內容。雖然如今有些技術如服務器推(如Comet)、還有如今的HTML5 websocket能夠實現Web服務器主動通知Web客戶端。
到此咱們瞭解了在web開發時的請求/響應模型,接下來咱們看一下標準的MVC模型是什麼。
MVC模型:是一種架構型的模式,自己不引入新功能,只是幫助咱們將開發的結構組織的更加合理,使展現與模型分離、流程控制邏輯、業務邏輯調用與展現邏輯分離。以下圖(圖2-2)所示:
圖2-2
首先讓咱們瞭解下MVC(Model-View-Controller)的概念:
Model(模型):數據模型,提供要展現的數據,所以包含數據和行爲,能夠認爲是領域模型(domain)或JavaBean組件(包含數據和行爲),不過如今通常都分離開來:Value Object(數據) 和 服務層(行爲)。也就是模型提供了模型數據查詢和模型數據的狀態更新等功能,包括數據和業務。
View(視圖):負責進行模型的展現,通常就是咱們見到的用戶界面,客戶想看到的東西。
Controller(控制器):接收用戶請求,委託給模型進行處理(狀態改變),處理完畢後把返回的模型數據返回給視圖,由視圖負責展現。 也就是說控制器作了個調度員的工做。
從圖2-1咱們還看到,在標準的MVC中模型能主動推數據給視圖進行更新(觀察者設計模式,在模型上註冊視圖,當模型更新時自動更新視圖),但在Web開發中模型是沒法主動推給視圖(沒法主動更新用戶界面),由於在Web開發是請求-響應模型。
那接下來咱們看一下在Web裏MVC是什麼樣子,咱們稱其爲 Web MVC 來區別標準的MVC。
Web MVC中的M(模型)-V(視圖)-C(控制器)概念和標準MVC概念同樣,咱們再看一下Web MVC標準架構,以下圖(圖2-3)所示:
圖2-3
在Web MVC模式下,模型沒法主動推數據給視圖,若是用戶想要視圖更新,須要再發送一次請求(即請求-響應模型)。
Servlet+JSP+JavaBean架構其實能夠認爲就是咱們所說的Web MVC模型,只是控制器採用Servlet、模型採用JavaBean、視圖採用JSP,如圖2-3
圖2-4
具體示例代碼:
一、模型(model)
二、視圖(View)
三、控制器(controller)
從Servlet+JSP+JavaBean(Web MVC)架構能夠看出,視圖和模型分離了,控制邏輯和展現邏輯分離了。
Servlet+JSP+JavaBean(Web MVC)架構雖然實現了視圖和模型分離以及控制邏輯和展現邏輯分離,但也有一些比較嚴重的缺點
此處的控制器使用Servlet,使用Servlet做爲控制器有如下幾個缺點:
一、控制邏輯可能比較複雜,其實咱們能夠按照規約,如請求參數submitFlag=toLogin,咱們其實能夠直接調用toLogin方法,來簡化控制邏輯;並且每一個模塊基本須要一個控制器,形成控制邏輯可能很複雜。如今流行的Web MVC框架(如Struts2)都支持"請求參數submitFlag=toAdd,就能夠直接調用toAdd方法"這樣的處理機制,在Struts2中相似這樣的處理機制就稱爲"動態方法調用"
二、請求參數到模型的封裝比較麻煩,若是能交給框架來作這件事情,咱們能夠從中獲得解放。
請求參數到模型的封裝代碼:
1 // 1收集參數 2 String username = req.getParameter("username"); 3 String password = req.getParameter("password"); 4 // 2封裝參數 5 UserBean user = new UserBean(); 6 user.setUsername(username); 7 user.setPassword(password);
當有幾十個甚至上百個參數須要封裝到模型中時,這樣寫恐怕就痛苦萬分了,要寫幾十次甚至上百次這樣的代碼,估計寫到吐了,因此如今流行的Web MVC框架(如Struts2)都提供了很是方便的獲取參數,封裝參數到模型的機制,減小這些繁瑣的工做。
三、選擇下一個視圖,嚴重依賴Servlet API,這樣很難或基本不可能更換視圖。
例如:使用Servlet API提供的request對象的getRequestDispatcher方法選擇要展現給用戶看的視圖
1 private void toLogin(HttpServletRequest req, HttpServletResponse resp) 2 throws ServletException, IOException { 3 //使用Servlet API提供的request對象的getRequestDispatcher方法選擇視圖 4 // 此處和JSP視圖技術緊密耦合,更換其餘視圖技術幾乎不可能 5 request.getRequestDispatcher("/mvc/login.jsp").forward(request, response); 6 }
四、給視圖傳輸要展現的模型數據,也須要使用Servlet API,更換視圖技術也要一塊兒更換,很麻煩。
例如:使用Servlet API提供的request對象給視圖傳輸要展現的模型數據
//使用Servlet API提供的request對象給視圖login.jsp傳輸要展現的模型數據(user) request.setAttribute("user", user); request.getRequestDispatcher("/mvc/login.jsp").forward(request, response)
此處模型使用JavaBean,JavaBean組件類既負責收集封裝數據,又要進行業務邏輯處理,這樣可能形成JavaBean組件類很龐大,因此通常如今項目都是採用三層架構,而不直接採用JavaBean。
如今被綁定在JSP,很難更換視圖,好比Velocity、FreeMarker;好比我要支持Excel、PDF視圖等等。
關於JavaWeb的兩種開發模式的講解就介紹到這裏,下一篇將使用servlet+jsp+javabean來開發一個用戶登陸註冊功能,以此來加深servlet+jsp+javabean開發模式的理解。