第8章 JavaBean技术与JSP 开发模型
学习目标
- 了解JavaBean的概念以及种类、熟悉JavaBean的应用
- 了解JSP开发模型、熟悉MVC设计模式的原理
- 熟悉JSP Model1和JSP Model2模型的原理
- 掌握JSP Model2模型的实际应用
- 重点:JavaBean的概念、编程规范
在Java Web的实际开发中,为了使得JSP页面中的业务逻辑变得更加清晰,程序中的实体对象和业务逻辑可以单独封装到Java类中,提高程序的可读性和易维护性,需要用到JavaBean技术、JSP开发模型以及MVC设计模式等相关知识。
1. JavaBean技术
1.1 JavaBean概述
(1) JavaBean的概念
在JSP网页开发的初级阶段,JSP页面包含了几乎所有的web功能:(1) 向服务器提交Web请求,含请求界面和请求数据;(2) 直接访问数据库并进行业务处理;(3) 向客户端发送响应,含响应界面和响应数据,JSP页面文件中包含了大量的html、css、js和图片等静态资源和嵌入了大量的访问动态资源的代码,含访问数据库、业务逻辑处理等Java代码。
(2) 早期的JSP开发的缺点
早期的JSP开发流程看似简单,但这种开发方式将大量的Java代码嵌入到JSP页面中,必定会给修改和维护带来一定的困难,因为在JSP页面中包含HTML代码、CSS代码、Java代码等,同时再加入业务逻辑处理代码,既不利于页面编程人员的设计,也不利于Java程序员对程序的开发,而且将Java代码嵌入到页面中,不能体现面向对象的开发模式,达不到代码的重用。
(3) JavaBean组件
如果使HTML代码与Java代码相分离,将Java代码单独封装成为一个处理某种业务逻辑的类,然后在JSP页面中调用此类,可以降低HTML代码与Java代码之间的耦合度,简化JSP页面。提高Java程序代码的重用性及灵活性。这种与HTML代码相分离,而使用Java代码封装的类,就是一个JavaBean组件。在Java Web开发中,可以使用JavaBean组件完成业务逻辑的处理。应用JavaBean与JSP整合的开发模式如下图所示。
(4) JavaBean定义和编程规范
JavaBean是一种可以重用、使用面向对象思想进行封装(---成员变量私有、setter|getter公开、无参构造)的Java类。对软件开发人员来说,JavaBean带来的最大的优点是充分提高了代码的可重用性,并且对软件的可维护性和易维护性起到了积极作用。
javaBean也被称为实体类,所谓的实体类就是现实生活中有的,其对象可以用于在程序中封装数据
JavaBean满足的编程规范:
- public class JavaBean类名 --- 公开类
- private 类型 成员变量 --- 成员变量(属性、特征)私有;提供成员变量对应的public setXxx()赋值和getXxx()取值方法。
- 要有无参(默认)构造器
- ----如果类中没有有参构造方法,编译器会自动构造1个无参构造方法;
- ----如果类中有1有参构造方法,就必须手工写1个无参构造方法
- 属性名要大于等于2个字母,并且要么都大写,要么都小写。(可以使用中文)
1.2 JavaBean种类
JavaBean起初的目的是将可以重复使用的代码进行打包。在传统的应用中,JavaBean主要用于实现一些可视化界面,如一个窗体、按钮、文本框等,这样的JavaBean称之为可视化的JavaBean。随着技术的不断发展与项目的需求,JavaBean的功能与应用范围也在不断扩展,目前JavaBean主要用于实现一些业务逻辑或封装一些业务对象,由于这样的JavaBean并没有可视化的界面,所以又称之为非可视化的JavaBean。
注意:
- 可视化的JavaBean一般应用于Swing程序中,Java Web开发中并不会采用,
- Java Web开发使用非可视化的JavaBean,实现一些业务逻辑或封装一些业务对象。
参照ch04创建ch08_ls项目,创建ch08首页index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JavaBean技术与JSP开发模型</title>
</head>
<body>
<h1>ch08 JavaBean技术与JSP开发模型(ls)</h1>
<hr>
<a href="01index_ls.jsp">1. 输入并提交用户名和密码</a><br>
<a href="02stuInfo_ls.jsp">2. 获取JavaBean属性信息</a><br>
<a href="03stuInfo_ls.jsp">3. 对Student对象的属性进行赋值并输出</a><br>
<a href="04add_ls.jsp">4. 图书信息添加</a><br>
<a href="05email_ls.jsp">5. 使用JavaBean解决中文乱码</a><br>
<a href="06login_ls.jsp">6. 判断用户名是否有效</a><br>
<a href="07register_ls.jsp">7. 按照JSP Model2思想实现用户注册功能</a><br>
<hr>
<p><a href="http://101.42.158.247/21javaweb.html">返回课程首页</a>
ls <script>document.write(document.lastModified); </script> 制作</p>
</body>
</html>
运行结果如下:
非可视化的JavaBean的应用
cn.ls.User.java
package cn.ls;
import java.io.Serializable;
public class User implements Serializable {
private static final long seralVersionUID = 1L;
private String 用户名;
private String 密码;
public User() {
}
public User(String username, String password) {
this.用户名 = username;
this.密码 = password;
}
public String get用户名() {
return 用户名;
}
public void set用户名(String username) {
this.用户名 = username;
}
public String get密码() {
return 密码;
}
public void set密码(String password) {
this.密码 = password;
}
}
01index_ls.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<form action="01result_ls.jsp" method="post">
<table align="center" width="300" border="1" height="150">
<tr>
<td colspan="2" align="center"><b>登录页面</b></td>
</tr>
<tr>
<td align="right">用户名:<input type="text"
name="用户名"></input></td>
</tr>
<tr>
<td align="right">密码:<input type="text"
name="密码"></input></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit"/></td>
</tr>
</table>
</form>
</body>
</html>
01result_ls.jsp
<%@ page import="cn.ls.User"%>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
<title>结果提示</title>
</head>
<body>
<div align="center">
<%
request.setCharacterEncoding("utf-8");
String username = request.getParameter("用户名");
String password = request.getParameter("密码");
User user = new User(username,password);
System.out.println(username);
if (user.get用户名().equals("ls")&& user.get密码().equals("123456")){
out.print("恭喜您,登录成功!");
} else{
out.print("请输入正确的用户名和密码!");
}
%>
<br/><br/>
<a href="01index_ls.jsp">返回</a>
</div>
</body>
</html>
运行结果如下:
1.3 JavaBean的应用
(1) 获取JavaBean属性信息
cn.ls.Student0.java
package cn.ls;
public class Student0 {
private String 姓名 = "ls";
private int 年龄 = 30;
private String 性别= "男";
public String get姓名() {
return 姓名;
}
public int get年龄() {
return 年龄;
}
public String get性别() {
return 性别;
}
}
02stuInfo_ls.jsp
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<title>学生信息</title>
</head>
<body>
<jsp:useBean id="student" class="cn.ls.Student0"/>
<div>
<ul>
<li>姓名:<jsp:getProperty name="student" property="姓名"/></li>
<li>年龄:<jsp:getProperty name="student" property="年龄"/></li>
<li>性别:<jsp:getProperty name="student" property="性别"/></li>
</ul>
</div>
</body>
</html>
运行结果如下:
<jsp:useBean>标签和<jsp:getProperty>标签操作Java类
- <jsp:useBean>标签用于获取类的实例,其内部是通过调用类的默认构造方法实现的,所以,JavaBean需要有一个默认的无参构造方法;
- <jsp:getProperty>标签获取JavaBean中的属性,其内部是通过调用属性的getter方法实现的,所以,JavaBean规范要求为属性提供公共的(public)类型访问方法。
(2) 设置和获取JavaBean属性信息
cn.ls.Student.java
package cn.ls;
public class Student {
private String 姓名;
private int 年龄;
private String 性别;
... setter 和 getter
}
03stuInfo_ls.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生信息</title>
</head>
<body>
<jsp:useBean id="student" class="cn.ls.Student"/>
<jsp:setProperty name="student" property="姓名" value="ls"/>
<jsp:setProperty name="student" property="年龄" value="58"/>
<jsp:setProperty name="student" property="性别" value="男"/>
<div>
<ul>
<li>姓名:<jsp:getProperty name="student" property="姓名"/></li>
<li>年龄:<jsp:getProperty name="student" property="年龄"/></li>
<li>性别:<jsp:getProperty name="student" property="性别"/></li>
</ul>
</div>
</body>
</html>
运行结果如下:
如果JavaBean提供了setter方法,在JSP页面中就可以通过<jsp:setProperty>标签对其属性进行赋值。
(3) 在JSP页面中应用JavaBean
src/cn/ls/Book.java
package cn.ls;
public class Book {
private String 书名;
private double 单价;
private String 作者;
... setter 和 getter
}
web/04add_ls.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>图书信息添加</title>
</head>
<body>
<form action="04info_ls.jsp" method="post">
<table align="center" width="400" height="200" border="1">
<tr>
<td align="center" colspan="2" height="40"><b>添加图书信息</b></td>
</tr>
<tr>
<td align="center">
名称:<input type="text" name="书名">
</td>
</tr>
<tr>
<td align="center">
价格:<input type="text" name="单价">
</td>
</tr>
<tr>
<td align="center">
作者:<input type="text" name="作者">
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" value="添加">
</td>
</tr>
</table>
</form>
</body>
</html>
web/04info_ls.jsp
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<title>图书信息</title>
</head>
<body>
<%request.setCharacterEncoding("UTF-8");%>
<jsp:useBean id="book" class="cn.ls.Book" scope="page">
<jsp:setProperty name="book" property="*"/>
</jsp:useBean>
<table align="center" width="400">
<tr>
<td align="center">名称:
<jsp:getProperty property="书名" name="book"/>
</td>
</tr>
<tr>
<td align="center">价格:
<jsp:getProperty property="单价" name="book"/>
</td>
</tr>
<tr>
<td align="center">作者:
<jsp:getProperty property="作者" name="book"/>
</td>
</tr>
</table>
</body>
</html>
运行结果如下:
2. 动手实践:中文乱码
(1) 中文乱码---中文编码设置成utf-8就能解决
src/cn/ls/Email.java
package cn.ls;
public class Email {
private String 标题;
private String 内容;
... setter 和 getter
}
web/05email_ls.jsp
中文乱码:
- 第1行page contentType="text/html;charset=UTF-8"
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>邮件发送</title>
</head>
<body>
<form action="05release_ls.jsp" method="post">
<table align="center" width="450" height="260" border="1">
<tr>
<td align="center" colspan="2" height="40"><b>邮件发送</b></td>
</tr>
<tr>
<td align="left">
标题:<input type="text" name="标题">
</td>
</tr>
<tr>
<td align="left">
内容:<textarea name="内容" rows="8" cols="40"></textarea>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" value="发送">
</td>
</tr>
</table>
</form>
</body>
</html>
web/05release_ls.jsp
中文乱码:
- 第1行page contentType="text/html;charset=UTF-8"
- 第7行request.setCharacterEncoding("UTF-8");
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<title>邮件信息</title>
</head>
<body>
<% request.setCharacterEncoding("UTF-8");%>
<jsp:useBean id="email" class="cn.ls.Email"/>
<jsp:useBean id="encoding" class="cn.ls.CharactorEncoding"/>
<jsp:setProperty name="email" property="*"/>
<div align="center">
<div id="container">
<div id="title">
<%=email.get标题()%>
</div>
<hr>
<div id="content">
<%=email.get内容()%>
</div>
</div>
</div>
</body>
</html>
运行结果如下:
(2) 判断用户名是否有效
cn/ls/Username.java
package cn.ls;
public class Username {
String reg = "[a-zA-Z\u4E00-\u9FA5]"; //首字母为字母、汉字
String regx = "[a-zA-Z\u4E00-\u9FA50-9_]"; //由字母、汉字、数字、下划线
private String 用户名;
private boolean 有效;
private String 提示;
... 用户名,有效,提示 setter|getter
// 另 get有效 如下
public boolean get有效() {
return isValid();
}
public boolean isValid(){
String name = get用户名();
System.out.println(name);
String firstname = String.valueOf(name.charAt(0));
//首字母为字母、汉字
if(firstname.matches(reg)){
for(int i=1;i<name.length();i++){
if(!String.valueOf(name.charAt(i)).matches(regx)){
set提示("用户姓名错误,只能由字母、汉字、数字和下划线组成!");
return false;
}
}
set提示("用户格式正确!");
return true;
}else{
set提示("用户姓名错误,首字符必须为字母、汉字!");
return false;
}
}
}
web/06login_ls.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>用户输入用户名界面</title>
</head>
<body>
<form action="06judge_ls.jsp" method="post" style="font-size: 20px;">
<ul>
<li>请输入用户名:<input type="text" name="用户名"/>
只能由字母、汉字、数字或者下划线组成
</li>
<li><input type="submit" value="验证"/></li>
</ul>
</form>
</body>
</html>
web/06judge_ls.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>验证反馈界面</title>
</head>
<body>
<% request.setCharacterEncoding("UTF-8");%>
<jsp:useBean id="username" class="cn.ls.Username">
<jsp:setProperty name="username" property="*"/>
</jsp:useBean>
<ul style="font-size: 20px;">
<li>输入的用户名为:
<jsp:getProperty property="用户名" name="username"/>
</li>
<li> 是否有效:
<jsp:getProperty property="有效" name ="username"/>
</li>
<li> 提示信息:
<jsp:getProperty property="提示" name= "username"/>
</li>
</ul>
</body>
</html>
运行结果如下:
3. JSP开发模型
(1) JSP的两种开发模型
JSP技术在Web应用程序的开发过程中运用十分广泛,它功能强大,是当前流行的动态网页技术标准之一。使用JSP技术开发Web应用程序,有两种开发模型可供选择,通常我们称为JSP Model1和JSP Model2。
(2) JSP Model1
在讲解JSP Model1开发模型之前,先来了解一下JSP开发的早期模型。在早期使用JSP开发Java Web应用时,JSP文件是一个独立的、能自主完成所有任务的模块,它负责处理业务逻辑、控制网页流程、向用户展示页面等,JSP早期模型的工作原理如下图所示。
由上图可知,首先浏览器会发送请求给JSP,然后JSP会直接对数据库执行读取、保存或修改等操作,最后JSP会将操作结果响应给浏览器。但是在程序中,JSP页面功能“过于复杂”,会给开发带来一系列的问题,比如JSP页面中HTML代码和Java代码耦合在一起,使得代码的可读性很差,数据、业务逻辑,控制流程混合在一起,使得程序难以修改和维护。为了解决上述问题,SUN公司提供了一种JSP开发的架构模型——JSP Model1。
(2) JSP Model2
JSP Model2架构模型采用JSP+Servlet+ JavaBean的技术,此技术将原本JSP页面中的流程控制代码提取出来,封装到Servlet中,实现了页面显示、流程控制和业务逻辑的分离。实际上JSP Model2模型就是MVC(Model-View-Controller,模型-视图-控制器)设计模式,其中控制器的角色由Servlet实现,视图的角色由JSP页面实现,模型的角色是由JavaBean实现。JSP Model2的工作原理如下图所示。
4. MVC设计模式
MVC设计模式是施乐帕克研究中心在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,提供了一种按功能对软件进行模块划分的方法。MVC设计模式将软件程序分为三个核心模块:模型(Model)、视图(View)和控制器(Controller)。
- 模型(Model)负责管理应用程序的业务数据、定义访问控制以及修改这些数据的业务规则。当模型的状态发生改变时,它会通知视图发生改变,并为视图提供查询模型状态的方法。模型--JavaBean、DAO、Service等
- 视图(View)负责与用户进行交互,它从模型中获取数据向用户展示,同时也能将用户请求传递给控制器进行处理。当模型的状态发生改变时,视图会对用户界面进行同步更新,从而保持与模型数据的一致性。界面--JSP、EL、JSTL或Vue等
- 控制器(Controller)负责应用程序中处理用户交互的部分,它从视图中读取数据,控制用户输入,并向模型发送数据。控制器--Servlet等
任务:按照JSP Model2思想实现用户注册功能
JSP Model2模型是一种MVC设计模式,由于MVC设计模式中的功能模块相互独立,并且使用该模式的软件具有极高的可维护性、可扩展性和可复用性,所以,使用MVC设计模式的Web应用越来越受到欢迎。本任务要求按照JSP Model2模型思想编写一个用户注册程序。
实现用户注册需要:
- 创建两个JSP页面,注册页面register.jsp和注册成功提示信息页面loginSuccess.jsp;
- 一个负责处理用户注册的请求的Servlet类ControllerServlet;
- 两个JavaBean类,封装注册表单信息的JavaBean类RegisterFormBean和封装用户信息的JavaBean类UserBean;
- 一个访问模拟数据库的辅助类DBUtil。
这些组件的关系如下图所示。
(1) UserBean
UserBean是封装用户信息的JavaBean,ControllerServlet根据用户注册信息创建出一个UserBean对象,并将UserBean对象添加到DBUtil对象中,loginSuccess.jsp页面从UserBean对象中提取用户信息进行显示。
package cn.ls.model2.domain;
public class UserBean {
private String 用户名; //定义用户名
private String 密码; //定义密码
private String 邮箱; //定义邮箱
public String get用户名() {
return 用户名;
}
public void set用户名(String 用户名) {
this.用户名 = 用户名;
}
public String get密码() {
return 密码;
}
public void set密码(String 密码) {
this.密码 = 密码;
}
public String get邮箱() {
return 邮箱;
}
public void set邮箱(String 邮箱) {
this.邮箱 = 邮箱;
}
@Override
public String toString() {
return "UserBean{" +
"用户名='" + 用户名 + '\'' +
", 密码='" + 密码 + '\'' +
", 邮箱='" + 邮箱 + '\'' +
'}';
}
}
(2) RegisterFormBean
RegisterFormBean是封装注册表单信息的JavaBean,用于校验从ControllerServlet中获取到的注册表单信息中的各个属性(也就是注册表单内的各个字段中所填写的数据)。
package cn.ls.model2.domain;
import java.util.HashMap;
import java.util.Map;
public class RegisterFormBean {
private String 姓名; //定义用户名
private String 密码; //定义密码
private String 密码2; //定义确认密码
private String 邮箱; //定义邮箱
// 定义成员变量errors,用于封装表单验证时的错误信息
private Map<String, String> errors = new HashMap<String, String>();
public String get姓名() {
return 姓名;
}
public void set姓名(String 姓名) {
this.姓名 = 姓名;
}
public String get密码() {
return 密码;
}
public void set密码(String 密码) {
this.密码 = 密码;
}
public String get密码2() {
return 密码2;
}
public void set密码2(String 密码2) {
this.密码2 = 密码2;
}
public String get邮箱() {
return 邮箱;
}
public void set邮箱(String 邮箱) {
this.邮箱 = 邮箱;
}
// 获取errors集合
public Map<String, String> getErrors() {
return errors;
}
public void setErrors(Map<String, String> errors) {
this.errors = errors;
}
@Override
public String toString() {
return "RegisterFormBean{" +
"姓名='" + 姓名 + '\'' +
", 密码='" + 密码 + '\'' +
", 密码2='" + 密码2 + '\'' +
", 邮箱='" + 邮箱 + '\'' +
", errors=" + errors.toString() +
'}';
}
public boolean validate() {
boolean flag = true;
if (姓名 == null || 姓名.trim().equals("")) {
errors.put("姓名", "请输入姓名.");
flag = false;
}
if (密码 == null || 密码.trim().equals("")) {
errors.put("密码", "请输入密码.");
flag = false;
} else if (密码.length() > 12 || 密码.length() < 6) {
errors.put("密码", "请输入6-12个字符.");
flag = false;
}
if (密码 != null && !密码.equals(密码2)) {
errors.put("密码2", "两次输入的密码不匹配.");
flag = false;
}
// 对email格式的校验采用了正则表达式
if (邮箱 == null || 邮箱.trim().equals("")) {
errors.put("邮箱", "请输入邮箱.");
flag = false;
} else if (!邮箱
.matches("[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+")) {
errors.put("邮箱", "邮箱格式错误.");
flag = false;
}
return flag;
}
// 向Map集合errors中添加错误信息
public void setErrorMsg(String err, String errMsg) {
if ((err != null) && (errMsg != null)) {
errors.put(err, errMsg);
}
}
}
(3) DBUtil
DBUtil是用于访问数据库的辅助类,它相当于一个DAO(数据访问对象)。DBUtil类中封装了一个HashMap对象,用于模拟数据库,HashMap对象中的每一个元素即为一个UserBean对象。
package cn.ls.model2.util;
import java.util.HashMap;
import cn.ls.model2.domain.UserBean;
public class DBUtil {
private static DBUtil instance = new DBUtil();
// 定义users集合,用于模拟数据库
private HashMap<String,UserBean> users = new HashMap<String,UserBean>();
private DBUtil() {
// 向数据库(users)中存入两条数据
UserBean user1 = new UserBean();
user1.set用户名("杰克");
user1.set密码("12345678");
user1.set邮箱("jack@it315.org");
users.put("Jack ",user1);
UserBean user2 = new UserBean();
user2.set用户名("罗丝");
user2.set密码("abcdefg");
user2.set邮箱("rose@it315.org");
users.put("Rose ",user2);
}
public static DBUtil getInstance() {
return instance;
}
// 获取数据库(users)中的数据
public UserBean getUser(String userName) {
return (UserBean) users.get(userName);
}
// 向数据库(users)插入数据
public boolean insertUser(UserBean user) {
if(user == null) {
return false;
}
String userName = user.get用户名();
if(users.get(userName) != null) {
return false;
}
users.put(userName,user);
return true;
}
}
(4) ControllerServlet
ControllerServlet是控制器,它负责处理用户注册的请求,如果注册成功,就会跳到loginSuccess.jsp页面,如果注册失败,重新跳回到register.jsp页面并显示错误信息。
package cn.ls.model2.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.ls.model2.domain.RegisterFormBean;
import cn.ls.model2.domain.UserBean;
import cn.ls.model2.util.DBUtil;
@WebServlet("/ControllerServlet")
public class ControllerServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
// 获取用户注册时表单提交的参数信息
String name = request.getParameter("姓名");
String password=request.getParameter("密码");
String password2=request.getParameter("密码2");
String email=request.getParameter("邮箱");
// 将获取的参数封装到注册表单相关的RegisterFormBean类中
RegisterFormBean formBean = new RegisterFormBean();
formBean.set姓名(name);
formBean.set密码(password);
formBean.set密码2(password2);
formBean.set邮箱(email);
// 验证参数填写是否符合要求,如果不符合,转发到register.jsp重新填写
if(!formBean.validate()){
request.setAttribute("formBean", formBean);
request.getRequestDispatcher("/07register_ls.jsp")
.forward(request, response);
return;
}
// 参数填写符合要求,则将数据封装到UserBean类中
UserBean userBean = new UserBean();
userBean.set用户名(name);
userBean.set密码(password);
userBean.set邮箱(email);
// 调用DBUtil类中的insertUser()方法执行添加操作,并返回一个boolean类型的标志
boolean b = DBUtil.getInstance().insertUser(userBean);
// 如果返回为false,表示注册的用户已存在,则重定向到register.jsp重新填写
if(!b){
request.setAttribute("DBMes", "你注册的用户已存在");
request.setAttribute("formBean", formBean);
request.getRequestDispatcher("/07register_ls.jsp")
.forward(request, response);
return;
}
response.getWriter().print("恭喜你注册成功,3秒钟自动跳转");
// 将成功注册的用户信息添加到Session中
request.getSession().setAttribute("userBean", userBean);
// 注册成功后,3秒跳转到登录成功页面loginSuccess.jsp
response.setHeader("refresh","3;url=07loginSuccess_ls.jsp");
}
}
(5) register.jsp
register.jsp是显示用户注册表单的页面,它将注册请求提交给ControllerServlet处理。
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>用户注册</title>
<style type="text/css">
h3 {
margin-left: 100px;
}
#outer {
width: 750px;
}
span {
color: #ff0000
}
div {
height:20px;
margin-bottom: 10px;
}
.ch {
width: 80px;
text-align: right;
float: left;
}
.ip {
width: 500px;
float: left
}
.ip>input {
margin-right: 20px
}
#bt {
margin-left: 50px;
}
#bt>input {
margin-right: 30px;
}
</style>
</head>
<body>
<form action="ControllerServlet" method="post">
<h3>用户注册</h3>
<div id="outer">
<div>
<div class="ch">姓名:</div>
<div class="ip">
<input type="text" name="姓名" value="${formBean.姓名 }" />
<span>${formBean.errors.姓名}${DBMes}</span>
</div>
</div>
<div>
<div class="ch">密码:</div>
<div class="ip">
<input type="text" name="密码">
<span>${formBean.errors.密码}</span>
</div>
</div>
<div>
<div class="ch">确认密码:</div>
<div class="ip">
<input type="text" name="密码2">
<span>${formBean.errors.密码2}</span>
</div>
</div>
<div>
<div class="ch">邮箱:</div>
<div class="ip">
<input type="text" name="邮箱" value="${formBean.邮箱 }" >
<span>${formBean.errors.邮箱}</span>
</div>
</div>
<div id="bt">
<input type="reset" value="重置 " />
<input type="submit" value="注册" />
</div>
</div>
</form>
</body>
</html>
(6) loginSuccess.jsp
loginSuccess.jsp是用户登录成功后进入的页面,新注册成功的用户自动完成登录,直接进入loginSuccess.jsp页面。
<%@ page pageEncoding="utf-8"
import="cn.ls.model2.domain.UserBean"%>
<!DOCTYPE html>
<html>
<head>
<title>login successfully</title>
<style type="text/css">
#main {
width: 500px;
height: auto;
}
#main div {
width: 200px;
height: auto;
}
ul {
padding-top: 1px;
padding-left: 1px;
list-style: none;
}
</style>
</head>
<body>
<%
if (session.getAttribute("userBean") == null) {
%>
<jsp:forward page="07register_ls.jsp" />
<%
return;
}
%>
<div id="main">
<div id="welcome">恭喜你,登录成功</div>
<hr />
<div>您的信息</div>
<div>
<ul>
<li>您的姓名:${userBean.用户名 }</li>
<li>您的邮箱:${userBean.邮箱 }</li>
</ul>
</div>
</div>
</body>
</html>
JavaBean、MVC设计模式与Java中Dao、Service、Controll三层体系
1. JavaBean
JavaBean实际就是一个普通的Java类,为了规范开发,要求JavaBean具有如下规范:
① 具有一个公共的、无参的构造方法;
② 类的属性私有,且必须提供公共的setter和getter方法用于外部对属性赋值和获取属性值;
简而言之:JavaBean = 属性私有 + 公共的setter/getter方法 + 无参构造器
ORM编程思想(object relational mapping,对象关系映射)
- ① 一个数据表对应一个JavaBean
- ② 表中的一条记录对应JavaBean的一个对象
- ③ 表中的一个字段对应JavaBean的一个属性
(在设计实体类和数据库表时尽量做到ORM,即属性名和字段名对应,表名和实体类类名对应,可以方便对数据库表的操作)
- 实体类(Entity Class):就是Java中的ORM思想形成的映射,将数据库中的一个表映射成对应的一个Java类(就是JavaBean),主要职责是存储和管理系统内部的信息。
- POJO(Plain Ordinary Java Object,普通Java对象):实际就是普通JavaBean,是为了避免和EJB混淆所创造的简称。
- 持久化类:是指其实例需要被持久化到数据库中的类。持久化类符合JavaBean的规范,包含私有属性,以及与之对应的getter()和getter()方法。
- 持久化(Persistence):把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘、数据库)。持久化的主要应用是将内存中的对象存储在数据库中、磁盘文件或XML文件中等等。
在实际开发中,JavaBean、实体类、POJO、持久类并没有本质的区别,但都必须满足JavaBean的规范。在涉及Spring对Bean的管理时,称为JavaBean;在Spring JDBC Template中需要对数据库进行操作,称为实体类(Entity Class);在MyBatis等持久化框架中涉及多个对象之间的关系,称为POJO或持久化类。
之所以有不同的名称,是因为需要处理的逻辑场合不同,类似在家里父母叫你小名,在学校老师同学叫你全名,在银行办理业务时工作人员叫你女士/先生,但你还是你,有姓名、性别、身份证号等属性,这是你必须要满足的规范。
2. Java三层体系
Dao层通过操作实体类(Entity Class),从而操作数据库中的表,完成对应数据的CRUD操作。
- Dao层 Dao全称Data Access Object(数据访问对象)主要负责访问数据库,对数据的CRUD,获取结果集返回给Service,不会涉及事务。
- Service层 Service层主要负责业务逻辑的实现,实际就是对Dao层的增删改查操作的进一步封装,涉及到事务的操作。如:获取数据库连接,关闭数据库连接,事务回滚或者一些复杂的逻辑业务处理。
- Controller层 Controller层主要用于对 业务逻辑 进行控制,控制用户输入,接收来自前端的请求,将需要执行的操作交给Service层进行处理,再将处理后的结果返回给前端。
三者之间的关系
几乎所有的业务逻辑,实际上最后就是对数据库表的操作,Dao层面向数据库中的表,Service进行事务、业务逻辑的具体实现,Controller层对接收到的请求进行控制,然后负责调用Service层进行业务逻辑实现,Service层将逻辑处理中需要对数据库表的操作交给Dao层进行数据操作,最后将处理结果逐层返回给前端,用户就可以看到最后的处理结果。
3. MVC设计模式
MVC是一种软件设计模式,将软件程序分为3个核心模块:模型(Model)、视图(View)、控制器(Controller)
- 模型(Model):管理数据库,用于数据的封装和传输,实现具体业务功能(事务处理、算法等)。
- 视图(View):负责与用户交互,从模型中获取数据通过网页向用户展示,将用户请求传递给控制器进行处理。
- 控制器(Controller):接收用户请求,对请求进行处理和转发,用于业务流程控制,并向模型发送数据。
三者之间的关系
用户通过View操作软件,View将请求传递给Controller,Model负责数据的管理,View负责与用户交互,Controller负责对用户的请求进行响应,同时,当数据更新时会传给View然后更新页面。
三层体系与MVC之间的关系
三层体系和MVC之间并不矛盾,三层体系是一种编程思想,目的是为了降低模块之间的耦合,更好的处理业务逻辑;MVC是一种软件设计模式,按照功能对软件进行的模块化的划分,目的是为了更好的实现软件开发。二者之间的关系如下:
关于MVC设计模式在Spring MVC框架中会进行详细的说明,Spring后会说到该种框架。