SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式。html
jsp+javabean开发模式的架构图以下图(图1-1)所示java
图1-1web
在jsp+javabean架构中,JSP负责控制逻辑、表现逻辑、业务对象(javabean)的调用。spring
JSP+JavaBean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务数据,JSP即负责处理用户请求,又显示数据。设计模式
首先分析一下jsp和javabean各自的职责,jsp负责显示计算器(calculator)页面,供用户输入计算数据,并显示计算后的结 果,javaBean负责接收用户输入的计算数据而且进行计算,JavaBean具备firstNum、secondNum、result、 operator属性,并提供一个calculate方法。浏览器
CalculatorBean代码以下:服务器
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页面代码以下:websocket
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>
运行结果以下:架构
在平时的JavaWeb项目开发中,在不使用第三方mvc开发框架的状况下,一般会选择Servlet+JSP+JavaBean开发模式来开发JavaWeb项目,Servlet+JSP+JavaBean组合开发就是一种MVC开发模式了,控制器(Controller)采用Servlet、模型(Model)采用JavaBean、视图(View)采用JSP。在讲解Servlet+JSP+JavaBean开发模式以前,先简单了解一下MVC开发模式。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视图等等。
spring springmvc等等