Prism代码语法高亮

第8章 JavaBean技术与JSP 开发模型


学习目标

在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代码。

图1 早期的JSP开发流程图

(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整合的开发模式如下图所示。

图2 应用JavaBean与JSP整合的开发模式

(4) JavaBean定义和编程规范

JavaBean是一种可以重用、使用面向对象思想进行封装(---成员变量私有、setter|getter公开、无参构造)的Java类。对软件开发人员来说,JavaBean带来的最大的优点是充分提高了代码的可重用性,并且对软件的可维护性和易维护性起到了积极作用。

javaBean也被称为实体类,所谓的实体类就是现实生活中有的,其对象可以用于在程序中封装数据

JavaBean满足的编程规范

1.2 JavaBean种类

JavaBean起初的目的是将可以重复使用的代码进行打包。在传统的应用中,JavaBean主要用于实现一些可视化界面,如一个窗体、按钮、文本框等,这样的JavaBean称之为可视化的JavaBean。随着技术的不断发展与项目的需求,JavaBean的功能与应用范围也在不断扩展,目前JavaBean主要用于实现一些业务逻辑或封装一些业务对象,由于这样的JavaBean并没有可视化的界面,所以又称之为非可视化的JavaBean

注意:

参照ch04创建ch08_zxx项目,创建ch08首页index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>JavaBean技术与JSP开发模型</title>
  </head>
  <body>
  <h1>ch08 JavaBean技术与JSP开发模型(张晓轩)</h1>
  <hr>
  <a href="01index_zxx.jsp">1. 输入并提交用户名和密码</a><br>
  <a href="02stuInfo_zxx.jsp">2. 获取JavaBean属性信息</a><br>
  <a href="03stuInfo_zxx.jsp">3. 对Student对象的属性进行赋值并输出</a><br>
  <a href="04add_zxx.jsp">4. 图书信息添加</a><br>
  <a href="05email_zxx.jsp">5. 使用JavaBean解决中文乱码</a><br>
  <a href="06login_zxx.jsp">6. 判断用户名是否有效</a><br>
  <a href="07register_zxx.jsp">7. 按照JSP Model2思想实现用户注册功能</a><br>
  <hr>
  <p><a href="http://101.42.158.247/21javaweb.html">返回课程首页</a>
    张晓轩 <script>document.write(document.lastModified); </script> 制作</p>
  </body>
</html>

运行结果如下:

图3 ch08 JavaBean技术与JSP开发模型--首页

非可视化的JavaBean的应用

cn.zxx.User.java

package cn.zxx;
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_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
  <title>登录页面</title>
</head>
<body>
<form action="01result_zxx.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_zxx.jsp

<%@ page import="cn.zxx.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("张晓轩")&& user.get密码().equals("123456")){
            out.print("恭喜您,登录成功!");
        } else{
            out.print("请输入正确的用户名和密码!");
        }
    %>
    <br/><br/>
    <a href="01index_zxx.jsp">返回</a>
</div>
</body>
</html>

运行结果如下:

图4 输入并提交用户名和密码

1.3 JavaBean的应用

(1) 获取JavaBean属性信息

cn.zxx.Student0.java

package cn.zxx;
public class Student0 {
    private String 姓名 = "张晓轩";
    private int 年龄 = 30;
    private String 性别= "男";

    public String get姓名() {
        return 姓名;
    }

    public int get年龄() {
        return 年龄;
    }

    public String get性别() {
        return 性别;
    }
}

02stuInfo_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
    <title>学生信息</title>
</head>
<body>
<jsp:useBean id="student" class="cn.zxx.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>

运行结果如下:

图5 获取JavaBean属性信息

<jsp:useBean>标签和<jsp:getProperty>标签操作Java类

(2) 设置和获取JavaBean属性信息

cn.zxx.Student.java

package cn.zxx;
public class Student {
    private String 姓名;
    private int 年龄;
    private String 性别;
    ... setter 和 getter
}

03stuInfo_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学生信息</title>
</head>
<body>
<jsp:useBean id="student" class="cn.zxx.Student"/>
<jsp:setProperty name="student" property="姓名" value="张晓轩"/>
<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>

运行结果如下:

图6 设置和获取JavaBean属性信息

如果JavaBean提供了setter方法,在JSP页面中就可以通过<jsp:setProperty>标签对其属性进行赋值。

(3) 在JSP页面中应用JavaBean

src/cn/zxx/Book.java

package cn.zxx;
public class Book {
    private String 书名;
    private double 单价;
    private String 作者;
    ... setter 和 getter
}

web/04add_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>图书信息添加</title>
</head>
<body>
<form action="04info_zxx.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_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
    <title>图书信息</title>
</head>
<body>
<%request.setCharacterEncoding("UTF-8");%>
<jsp:useBean id="book" class="cn.zxx.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>

运行结果如下:

图7 在JSP页面中应用JavaBean

2. 动手实践:中文乱码

(1) 中文乱码---中文编码设置成utf-8就能解决

src/cn/zxx/Email.java

package cn.zxx;
public class Email {
    private String 标题;
    private String 内容;

   ... setter 和 getter
}

web/05email_zxx.jsp

中文乱码:

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>邮件发送</title>
</head>
<body>
<form action="05release_zxx.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_zxx.jsp

中文乱码:

<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
    <title>邮件信息</title>
</head>
<body>
<% request.setCharacterEncoding("UTF-8");%>
<jsp:useBean id="email" class="cn.zxx.Email"/>
<jsp:useBean id="encoding" class="cn.zxx.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>

运行结果如下:

图8 解决中文乱码

(2) 判断用户名是否有效

cn/zxx/Username.java

package cn.zxx;
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_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>用户输入用户名界面</title>
</head>
<body>
    <form action="06judge_zxx.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_zxx.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>验证反馈界面</title>
</head>
<body>
    <% request.setCharacterEncoding("UTF-8");%>
    <jsp:useBean id="username" class="cn.zxx.Username">
        <jsp:setProperty name="username" property="*"/>
    </jsp:useBean>
    <ul style="font-size: 20px;">
        <li>输入的用户名为:
            <jsp:getProperty property="用户名" name="username"/>
        </li>
        <li>&nbsp;&nbsp;&nbsp;是否有效:
            <jsp:getProperty property="有效" name ="username"/>
        </li>
        <li>&nbsp;&nbsp;&nbsp;提示信息:
            <jsp:getProperty property="提示" name= "username"/>
        </li>
    </ul>
</body>
</html>

运行结果如下:

图9 判断用户名是否有效

3. JSP开发模型

(1) JSP的两种开发模型

JSP技术在Web应用程序的开发过程中运用十分广泛,它功能强大,是当前流行的动态网页技术标准之一。使用JSP技术开发Web应用程序,有两种开发模型可供选择,通常我们称为JSP Model1和JSP Model2。

(2) JSP Model1

在讲解JSP Model1开发模型之前,先来了解一下JSP开发的早期模型。在早期使用JSP开发Java Web应用时,JSP文件是一个独立的、能自主完成所有任务的模块,它负责处理业务逻辑、控制网页流程、向用户展示页面等,JSP早期模型的工作原理如下图所示。

图10 JSP早期模型

由上图可知,首先浏览器会发送请求给JSP,然后JSP会直接对数据库执行读取、保存或修改等操作,最后JSP会将操作结果响应给浏览器。但是在程序中,JSP页面功能“过于复杂”,会给开发带来一系列的问题,比如JSP页面中HTML代码和Java代码耦合在一起,使得代码的可读性很差,数据、业务逻辑,控制流程混合在一起,使得程序难以修改和维护。为了解决上述问题,SUN公司提供了一种JSP开发的架构模型——JSP Model1。

图11 JSP Model1

(2) JSP Model2

JSP Model2架构模型采用JSP+Servlet+ JavaBean的技术,此技术将原本JSP页面中的流程控制代码提取出来,封装到Servlet中,实现了页面显示、流程控制和业务逻辑的分离。实际上JSP Model2模型就是MVC(Model-View-Controller,模型-视图-控制器)设计模式,其中控制器的角色由Servlet实现,视图的角色由JSP页面实现,模型的角色是由JavaBean实现。JSP Model2的工作原理如下图所示。

图12 JSP Model2

4. MVC设计模式

MVC设计模式是施乐帕克研究中心在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,提供了一种按功能对软件进行模块划分的方法。MVC设计模式将软件程序分为三个核心模块:模型(Model)、视图(View)和控制器(Controller)。

图13 MVC三个模块之间的关系

任务:按照JSP Model2思想实现用户注册功能

JSP Model2模型是一种MVC设计模式,由于MVC设计模式中的功能模块相互独立,并且使用该模式的软件具有极高的可维护性、可扩展性和可复用性,所以,使用MVC设计模式的Web应用越来越受到欢迎。本任务要求按照JSP Model2模型思想编写一个用户注册程序。

实现用户注册需要:

这些组件的关系如下图所示。

图14 组件的关系

(1) UserBean

UserBean是封装用户信息的JavaBean,ControllerServlet根据用户注册信息创建出一个UserBean对象,并将UserBean对象添加到DBUtil对象中,loginSuccess.jsp页面从UserBean对象中提取用户信息进行显示。

package cn.zxx.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.zxx.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.zxx.model2.util;
import java.util.HashMap;
import cn.zxx.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.zxx.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.zxx.model2.domain.RegisterFormBean;
import cn.zxx.model2.domain.UserBean;
import cn.zxx.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_zxx.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_zxx.jsp")
                    .forward(request, response);
            return;
        }
        response.getWriter().print("恭喜你注册成功,3秒钟自动跳转");
        // 将成功注册的用户信息添加到Session中
        request.getSession().setAttribute("userBean", userBean);
        // 注册成功后,3秒跳转到登录成功页面loginSuccess.jsp
        response.setHeader("refresh","3;url=07loginSuccess_zxx.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.zxx.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_zxx.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>
图15 按照JSP Model2思想实现用户注册
图16 ch08源代码文件结构




JavaBean、MVC设计模式与Java中Dao、Service、Controll三层体系


1. JavaBean

JavaBean实际就是一个普通的Java类,为了规范开发,要求JavaBean具有如下规范:

① 具有一个公共的、无参的构造方法;

② 类的属性私有,且必须提供公共的setter和getter方法用于外部对属性赋值和获取属性值;

简而言之:JavaBean = 属性私有 + 公共的setter/getter方法 + 无参构造器

ORM编程思想(object relational mapping,对象关系映射)

(在设计实体类和数据库表时尽量做到ORM,即属性名和字段名对应,表名和实体类类名对应,可以方便对数据库表的操作)

在实际开发中,JavaBean、实体类、POJO、持久类并没有本质的区别,但都必须满足JavaBean的规范。在涉及Spring对Bean的管理时,称为JavaBean;在Spring JDBC Template中需要对数据库进行操作,称为实体类(Entity Class);在MyBatis等持久化框架中涉及多个对象之间的关系,称为POJO或持久化类。

之所以有不同的名称,是因为需要处理的逻辑场合不同,类似在家里父母叫你小名,在学校老师同学叫你全名,在银行办理业务时工作人员叫你女士/先生,但你还是你,有姓名、性别、身份证号等属性,这是你必须要满足的规范。

2. Java三层体系

Dao层通过操作实体类(Entity Class),从而操作数据库中的表,完成对应数据的CRUD操作。

三者之间的关系

几乎所有的业务逻辑,实际上最后就是对数据库表的操作,Dao层面向数据库中的表,Service进行事务、业务逻辑的具体实现,Controller层对接收到的请求进行控制,然后负责调用Service层进行业务逻辑实现,Service层将逻辑处理中需要对数据库表的操作交给Dao层进行数据操作,最后将处理结果逐层返回给前端,用户就可以看到最后的处理结果。

图17 三者之间的关系

3. MVC设计模式

MVC是一种软件设计模式,将软件程序分为3个核心模块:模型(Model)、视图(View)、控制器(Controller)

三者之间的关系
图18 MVC三者之间的关系

用户通过View操作软件,View将请求传递给Controller,Model负责数据的管理,View负责与用户交互,Controller负责对用户的请求进行响应,同时,当数据更新时会传给View然后更新页面。

三层体系与MVC之间的关系

三层体系和MVC之间并不矛盾,三层体系是一种编程思想,目的是为了降低模块之间的耦合,更好的处理业务逻辑;MVC是一种软件设计模式,按照功能对软件进行的模块化的划分,目的是为了更好的实现软件开发。二者之间的关系如下:

图19 三层体系与MVC之间的关系

关于MVC设计模式在Spring MVC框架中会进行详细的说明,Spring后会说到该种框架。


返回