ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # 什么是 JavaBean JavaBean 是一个遵循特定写法的 Java 类,它通常具有如下特点: * 这个 Java 类必须具有一个无参的构造函数。 * 属性必须私有化。 * 私有化的属性必须通过 public 类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。 ~~~ public class Person { //------------------Person类封装的私有属性--------------------------------------- private String name = "aaa"; // getClass() private int age; private Date birthday; //--------------------------------------------------------- //------------------Person类的无参数构造方法--------------------------------------- public Person() { super(); // TODO Auto-generated constructor stub } //--------------------------------------------------------- //------------------Person类对外提供的用于访问私有属性的public方法--------------------------------------- public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //--------------------------------------------------------- } ~~~ JavaBean 在 J2EE 开发中,通常用于封装数据,对于遵循以上写法的 JavaBean 组件,其它程序可以通过反射技术实例化 JavaBean 对象,并且通过反射那些遵守命名规范的方法,从而获知 JavaBean 的属性,进而调用其属性保存数据。 ## JavaBean 的属性 JavaBean 的属性可以是任意类型,并且一个 JavaBean 可以有多个属性。每个属性通常都需要具有相应的 setter、 getter 方法,setter 方法称为属性修改器,getter 方法称为属性访问器。 属性修改器必须以小写的 set 前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如,name 属性的修改器名称为 setName,password 属性的修改器名称为 setPassword。 属性访问器通常以小写的 get 前缀开始,后跟属性名,且属性名的第一个字母也要改为大写,例如,name 属性的访问器名称为 getName,password 属性的访问器名称为 getPassword。 一个 JavaBean 的某个属性也可以只有 set 方法或 get 方法,这样的属性通常也称之为只写、只读属性。 # JSP 中使用 JavaBean JSP 技术提供了三个关于 JavaBean 组件的动作元素,即 JSP 标签,它们分别为: * `<jsp:useBean>`标签:用于在 JSP 页面中查找或实例化一个 JavaBean 组件。 * `<jsp:setProperty>`标签:用于在 JSP 页面中设置一个 JavaBean 组件的属性。 * `<jsp:getProperty>`标签:用于在 JSP 页面中获取一个 JavaBean 组件的属性。 ## `<jsp:useBean>`标签 `<jsp:useBean>`标签用于在指定的域范围内查找指定名称的 JavaBean 对象: * 如果存在则直接返回该 JavaBean 对象的引用。 * 如果不存在则实例化一个新的 JavaBean 对象并将它以指定的名称存储到指定的域范围中 ~~~ <jsp:useBean id="beanName" class="package.class" scope="page|request|session|application"/> ~~~ * id 属性用于指定 JavaBean 实例对象的引用名称和其存储在域范围中的名称。 * class 属性用于指定 JavaBean 的完整类名(即必须带有包名)。 * scope 属性用于指定 JavaBean 实例对象所存储的域范围,其取值只能是 page、request、session 和 application 等四个值中的一个,其默认值是 page `<jsp:useBean>`标签使用范例: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:userbean标签的使用</title> </head> <body> <jsp:useBean id="person" class="cn.domain.Person" scope="page" /> <%=person.getName() %> </body> </html> ~~~ 运行结果如下: ![](https://box.kancloud.cn/2572ce631ea8fbda8768d7e3d30ebe6b_460x150.png) `<jsp:useBean>`执行原理 上面我们在 1.jsp 中使用 ~~~ <jsp:useBean id="person" class="cn.domain.Person" scope="page" /> ~~~ 实例化了一个 cn.domain.Person 类的对象,那么这个 person 对象是怎么实例化出来的呢?1.jsp 在执行的过程中首先会翻译成一个 servlet,因此我们可以通过查看 1.jsp 页面生成的 servlet 的 java 代码来查看 person 对象的实例化过程。 找到 tomcat 服务器下的 “work\Catalina\localhost\项目名称 \org\apache\jsp” 这个目录,就可以看到将 1.jsp 页面翻译成 servlet 的 java 源码了,如下所示: 使用 Sublime Text 打开_1_jsp.java 文件,在_jspService 方法中可以看到 person 对象的创建过程,如下所示: ~~~ cn.domain.Person person = null; person = (cn.itcast.domain.Person) _jspx_page_context.getAttribute("person", javax.servlet.jsp.PageContext.PAGE_SCOPE); if (person == null){ person = new cn.itcast.domain.Person(); _jspx_page_context.setAttribute("person", person, javax.servlet.jsp.PageContext.PAGE_SCOPE); } ~~~ 下面我们来分析一下上述生成的代码: 首先是定义一个 person 对象,值是 null。 ~~~ cn.domain.Person person = null; // 定义一个空的person对象 ~~~ 然后是使用 pageContext 对象的 getAttribute 方法获取存储在 `PageContext.PAGE_SCOPE` 域中的 Person 对象。 ~~~ person = (cn.domain.Person) _jspx_page_context.getAttribute("person", javax.servlet.jsp.PageContext.PAGE_SCOPE); ~~~ 如果在 PageContext.PAGE_SCOPE 域中的 Person 对象没有找到,那么就创建一个新的 person 对象,然后使用 pageContext 对象的 setAttribute 方法将新创建的 person 存储在 PageContext.PAGE_SCOPE 域中。 ~~~ if (person == null){ person = new cn.itcast.domain.Person(); _jspx_page_context.setAttribute("person", person, javax.servlet.jsp.PageContext.PAGE_SCOPE); } ~~~ 也就是说,在 1.jsp 中使用 ~~~ <jsp:useBean id="person" class="cn.domain.Person" scope="page" /> ~~~ 来实例化 person 对象的过程实际上是执行了上述的 java 代码来实例化 Person 对象。这就是`<jsp:useBean>`标签的执行原理:” 首先在指定的域范围内查找指定名称的 JavaBean 对象,如果存在则直接返回该 JavaBean 对象的引用,如果不存在则实例化一个新的 JavaBean 对象并将它以指定的名称存储到指定的域范围中。 注意:`<jsp:useBean>`标签的标签体只在`<jsp:useBean>`标签实例化 bean 时才执行。 如以下 1.jsp 代码: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:userbean标签的使用</title> </head> <body> <!-- userbean标签的标签体只在userbean标签实例化bean时才执行 --> <jsp:useBean id="person" class="cn.domain.Person" scope="page"> bbbbbb </jsp:useBean> <br/> <%=person.getName() %> </body> </html> ~~~ 运行结果如下: ![](https://box.kancloud.cn/9a4a6d8072d5f5272c53e732761197c5_351x145.png) 若将以上 1.jsp 代码修改为: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:userbean标签的使用</title> </head> <body> <!-- userbean标签的标签体只在userbean标签实例化bean时才执行 --> <jsp:useBean id="person" class="cn.domain.Person" scope="session"> bbbbbb </jsp:useBean> <br/> <%=person.getName() %> </body> </html> ~~~ 第一次运行结果仍不变,但第二次运行时结果如下图 ![](https://box.kancloud.cn/690ba333c5d6dd1917d3bfe98ea971a0_211x140.png) 原因是:第一次运行时,JavaBean 对象不存在则实例化一个新的 JavaBean 对象并将它以指定的名称存储到指定的域范围 session 中;第二次运行时,在指定的域范围 session 内就已经查找到指定名称的 JavaBean 对象,所以不会再创建一个新的 JavaBean 对象,即`<jsp:useBean>`标签的标签体只在`<jsp:useBean>`标签实例化 bean 时才执行。 带标签体的`<jsp:useBean>`标签 语法: ~~~ <jsp:useBean ...> Body </jsp:useBean> ~~~ 功能:Body 部分的内容只在`<jsp:useBean>`标签创建 JavaBean 的实例对象时才执行。以上例子已证明过 ## `<jsp:setProperty>`标签 `<jsp:setProperty>`标签用于设置和访问 JavaBean 对象的属性。 语法格式一: ~~~ <jsp:setProperty name="beanName" property="propertyName" value="string字符串"/> ~~~ 语法格式二: ~~~ <jsp:setProperty name="beanName" property="propertyName" value="<%= expression %>" /> ~~~ 语法格式三: ~~~ <jsp:setProperty name="beanName" property="propertyName" param="parameterName"/> ~~~ 语法格式四: ~~~ <jsp:setProperty name="beanName" property= "*" /> ~~~ * name 属性用于指定 JavaBean 对象的名称。 * property 属性用于指定 JavaBean 实例对象的属性名。 * value 属性用于指定 JavaBean 对象的某个属性的值,value 的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为 JavaBean 属性相应的类型,如果 value 的值是一个表达式,那么该表达式的计算结果必须与所要设置的 JavaBean 属性的类型一致。 * param 属性用于将 JavaBean 实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的 JavaBean 属性的类型。 `<jsp:setProperty>`标签使用范例 1:使用 jsp:setProperty 标签设置 person 对象的属性值——手工为 bean 属性赋值 。 ~~~ <%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:setProperty标签使用范例</title> </head> <body> <jsp:useBean id="person" class="cn.domain.Person" /> <%-- 使用jsp:setProperty标签设置person对象的属性值 jsp:setProperty在设置对象的属性值时会自动把字符串转换成8种基本数据类型 但是jsp:setProperty对于复合数据类型无法自动转换 --%> <jsp:setProperty property="name" name="person" value="x"/> <jsp:setProperty property="age" name="person" value="23"/> <%-- birthday属性是一个Date类型,这个属于复合数据类型,因此无法将字符串自动转换成Date ,用下面这种写法是会报错的 <jsp:setProperty property="birthday" name="person" value="1980-09-12"/> --%> <jsp:setProperty property="birthday" name="person" value="<%=new Date() %>"/> <%--使用getXxx()方法获取对象的属性值 --%> <h2>姓名:<%=person.getName() %></h2> <h2>年龄:<%=person.getAge() %></h2> <h2>生日:<%=person.getBirthday() %></h2> </body> </html> ~~~ `<jsp:setProperty`>标签使用范例 2:使用请求参数为 bean 的属性赋值。 ~~~ <%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:setProperty标签使用范例</title> </head> <body> <jsp:useBean id="person" class="cn.domain.Person" /> <%-- jsp:setProperty标签可以使用请求参数为bean的属性赋值 param="name"用于接收参数名为name的参数值,然后将接收到的值赋给name属性 --%> <jsp:setProperty property="name" name="person" param="name"/> <%--使用getXxx()方法获取对象的属性值 --%> <h2>姓名:<%=person.getName() %></h2> </body> </html> ~~~ 又如: ~~~ <%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:setProperty标签使用范例</title> </head> <body> <jsp:useBean id="person" class="cn.domain.Person" /> <%-- jsp:setProperty标签可以使用请求参数为bean的属性赋值 --%> <jsp:setProperty property="name" name="person" param="name"/> <jsp:setProperty property="age" name="person" param="age"/> <%-- 支持8种基本数据类型的转换(把客户机提交的字符串,转成相应的8种基本数据类型,赋到bean的属性上) --%> <%--使用getXxx()方法获取对象的属性值 --%> <h2>姓名:<%=person.getName() %></h2> <h2>年龄:<%=person.getAge() %></h2> </body> </html> ~~~ `<jsp:setProperty>`标签使用范例 3:用所有的请求参数为 bean 的属性赋值。 ~~~ <%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:setProperty标签使用范例</title> </head> <body> <jsp:useBean id="person" class="cn.domain.Person" /> <%-- jsp:setProperty标签用所有的请求参数为bean的属性赋值 property="*"代表bean的所有属性 --%> <jsp:setProperty property="*" name="person"/> <%--使用getXxx()方法获取对象的属性值 --%> <h2>姓名:<%=person.getName() %></h2> <h2>年龄:<%=person.getAge() %></h2> </body> </html> ~~~ 注意:请求参数的名称和 bean 的属性名称一定要一致,内部用的是反射技术。 ## `<jsp:getProperty>`标签 `<jsp:getProperty>`标签用于读取 JavaBean 对象的属性,也就是调用 JavaBean 对象的 getter 方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中。 语法: ~~~ <jsp:getProperty name="beanInstanceName" property="PropertyName" /> ~~~ * name 属性用于指定 JavaBean 实例对象的名称,其值应与<jsp:useBean>标签的 id 属性值相同。 * property 属性用于指定 JavaBean 实例对象的属性名。 如果一个 JavaBean 实例对象的某个属性的值为 null,那么,使用`<jsp:getProperty>`标签输出该属性的结果将是一个内容为 “null” 的字符串。 ~~~ <%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>jsp:setProperty标签使用范例</title> </head> <body> <jsp:useBean id="person" class="cn.domain.Person" /> <%-- 使用jsp:setProperty标签设置person对象的属性值 jsp:setProperty在设置对象的属性值时会自动把字符串转换成8种基本数据类型 但是jsp:setProperty对于复合数据类型无法自动转换 --%> <jsp:setProperty property="name" name="person" value="李阿昀"/> <jsp:setProperty property="age" name="person" value="23"/> <%-- birthday属性是一个Date类型,这个属于复合数据类型,因此无法将字符串自动转换成Date ,用下面这种写法是会报错的 <jsp:setProperty property="birthday" name="person" value="1980-09-12"/> --%> <jsp:setProperty property="birthday" name="person" value="<%=new Date() %>"/> <%--使用jsp:getProperty标签获取对象的属性值 --%> <h2>姓名:<jsp:getProperty property="name" name="person"/></h2> <h2>年龄:<jsp:getProperty property="age" name="person"/></h2> <h2>生日:<jsp:getProperty property="birthday" name="person"/></h2> </body> </html> ~~~