■ 学习目标

  • 了解Model1和Model2的概念
  • 掌握JavaBean的概念
  • 能在Jsp页面中熟练使用JavaBean
  • 了解JavaBean的基本原理
  • 掌握表单操作的相关知识

目录:


非MVC模式(Model1)

单纯的JSP页面编程

定义:在单纯的JSP编程模式下,通过应用JSP中的脚本标志,可直接在JSP页面中实现各种功能。

优点:逻辑简单,容易理解

缺点:

  • Java代码与HTML耦合
  • 极难维护与扩展
  • 不方便测试

JSP+JavaBean编程

定义:JSP负责表示显示和控制逻辑,JavaBean负责业务逻辑。JSP程序开发经典设计模式之一,适合中小型网站开发。

优点:

  • 纯净的JSP页面
  • 可重用的组件
  • 方便进行调试
  • 易维护易扩展

缺点:表现逻辑和控制逻辑仍未分离

JSP+JavaBean开发模式示意

6-1-1.png

MVC模式(Model2)

MVC(Model-View-Controller,模型—视图—控制器)是一种程序设计概念,它同时适用于简单的和复杂的程序。

使用该模式可将待开发的应用程序分解为3个独立的部分:模型、视图和控制器。

6-1-2.png

  • Model(模型):指的是业务逻辑的代码,是应用程序中真正用来完成任务的部分。
  • View(视图):实际上就是程序与用户进行交互的界面,用户可以看到它的存在。视图可以具备一定的功能并应遵守对其的约束,在视图中不应包含对数据处理的代码,即业务逻辑代码。
  • Controller(控制器):主要控制用户请求并作出响应。它根据用户的请求选择模型或修改模型,并决定返回怎样的视图。

MVC:JSP+Servlet+JavaBean编程

在JSP+JavaBean设计模式的基础上加入Servlet来实现程序中的控制层。

由Servlet来执行业务逻辑并负责程序的流程控制,JavaBean组件实现业务逻辑,充当着模型的角色,JSP用于页面的显示。

JSP+Servlet+JavaBean模式示意图

6-1-3.png

剖析JavaBean

什么是组件?
□ 独立的模块
□ 外界不了解其内部实现
□ 外界通过其提供的接口对组件进行访问
□ 可以重用
目前有代表性的组件技术
COM、COM+、JavaBean、EJB等

什么是JavaBean

JavaBean是Java的可重用组件技术,实质是一种符合某些命名和设计规范的Java类。

JavaBean通常封装成为具有特定功能或者处理某个业务(如连接数据库,访问数据库等)

应用:

  • JSP页面内可以访问JavaBean的对象以及它的方法。
  • 在JSP的Web应用中集成JavaBean组件,由JavaBean中处理业务逻辑,然后在JSP中调用,而JSP页面着重网页界面的设计,可以实现业务逻辑和前台显示的部分分离。

6-3-1.png

使用JavaBean的好处

  • 可以使得JSP页面变得清晰;
  • 节省软件开发时间;
  • 降低系统维护的难度

JavaBean的分类

  • 可视的JavaBean:传统的JavaBean应用于可视化界面(如java图形界面中使用的按钮、文本框或列表框等等)。
  • 非可视化的JavaBean:封装逻辑、封装数据,与JSP搭配使用。

JavaBean的特征

通常一个标准的JavaBean有以下特征(编写规范):

  • 一定使用了package语句进行打包
  • JavaBean是一个public类型的类
  • 有一个无参数的构造方法
  • 属性一般是私有的(即用private修饰)
  • 对属性值xxx的获取有相应的getXxx()方法,并且此方法是公有的(即用public修饰
    若要获取的属性xxx为boolean类型则可以使用isXxx()方法
  • 对属性值xxx的设置有相应的setXxx()方法,并且此方法也是公有的(即用public修饰

典型JavaBean示意

UserBean.java   
package jsp.test;
public class UserBean {
    private String userName;        //用户名
    private String pwd;         //密码
    private String name;        //真实姓名
    private String gender;      //性别
    private int age;            //年龄
    private String email;       //电子邮件
    private String tel;             //固定电话
    private String mphone;      //手机
    public int getAge() {  return age; }
    public void setAge(int age) { this.age = age; }
    public String getEmail() { return email;    }
    public void setEmail(String email) { this.email = email;    }
    public String getGender() { return gender; }
    public void setGender(String gender) { this.gender = gender;    }
    public String getMphone() { return mphone;  }
    public void setMphone(String mphone) { this.mphone = mphone; }
    public String getName() { return name;  }
    public void setName(String name) { this.name = name;    }
           ……

在JSP中使用JavaBean

一个JavaBean编写完以后,需要将它编译成.class文件,并将此.class文件(连同其目录)放到本次应用的WEB-INF\classes目录之下。

注意:用Eclipse编写会自动地把.class放到相应的class目录下

需要使用以下几个动作元素

  • <jsp:useBean> 标签: 在网页中创建一个Bean对象
  • <jsp:setProperty> 标签:用于为Bean对象中的属性赋值
  • <jsp:getProperty> 标签:用于获取Bean对象中属性的值

JavaBean应用案例

<%@ page pageEncoding="utf-8" %>
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<jsp:useBean id="myBean" scope="request" class="bean.SampleBean"/>
属性sample的初始值:<jsp:getProperty name="myBean" property="sample"/>
</p>
<jsp:setProperty name="myBean" property="sample" value="Hello.JSP"/>
属性sample的新值:<jsp:getProperty name="myBean" property="sample"/>
</html>
package bean;
public class SampleBean {
    private String sample = "Hello,World";
    public void setSample(String s) {
        if(s != null)
            sample = s;
    }
    public String getSample() { return sample; }
}

<jsp:useBean>

该标签用来在JSP页面中创建一个JavaBean实例。

语法如下:

<jsp:useBean id=“beanname” class=“package.class” [scope=“page|request|session|application”] />

其中:

  • id指定该JavaBean的实例变量的名称
  • scope指定该Bean变量的有效范围,指定Bean在哪种上下文内可用,可以取page,request,session和application四个值之一
    • page(是默认值)表示该Bean只在当前页面内可用(保存在当前页面的PageContext内)
    • request表示该Bean在当前的客户请求内有效(保存在ServletRequest对象内)
    • session表示该Bean对当前HttpSession内的所有页面都有效
    • application表示该Bean对所有具有相同ServletContext的页面都有效

scope很重要,是因为 <jsp:useBean> 只有在不存在具有相同id和scope的对象时才会实例化新的对象;如果已有id和scope都相同的对象则直接使用已有的对象,此时 <jsp:useBean> 开始标记和结束标记之间的任何内容都将被忽略

<jsp:getProperty>

<jsp:getProperty> 标签用来获取Bean对象的属性值,并显示在页面上,其语法如下:

<jsp:getProperty name=“beanname” property=“propertyname” />
  • name指出了要获取哪个bean的属性值,取值与useBean中 id值相同;
  • property指出要获取该bean的哪个属性值

注意:

  • 在使用 <jsp:getProperty> 之前,必须有由 <jsp:useBean> 所创建的Bean对象
  • 如果使用 <jsp:getProperty> 来检索的值是空值,那么将会产生NullPointerException例外;如果使用程序段或表达式来检索值,那么在浏览器上出现的是将是null(空值)

<jsp:setProperty>

<jsp:setProperty> 设置Bean对象的属性的语法有多种:

1、简单bean属性设置

<jsp:setProperty name=“beanName”
            property=“propertyName”
            value=“propertyValue” />

其中:

  • name指出是在操作哪个bean
  • property指出对该bean的哪个属性赋值
  • value用来指定给属性赋的值

例:

<jsp:setProperty name="myBean"   property="sample" value="Hello,JSP"/>

【例】一个描述学生的beans,在一个JSP页面中获得一个这样的beans,其有效范围是page。在JSP页面中使用动作标签设置、获取该beans的属性。

public class Student  { 
  String name=null;
  long number;
  double height,weight;
  public String getName() { return name; }
  public void setName(String newName) { name=newName; }
  public long getNumber() {return number; }
  public void setNumber(long newNumber) { number=newNumber; }
  public double getHeight() { return height; }
  public void setHeight(double newHeight) { height=newHeight; }
  public double getWeight() { return weight; }
  public void setWeight(double newWeight) { weight=newWeight; }
}
<%@ page contentType="text/html;charset=utf-8" %>
<%@ page import="Student"%> 
<HTML> <BODY> <Font size=10>
<jsp:useBean id="zhang" class="Student" scope="page" > </jsp:useBean>
<jsp:setProperty  name= "zhang"  property="name" value="张小三"  />
<P>名字是:<jsp:getProperty  name= "zhang"  property="name"  />
<jsp:setProperty  name= "zhang"  property="number" value="1999001"  />
<P>学号是:<jsp:getProperty  name= "zhang"  property="number"  />
<% double height=1.70; %>
<jsp:setProperty name= "zhang"  property="height" value="<%=height+0.05%>"  />
<P>身高是:<jsp:getProperty  name= "zhang"  property="height"  />米
<jsp:setProperty  name= "zhang"  property="weight" value="66.65"  />
<P>体重是:<jsp:getProperty  name= "zhang"  property="weight"  />公斤
</FONT> </BODY> </HTML>

2、将单个属性值和输入参数关联

<jsp:setProperty name=“beanName”
        property=“propertyName”
        param=“paramName” />

param代替value表示将一个form表单中传入参数的值赋给bean的某个属性。

其中:

  • name指出是在操作哪个bean
  • property指出对该bean的哪个属性赋值
  • 而param表示传入参数的名字
<html>
<form action="test4.jsp">
姓名:<input type="text"   name="user">
年龄:<input type="text" name="age">
<input type="submit">
</form>
</html>
package bean;
public class TestBean {
    private String userName;
    private int age;
    public int getAge() { return age;}
    public void setAge(int age) {
        this.age = age;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;  
    }
}
<%@ page pageEncoding="utf-8" %>
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<jsp:useBean id="myBean" scope="request" class="bean.TestBean"/>
<jsp:setProperty name="myBean" property="userName"  param=“user”/>
<jsp:setProperty name="myBean" property="age" />
<jsp:getProperty name="myBean" property="userName"/>
<jsp:getProperty name="myBean" property="age"/>
</html>

3、输入参数和bean属性值相同,可以简化

<jsp:setProperty name=“beanName” property=“propertyName” />

这种用法将form表单中传入参数的值赋给bean的某个属性

要求:form表单中参数的名称要与propertyName一致

4、将bean的所有属性与表单中参数关联

<jsp:setProperty name=“beanName” property=“*” />

在这种用法中,JSP容器会一个个检查传入的参数,如果某个传入参数的名字和bean中某个属性的名字相同,则将该参数的值赋给bean中的属性。

使用这种方式可以一次为多个属性赋值

<html>
<form action="test3.jsp">
姓名:<input type="text"   name="userName">  年龄:<input type="text" name="age">
<input type="submit">
</form>
package bean;
public class TestBean {
    private String userName;
    private int age;
    public int getAge() { return age;}
    public void setAge(int age) {
          this.age = age; }
    public String getUserName() {
          return userName; }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}
<%@ page pageEncoding="utf-8" %>
<%@ page contentType="text/html;charset=utf-8" %>
<html>
<jsp:useBean id="myBean" scope="request" class="bean.TestBean"/>
<jsp:setProperty name="myBean" property=“*" />
<jsp:getProperty name="myBean" property="userName"/>
<jsp:getProperty name="myBean" property="age"/>
</html>

JavaBean生命周期

scope 属性-表明JavaBean对象存在的范围,可为如下几个值:
page(默认)、request、session、Application

Page:

  • 保存在pageContext对象中,有page范围的JavaBean实例只能在当前创建这个JavaBean的JSP文件中进行操作,这个实例只有在请求返回给客户端后或者转移到另外的JSP页面后才会释放掉。
  • page范围的JavaBean常用于进行一次性操作的JavaBean,这样的Bean用的最多,比如大部分表单提交,Bean的一些计算处理等都可以使用page范围的JavaBean

Request

  • 有request范围的JavaBean实例可以在处理请求所有JSP页面中都存在,这个对象只有在请求全部处理完毕后才会被释放掉
  • request范围的JavaBean常用于共享同一次请求的JSP页面中,比如判断用户登录功能,如果用户名密码合法就可以forward到一个合法页面中,否则就forward到一个出错页面,当然转移后的页面仍然能够得到用户的输入。

Session

  • JavaBean对象是保存在session范围的
  • JavaBean实例的生存周期是整个session,只有当session过期后才能释放掉,
  • 这样常用于共享同一session的JSP页面,比如购物车一般就是放在session中的或者登陆后的用户信息等也可以在session中

application

  • JavaBean对象保存在application对象中,

  • 有application范围的JavaBean对象的生存周期是整个application。这就意味着这样的JavaBean的生存周期是整个应用程序,当web Server停掉才会消失掉。

  • 这样的常用于共享同一application的JSP程序中,比如程序中一些经常用到配置东西如数据库连接URL,全局的计数器或者是聊天室中人员信息等。

使用JavaBean处理表单数据

操纵HTML表单步骤

  1. 写JSP原文件,创建一些HTML的表单并命名。
  2. 在Java文件里写Bean,定义属性,GET或者SET方法来配合已经被指定好名字的表单。
  3. 回到JSP原文件中,增加 <jsp:useBean> 标签来创建一个或者调用一个现成的Bean。
  4. 增加 <jsp:setProperty> 标签设置HTML表单中需要SET方法的Bean的属性。
  5. 增加 <jsp:getProperty> 标签设置HTML表单中需要GET方法的Bean的属性。
  6. 如果需要处理更多的用户数据,用request对象。

eg1. 用户通过form表单提交数据,提交的数据被处理后,再在Jsp文件中显示处理

  • usingGetParameter.html让用户输入个人信息
  • usingGetParameter.jsp将其一一输出

eg2. 使用Jsp+JavaBean形式处理表单

  • showInfo.jsp让用户输入个人信息
  • 服务器取得这些信息之后,利用show.java这个Javabean中的方法将其一一输出

乱码解决方法汇总

  1. 页面保存:<%@ page contentType="text/html;charset=utf-8" %>

  2. 提交表单页面:<%request.setCharacterEncoding("utf-8");%>

  3. cookie保存数据:
    写入Cookie nameCookie = new Cookie("name", java.net.URLEncoder.encode(strname));
    读取<%=java.net.URLDecoder.decode(name)%>

  4. str.getBytes(“utf-8”):目的是将str按utf-8取出。

  5. new String(str.getBytes("utf-8"),"ISO-8859-1") 是将取出的utf-8 ,转换为ISO-8859-1(UNICODE)或者 new String (str.getBytes("ISO-8859-1"), “utf-8")