零、哪两种JavaWeb开发模式
- JSP+JavaBean模式
- Servlet+JSP+JavaBean模式
一、JSP+JavaBean开发模式
1.1、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 waf.yty.domain;
import java.math.BigDecimal;
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"%>
<!-- 使用waf.yty.domain.CalculatorBean -->
<jsp:useBean id="calcBean" class="waf.yty.domain.CalculatorBean"/>
<!-- 接收用户输入的参数 -->
<jsp:setProperty property="*" name="calcBean"/>
<!-- 使用CalculatorBean进行计算 -->
<%
calcBean.calculate();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>使用{jsp+javabean开发模式}开发简单的计算器</title>
</head>
<body>
<br>
计算结果是:
<jsp:getProperty property="firstNum" name="calcBean"/>
<jsp:getProperty property="operator" name="calcBean"/>
<jsp:getProperty property="secondNum" name="calcBean"/>
=
<jsp:getProperty property="result" name="calcBean"/>
<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世界里:都是Web客户端发起请求,Web服务器接收、处理并产生响应。
2.2、标准MVC模型概述
MVC模型:是一种架构型的模式,本身不引入新功能,只是帮助我们将开发的结构组织的更加合理,使展示与模型分离、流程控制逻辑、业务逻辑调用与展示逻辑分离。如下图所示:
2.3、MVC(Model-View-Controller)的概念
Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型(domain)或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据) 和 服务层(行为)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。 也就是说控制器做了个调度员的工作。
从2.2的图中我们还看到,在标准的MVC中模型能主动推数据给视图进行更新(观察者设计模式,在模型上注册视图,当模型更新时自动更新视图),但在Web开发中模型是无法主动推给视图(无法主动更新用户界面),因为在Web开发是请求-响应模型。
接下来我们看一下在Web里MVC是什么样子,我们称其为 Web MVC 来区别标准的MVC。
2.4.、Web MVC概述
在Web MVC模式下,模型无法主动推数据给视图,如果用户想要视图更新,需要再发送一次请求(即请求-响应模型)。
2.5、Servlet+JSP+JavaBean开发模式介绍
Servlet+JSP+JavaBean架构其实可以认为就是我们所说的Web MVC模型,只是控制器采用Servlet、模型采用JavaBean、视图采用JSP。
Servlet+JSP+JavaBean 简易Web MVC模型示例
1、模型(model------JavaBean)
1.1 Userbean:
package waf.yty.domain;
public class UserBean {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
/**
* 校验用户输入的数据
* @return
*/
public boolean validate() {
if ("".equals(this.username) || "".equals(this.password)) {
return false;
}
return true;
}
public boolean login() {
if ("yty".equals(this.username) && "666".equals(this.password)) {
return true;
}
return false;
}
@Override
public String toString() {
return "UserBean [username=" + username + ", password=" + password + "]";
}
}
2、视图(View------jsp)
2.1 登录验证界面(login.jsp) :
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="waf.yty.domain.UserBean" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登陆网咖</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/LoginServlet" method="post">
<input type="hidden" name="submitFlag" value="login">
username:<input type="text" name="username" <%-- value="${user.username }" --%>><br>
password:<input type="password" name="password" <%-- value="${user.password} " --%>><br>
<input type="submit" value="登录按钮">
</form>
</body>
</html>
2.2 登录成功界面(success.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陆成功界面</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h1>远洋荣域欢迎业主回家!</h1>
</body>
</html>
3、控制器(controller------Servlet)
3.1 LoginServlet.java :
package waf.yty.web.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import waf.yty.domain.UserBean;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String submitFlag = request.getParameter("submitFlag");
if ("toLogin".equals(submitFlag)) {
toLogin(request,response);
return;
}else if ("login".equals(submitFlag)) {
login(request,response);
return;
}
}
private void toLogin(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.getRequestDispatcher("/mvc/login.jsp").forward(request, response);
}
private void login(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String username = request.getParameter("username");
String password = request.getParameter("password");
UserBean user = new UserBean();
user.setUsername(username);
user.setPassword(password);
if (user.login()) {
response.sendRedirect(request.getContextPath() + "/mvc/success.jsp");
}else {
request.setAttribute("user", user);
toLogin(request, response);
return;
}
}
}
程序的执行流程如下:
1、首先进入登录界面login.jsp,输入用户名和密码,点击登录按钮后post请求方式提交表单到LoginServlet。
2、因为submitFlag参数的值设置为login,LoginServlet判断后执行login方法。login方法把用户输入的用户名和密码赋给UserBean,UserBean用它的userLogin方法判断用户名(yty)和密码(666)是否正确。
3、如果用户输入的用户名和密码中有一项不符合,就失败,把user的信息保存到request域对象中,请求转发回login.jsp页面。
4、如果用户输入的用户名和密码都符合,重定向到登录成功界面!
三、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、请求参数到模型的封装比较麻烦。如果能交给框架来做这件事情,我们可以从中得到解放。
String username = request.getParameter("username");
String password = request.getParameter("password");
UserBean user = new UserBean();
user.setUsername(username);
user.setPassword(password);
当有几十个甚至上百个参数需要封装到模型中时,这样写恐怕就痛苦万分了,要写几十次甚至上百次这样的代码,估计写到吐了,所以现在流行的Web MVC框架(如Struts2)都提供了非常方便的获取参数,封装参数到模型的机制,减少这些繁琐的工作。
3、选择下一个视图,严重依赖Servlet API,给视图传输要展示的模型数据,也需要使用Servlet API。这样很难或基本不可能更换视图。
request.getRequestDispatcher("/mvc/login.jsp").forward(request, response);
request.setAttribute("user", user);
3.2、JavaBean作为模型的缺点
此处模型使用JavaBean,JavaBean组件类既负责收集封装数据,又要进行业务逻辑处理,这样可能造成JavaBean组件类很庞大,所以一般现在项目都是采用三层架构,而不直接采用JavaBean。
3.3、视图的缺点
现在被绑定在JSP,很难更换视图,比如Velocity、FreeMarker;比如我要支持Excel、PDF视图等等。