JavaBean介绍
JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
- 这个Java类必须具有一个无参的构造函数
- 字段必须私有化。
- 私有化的字段必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
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>标签用于在指定的域范围内查找指定名称的JavaBean对象:
如果存在则直接返回该JavaBean对象的引用。
如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。
常用语法:
<jsp:useBean id="beanName" class="package.class"
scope="page|request|session|application"/>
<jsp:useBean>执行原理
我们可以看看 <jsp:useBean id="p" class="java.util.Date"/> 这个脚本翻译成的Servlet源码:
java.util.Date p = null;
p = (java.util.Date) _jspx_page_context.getAttribute("p", javax.servlet.jsp.PageContext.PAGE_SCOPE);
if (p == null){
p = new java.util.Date();
_jspx_page_context.setAttribute("p", p, javax.servlet.jsp.PageContext.PAGE_SCOPE);
}
<jsp:useBean id="p" class="java.util.Date"/>脚本执行原理就是通过pageContext对象从相应的域范围内查找对象,如果没有找到的话直接new一个新对象,并放置到指定的域范围中。
<jsp:setProperty>标签
<jsp:setProperty>标签用于设置和访问JavaBean对象的属性。
语法格式(演示)
<jsp:setProperty name="beanName"
{
property="propertyName" value="{string | <%= expression %>}" |
property="propertyName" [ param="parameterName" ] |
property= "*"
}/>
- name属性用于指定JavaBean对象的名称。
- property属性用于指定JavaBean实例对象的属性名。
- value属性用于指定JavaBean对象的某个属性的值,value的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。
- param属性用于将JavaBean实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的JavaBean属性的类型。
<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”的字符串。
EL表达式
EL 全名为Expression Language。EL主要作用:
获取数据(替换掉JSP中的Java表达式<%=%>):
EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)
执行运算:
利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}
获取web开发常用对象
EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
调用Java方法
EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
1、获取数据
使用EL表达式获取数据语法:“${标识符}”
EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。
EL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
${user.address.city}
${user.list[0]}:访问有序集合某个位置的元素
${map.key} : 获得map集合中指定key的值
结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,后面JSTL会介绍。
2、执行运算
语法:${运算表达式},EL表达式支持如下运算符:
empty运算符:检查对象是否为null或“空”,很好用!!!
三元表达式:${user!=null?user.name : “”} ,很好用!!!
[ ] 和 . 号运算符
3、获得web开发常用对象
EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
语法:${隐式对象名称} :获得对象的引用
隐含对象名称 | 描 述 |
pageContext | 对应于JSP页面中的pageContext对象(注意:取的是pageContext对象。) |
pageScope | 代表page域中用于保存属性的Map对象 |
requestScope | 代表request域中用于保存属性的Map对象 |
sessionScope | 代表session域中用于保存属性的Map对象 |
applicationScope | 代表application域中用于保存属性的Map对象 |
param | 表示一个保存了所有请求参数的Map对象 |
paramValues | 表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[] |
header | 表示一个保存了所有http请求头字段的Map对象 |
headerValues | 同上,返回string[]数组。注意:如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”] |
cookie | 表示一个保存了所有cookie的Map对象 |
initParam | 表示一个保存了所有web应用初始化参数的map对象 |
EL表达式自定义函数
EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。
示例:${prefix:method(params)}
- 在EL表达式中调用的只能是Java类的静态方法。
- 这个Java类的静态方法需要在TLD(Tagliary Definition)文件中描述,才可以被EL表达式调用。
- EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。
一般来说, EL自定义函数开发与应用包括以下三个步骤:
- 编写一个Java类的静态方法
- 编写标签库描述符(tld)文件,在tld文件中描述自定义函数。
- 在JSP页面中导入和使用自定义函数。
JSTL标签库
JSTL是sun公司开发的一套标签库,使用JSTL可以在页面中实现一些简单的逻辑,从而替换页面中的脚本代码。
由于JSTL是在JSP 1.2规范中定义的,所以JSTL需要运行在支持JSP 1.2及其更高版本的WEB容器上,例如,Tomcat 5.5。
它包括:
- 核心标签库
- 国际化标签
- 数据库标签
- XML标签
- JSTL函数(EL函数)
JSTL建议前缀如下表所示:
标签库功能描述 | 标签库的URI | 建议前缀 |
核心标签库 | http://java.sun.com/jsp/jstl/core | c |
XML标签库 | http://java.sun.com/jsp/jstl/xml | x |
国际化/格式化标签库 | fmt | |
数据库标签库 | sql | |
EL自定义函数 | http://java.sun.com/jsp/jstl/functions | fn |
下面对JSTL的各个标签库进行简单的介绍:
(1)核心标签库中包含了实现WEB应用中的通用操作的标签。例如,用于输出一个变量内容的<c:out>标签、用于条件判断的<c:if>标签、用于迭代循环的<c:forEach>标签。
(2)国际化/格式化标签库中包含实现WEB应用程序的国际化的标签。例如,设置JSP页面的本地信息、设置JSP页面的时区、绑定资源文件,使本地敏感的数据(例如数值、日期等)按照JSP页面中设置的本地格式显示。
(3)数据库标签库中包含用于访问数据库和对数据库中的数据进行操作的标签。例如,从数据源中获得数据库连接、从数据库表中检索数据等。由于在软件分层的开发模型中,JSP页面仅用作表现层,我们一般不在JSP页面中直接操作数据库,而是在业务逻辑层或数据访问层操作数据库,所以,JSTL中提供的这套数据库标签库没有多大的实用价值。
(4)XML标签库中包含对XML文档中的数据进行操作的标签。例如,解析XML文档、输出XML文档中的内容,以及迭代处理XML文档中的元素。因为XML广泛应用于WEB开发,对XML文档的处理非常重要,XML标签库使处理XML文档变得简单方便,这也是JSTL的一个重要特征。
(5)JSTL中提供的一套EL自定义函数包含了JSP页面制作者经常要用到的字符串操作。例如,提取字符串中的子字符串、获取字符串的长度和处理字符串中的空格等。
下载&使用
在使用JSTL之前需要下载JSTL的jar包。可以进入Apache的网站首页,然后根据相关的提示下载所需的文件。从http://jakarta.apache.org/taglibs/ 下载的压缩文件中只包含jstl.jar和standard.jar两个 jar 包,而 xalan.jar包要从 http://xml.apache.org/xalan-j/downloads.html 下载。然后将这些jar包拷贝到工程的libs目录下。
要在JSP文件中使用JSTL,首先就需要使用taglib指令导入所需要使用的JSTL标签库,taglib指令的uri属性必须为相应标签库的TLD文件中的<uri>元素的值,taglib指令的prefix属性可以自己随意指定,但最好是采用表8.1中的建议前缀。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
注意:结尾为jstl/core的uri有3个,千万不要选错了。
<c:out>标签
<c:out> 标签用于输出一段文本内容到pageContext对象当前保存的“out”对象中。
属性名 | 是否支持EL | 属性类型 | 属 性 描 述 |
Value | true | Object | 指定要输出的内容 |
escapeXml | true | Boolean | 指定是否将>、<、&、'、" 等特殊字符进行HTML编码转换后再进行输出。默认值为true |
default | true | Object | 指定如果value属性的值为null时所输出的默认值 |
<c:set>标签
<c:set>标签用于把某一个对象存在指定的域范围内,或者设置Web域中的java.util.Map类型的属性对象或JavaBean类型的属性对象的属性。
属性名 | 是否支持EL | 属性类型 | 属 性 描 述 |
value | true | Object | 用于指定属性值 |
var | false | String | 用于指定要设置的Web域属性的名称 |
scope | false | String | 用于指定属性所在的Web域 |
target | true | Object | 用于指定要设置属性的对象,这个对象必须是JavaBean对象或java.util.Map对象 |
property | true | string | 用于指定当前要为对象设置的属性名称 |
<c:remove>标签
<c:remove>标签用于删除各种Web域中的属性。
其语法格式如下:
<c:remove var="varName"
[scope="{page|request|session|application}"] />
<c:catch>标签
<c:catch>标签用于捕获嵌套在标签体中的内容抛出的异常,其语法格式如下:<c:catch [var="varName"]>nested actions</c:catch>
var属性用于标识<c:catch>标签捕获的异常对象,它将保存在page这个Web域中。
示例代码如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:catch var="myex“ scope=“page”>
<%
10/0;
%>
</c:catch>
异常:<c:out value="${myex}" /><br />
异常 myex.getMessage:<c:out value="${myex.message}" /><br />
异常 myex.getCause:<c:out value="${myex.cause}" /><br />
异常 myex.getStackTrace:<c:out value="${myex.stackTrace}" />
<c:if>标签
<c:if test=“”>标签可以构造简单的“if-then”结构的条件表达式
属性名 | 是否支持EL | 属性类型 | 属 性 描 述 |
test | true | boolean | 决定是否处理标签体中的内容的条件表达式 |
var | false | String | 用于指定将test属性的执行结果保存到某个Web域中的某个属性的名称 |
scope | false | String | 指定将test属性的执行结果保存到哪个Web域中 |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>JSTL标签</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>
<%
pageContext.setAttribute("user", "fuck");
session.setAttribute("user", "abc");
%>
<c:if test="${user==null}">未登陆</c:if>
<c:if test="${user!=null}">登陆</c:if>
<c:if test="${sessionScope.user==null}">未登陆</c:if>
<c:if test="${sessionScope.user!=null}">登陆</c:if>
<!-- 将结果result存放到page域中 -->
<c:if test="${abc==null}" var="result" scope="page">
</c:if>
${result }
</body>
</html>
<c:choose>标签
<c:choose>标签用于指定多个条件选择的组合边界,它必须与<c:when>和<c:otherwise>标签一起使用。使用<c:choose>,<c:when>和<c:otherwise>三个标签,可以构造类似 “if-else if-else” 的复杂条件判断结构。
示例代码如下:
<!-- 功能类似 if-else -->
<c:choose>
<c:when test="${user!=null }">
登陆
</c:when>
<c:otherwise>
请登陆
</c:otherwise>
</c:choose>
<c:forEach>标签
<c:forEach>标签用于对一个集合对象中的元素进行循环迭代操作,或者按指定的次数重复迭代执行标签体中的内容。
属性名 | 是否支持EL | 属性类型 | 属 性 描 述 |
var | false | String | 指定将当前迭代到的元素保存到page这个Web域中的属性名称 |
items | true | 任何支持的类型 | 将要迭代的集合对象 |
begin | true | int | 如果指定items属性,就从集合中的第begin个元素开始进行迭代,begin的索引值从0开始编号;如果没有指定items属性,就从begin指定的值开始迭代,直到end值时结束迭代 |
end | true | int | 参看begin属性的描述 |
step | true | int | 指定迭代的步长,即迭代因子的迭代增量 |
示例代码如下:
<%@page import="com.fxsky.servlet.entity.Person"%>
<%@page import="java.lang.reflect.Array"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>JSTL标签</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>
<%
String[] s = {"aaa","bbb","ccc","ddd"};
//一定要存放到域对象中
pageContext.setAttribute("s", s);
%>
<c:forEach items="${s }" var="element">
${element }<br>
</c:forEach>
<hr>
<%
List<String> list = new ArrayList<String>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
pageContext.setAttribute("list", list);
%>
<c:forEach items="${list }" var="item">
${item }<br>
</c:forEach>
<hr>
<%
Map<String,Person> map = new HashMap<String,Person>();
map.put("p1", new Person("p1","zhangsan"));
map.put("p2", new Person("p2","lisi"));
map.put("p3", new Person("p3","wangwu"));
map.put("p4", new Person("p4","zhaoliu"));
pageContext.setAttribute("map",map);
%>
<!-- var代表的是Map.Entry -->
<c:forEach items="${map }" var="me">
${me.key }=${me.value.name }<br>
</c:forEach>
<hr>
<!-- 分页显示 -->
<c:forEach begin="1" end="10" var="index" step="2">
${index }<br>
</c:forEach>
<hr>
<!-- 遍历数组中的某些元素 -->
<c:forEach items="${s }" begin="1" step="2" var="element" >
${element }<br>
</c:forEach>
</body>
</html>
下面通过varStatus来实现表格隔行换色功能,示例代码如下:
<%@page import="com.fxsky.servlet.entity.Person"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP '10.jsp' starting page</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>
<%
List<Person> list = new ArrayList<Person>();
list.add(new Person("ID00001","zhangsan"));
list.add(new Person("ID00002","lisi"));
list.add(new Person("ID00003","wangwu"));
list.add(new Person("ID00004","zhaoliu"));
list.add(new Person("ID00005","wangmazi"));
list.add(new Person("ID00006","qianqi"));
list.add(new Person("ID00007","jack"));
list.add(new Person("ID00008","kobe"));
list.add(new Person("ID00009","james"));
pageContext.setAttribute("list", list);
%>
<table border="1" width="30%">
<tr>
<th>序号</th>
<th>ID</th>
<th>姓名</th>
<th>第一条</th>
<th>最后一条</th>
</tr>
<c:forEach items="${list }" var="p" varStatus="status">
<tr bgcolor="${status.count%2==0?'#ff0000':'#868686' }">
<td>${status.count }</td>
<td>${p.id }</td>
<td>${p.name }</td>
<td>${status.first }</td>
<td>${status.last }</td>
</tr>
</c:forEach>
</table>
</body>
</html>