一、什么是JavaBean
(1)JavaBean是一个遵循特定写法的java类,它通常具有如下特点:
这个java类必须具有一个无参的构造函数;
属性必须私有化;
私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵守一定的命名规范。
(2)JavaBean在javaEE开发中,通常用于封装数据,对于遵循以上写法的JavaBean组件,其它程序可以通过反射技术实例化JavaBean对象,并且通过反射那些遵守命名规范的方法,从而获知JavaBean的属性,进而调用其属性保存数据。
二、 JavaBean的属性
(1)JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有相应的的setter、getter方法,setter方法称为属性修改器,getter方法称为属性访问器。
(2)属性修改器必须以小写的set前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如,name属性的修改器名称为setName,password属性的修改器名称为setPassword。属性访问器和属性修改器类似。一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。注意:一个字段想要称之为属性,那么必须要有一个get或set方法。
三、在jsp中使用JavaBean
(1)jsp技术提供了三个关于JavaBean组件的动作元素,即jsp标签,它们分别为:
<jsp:useBean>标签:用于在jsp页面中查找或实例化一个JavaBean组件。
<!-- 实例化一个bean -->
<jsp:useBean id="person" class="cn.itcast.Person"
scope="page"></jsp:useBean>
<%
System.out.println(person.getName());
%>
注意:其中scope用于指定域,可以指定request、session、page(pageContext)和application四个域,默认是page,即pageContext域。而JavaBean一般通过request域中带给jsp。
常用语法:
<jsp:useBean id="beanName" class="package.class" scope="page"/>
id属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
class属性用于指定JavaBean的完整类名(必须带包名)。
最终会被翻译到servlet中去。
注意:对于带标签体的<jsp:useBean>标签
<jsp:useBean>
Body
</jsp:useBean>
这种情况下,body部分的内容只在此标签创建JavaBean的实例对象时才执行,创建JavaBean之后则表示JavaBean已存在,则body内容不会显示了。
<jsp:setProperty>标签:用于在jsp页面中设置一个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:setProperty name="person" property="name" value="xxx"/>
<jsp:setProperty name="person" property="age" value="123"/><!-- 自动将字符串
转换成了int -->
注意:可以将八种基本数据类型和字符串相互转换,但是对与复杂类型不能转换。
<jsp:setProperty name="person" property="birthday" value="1990-11-24"/>
<!--不能自动将字符串转换成了Date型 -->
只能这样:
<jsp:setProperty name="person" property="birthday" value="<%=new Date() %>>"/>
使用请求参数:
<!-- 之后再访问的时候:http://localhost:8080/jsp/2.jsp?name=yj -->
<jsp:setProperty name="person" property="name" param="name"/>
用所有的请求参数为bean赋值:
<!--http://localhost:8080/day09/2.jspname=yj&password=123&age=24-->
<jsp:setProperty name="person" property="*"/>
注意:使用*号则参数的顺序必须是一致的。
输出:
<%
System.out.println(person.getName());
System.out.println(person.getPassword());
System.out.println(person.getAge());
%>
<jsp:getProperty>标签:用于在jsp页面中获取一个JavaBean组件的属性。
我们看到上面的输出是使用java代码,这里我们可以使用此标签进行替换:
<jsp:getProperty name=”person” property=”name”/>
<jsp:getProperty name=”person” property=”birthday”/>
注意:上面若输出birthday,但是如果我们没有给出其值,这是会输出一个null的字符串,但是这样的输出是没有意义的,这里我们一般都要求做判断,若为空,则最好不输出,这在后面使用EL表达式可以做到。
四、JSP开发模式
sun公司推出了jsp技术后,同时还推荐了两种web应用程序的开发模式,一种是jsp+JavaBean模式,一种是Servlet+jsp+JavaBean模式。jsp+JavaBean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务逻辑数据,jsp既负责处理用户请求,又显示数据。
Servlet+jsp+JavaBean模式(MVC)模式适合开发复杂的web应用,在这种模式下,Servlet负责处理用户请求,jsp负责数据显示,JavaBean负责封装数据。Servlet+jsp+JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。
先看一个jsp+JavaBean模式的例子:编写计算器
<%@page import="cn.itcast.CalculatorBean"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>计算器</title>
</head>
<body style="text-align:center;">
<jsp:useBean id="CalculatorBean" class="cn.itcast.CalculatorBean"></jsp:useBean>
<jsp:setProperty name="CalculatorBean" property="*"></jsp:setProperty>
<%
CalculatorBean.calculate();
%>
计算结果是:
<jsp:getProperty name="CalculatorBean" property="firstNum"/>
<jsp:getProperty name="CalculatorBean" property="operator"/>
<jsp:getProperty name="CalculatorBean" property="secondNum"/>
=
<jsp:getProperty name="CalculatorBean" property="result"/>
<br/><br/>
<form action="/jsp/3.jsp" method="post">
<table border="1" width="50%">
<tr>
<td colspan="2">一个简单计算器</td>
</tr>
<tr>
<td>第一个参数</td>
<td>
<input type="text" name="firstNum">
</td>
</tr>
<tr>
<td>运算符</td>
<td>
<select name="operator">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
</td>
</tr>
<tr>
<td>第二个参数</td>
<td>
<input type="text" name="secondNum">
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="计算结果">
</td>
</tr>
</table>
</form>
</body>
</html>
package cn.itcast;
import java.math.BigDecimal;
public class CalculatorBean {
private double firstNum ;
private double secondNum ;
//注意:这里必须给默认值,不然在jsp中的CalculatorBean.calculate()会出现异常
private char operator = '+';
private double result ;
public void calculate(){
switch (this.operator) {
case '+':{
this.result = this.firstNum + this.secondNum;
break;
}
case '-':{
this.result = this.firstNum - this.secondNum;
break;
}
case '*':{
this.result = this.firstNum * this.secondNum;
break;
}
case '/':{
if(this.secondNum == 0){
throw new RuntimeException("除数不能为0");
}
this.result = this.firstNum / this.secondNum;
//需要四舍五入,向上进位模式,保留两位小数
this.result = new BigDecimal(this.result).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
break;
}
default:
throw new RuntimeException("对不起,传入的运算符非法");
}
}
public double getFirstNum() {
return firstNum;
}
public void setFirstNum(double firstNum) {
this.firstNum = firstNum;
}
public double getSecondNum() {
return secondNum;
}
public void setSecondNum(double secondNum) {
this.secondNum = secondNum;
}
public char getOperator() {
return operator;
}
public void setOperator(char operator) {
this.operator = operator;
}
public double getResult() {
return result;
}
public void setResult(double result) {
this.result = result;
}
}
五、EL表达式和JSTL标签快速入门
(1)EL表达式用于获取数据,在jsp页面中可使用 ${标识符} 的形式,通知jsp引擎调用 pageContext.findAttribute() 方法,以标识符为关键字从各个域对象中获取对象。如果域对象中不存在标识符所对应的对象,则返回结果为“”(注意:不是null)。
示例:使用EL表达式获取request、session、application域中的数据。
<%
request.setAttribute("name", "aaa");
%>
${name}
(2)EL表达式中也可以使用 ${customerBean.address} 的形式来访问JavaBean对象的属性。
示例:使用EL表达式获取bean属性。
<!-- 使用el表达式取得javaBean中的属性数据 -->
<%
Person p = new Person();
p.setAge(12);
request.setAttribute("person", p);
%>
${person.age}
<!-- 使用el表达式取得bean中的bean的属性 -->
<%
Person person = new Person();
Address address = new Address();
person.setAddress(address);
request.setAttribute("person", person);
%>
${person.address.name}
(3)结合JSTL标签,EL表达式也可以轻松获取各种集合中的元素。
示例:使用EL表达式获取List、Map集合中的元素。但是这里我们只能取得特定位置的属性值,因为若要取得所有的值必须用到迭代,而这就必须配合自定义标签,这在后面讲。
<!-- 使用el表达式获取list集合的数据的属性 ,因为有时候我们会将多个数据封装在bean中,而我们一般将多个数据存放在一个list中传给servlet,那么我们就需要从list中取数据-->
<%
Person p1 = new Person();
p1.setName("aaa");
Person p2 = new Person();
p2.setName("bbb");
List list = new ArrayList();
list.add(p1);
list.add(p2);
request.setAttribute("list", list);
%>
<!-- 取得第一个位置上的属性数据,即特定位置上的属性数据 -->
${list[0].name}
<!-- 取map中的数据 -->
<%
Map map = new HashMap();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c", "ccc");
request.setAttribute("map", map);
%>
${map.a }根据关键字a取得相关数据。
注意:如果我们使用数字作为关键字:
map.put("1", "ccc");如果这样取${map.1}是不行的,应该这样取:${map[“1”]}
(4)EL表达式也可使用类如${1==1}的形式进行简单的逻辑判断
(5)使用EL表达式取得web应用的路径
<a href="/day09/1.jsp">按钮</a>
这种超链接在网页里经常见到,但是我们在部署的时候经常需要改动web应用的名字,这样的话如果在这里将路径名字写死就不便于管理。
${pageContext.request.contextPath} 这里就可以取得web应用的名字、路径。在pageContext中有一个方法getRequest方法表明有个request属性,而request中有个方法getContextPath方法表示里面有个contextPath的属性。这里就可以取得/day09,那么以后的超链接就可以这样写:
<a href=” ${pageContext.request.contextPath}/1.jsp”>按钮</a>
(6)JSTL标签库
JSTL是sun公司开发的一套标准库,使用JSTL可以在页面中实现了一些简单的逻辑,从而替代页面中的脚本代码。
在页面中使用JSTL标签需要完成以下两个步骤:
1.导入jstl.jar和standard.jar这两个JSTL的包文件;
2.在JSP页面中使用<%@ taglib uri="..." prefix="..."%>元素导入标签库。
注意:在MyEclipse中已经继承了这两个包了。我们只需要导入地址即可。
如果不是使用MyEclipse的话需要手动导入包,在包standard中的c.tld文件中可以找到uri地址:http://java.sun.com/jsp/jstl/core, 这样prefix的值最好就写成这个文件的名字“c”。如果没有写这一行,会发现不报错,但是也不会显示任何内容。同时导入包文件之后需要重新部署。下面我们看如何迭代出上面例子中list和map集合中的内容:
对于存在list集合中的内容:
<c:forEach var="person" items="${list}">
${person.name}<br/>
</c:forEach>
对于存在map集合中的内容:
<c:forEach var="me" items="${map}">
${me.key} = ${me.value}<br/>
</c:forEach>
注意:注意其格式语法。同时在迭代map集合中的内容时,其实不是直接迭代的,而是执行了Set set=map.entrySet()中的set集合。
对于<c:if test>语句:
这种语句一般用在登录界面中
<c:if test="${user!=null}">
欢迎您:${user.username}
</c:if>
<c:if test="${user==null }">
用户名:<input type="text" name="username">
密 码:<input type="password" name="password">
<input type="submit" value="登录">
</c:if>
使用test执行判断语句。
注意:我们在使用EL表达式取得某个属性时,如果这个属性本身不存在,则会出现Property ‘username’ not found...的异常。