目录
Java Bean
Java Bean的基本概念
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。 换句话说,javabean就是一个java的类,只不过这个类你要按上面提到的一些规则来写,比如必须是公共的啊,无参构造啊等等,按这些规则写了之后,这个javabean可以在程序里被方便的重用,使开发效率提高。
最初,JavaBean的目的是为了将可以重复使用的软件代码打包标准。特别是用于帮助厂家开发在综合开发环境(IDE)下使用的java软件部件。这些包括如Grid控件 ,用户可以将该部件拖放到开发环境中。从此,JavaBean就可以扩展为一个java web 应用的标准部件,并且JavaBean部件框架已经扩展为企业版的 Bean(EJB)。
JavaBean 和 Server Bean(通常称为 Enterprise JavaBean (EJB))有一些基本相同之处。它们都是用一组特性创建,以执行其特定任务的对象或组件。它们还有从当前所驻留服务器上的容器获得其它特性的能力。这使得 bean 的行为根据特定任务和所在环境的不同而有所不同。
Java Bean的特性
* 支持反射机制:利用反射机制可以分析出Java Bean是如何运行的。
* 支持事件:事件是一种简单的通讯机制,利用它可以将对应的信息通知给Java Bean。
* 支持属性:可以自定义属性,利用标准标签与JSP界面交互数据。
* 支持持久性:持久性是指可以将Java Bean进行保存,在需要的时候又可以重新载入。
一个规范的Java Bean例子
import java.io.Serializable;
/*
* 基本结构:
* Java Bean 类必须是public 类。
* 提供给JSP页面调用的方法,必须赋予public访问权限。
* Java Bean 类中的属性,提供给JSP页面调用时必须提供public的get和set方法。
* 必须拥有不带参数的构造方法。
*/
public class User implements Serializable{
private String username;
private String password;
private String sex;
private String address;
public User() {
super();
}
public String getUsername(){
return username;
}
public void setUsername(String username) {
this.username=username;
}
public String getPassword(){
return password;
}
public void setPassword(String password) {
this.password=password;
}
public String getSex(){
return sex;
}
public void setSex(String sex) {
this.sex=sex;
}
public String getAddress(){
return address;
}
public void setAddress(String address) {
this.address=address;
}
}
Serializable四问
Serializable是什么?
一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化。
Serializable是java.io包中定义的、用于实现Java类的序列化操作而提供的一个语义级别的接口。
Serializable序列化接口没有任何方法或者字段,只是用于标识可序列化的语义。
实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象。例如,我们可以将序列化对象写入文件后,再次从文件中读取它并反序列化成对象,也就是说,可以使用表示对象及其数据的类型信息和字节在内存中重新创建对象。
什么是序列化?
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
为什么要序列化?
序列化对于面向对象的编程语言来说是非常重要的,因为无论什么编程语言,其底层涉及IO操作的部分还是由操作系统其帮其完成的,而底层IO操作都是以字节流的方式进行的,所以写操作都涉及将编程语言数据类型转换为字节流,而读操作则又涉及将字节流转化为编程语言类型的特定数据类型。
什么情况下需要使用序列化?
当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化。
那为什么还要继承Serializable。那是存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本。
Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。
JSP中使用Bean
- 按照规范定义Bean类,并给出类属性的相应get和set方法
- 在页面中要导入相应的的Bean类
- 在JSP页面中利用<jsp:useBean>标签使用Bean类
<jsp:useBean>标签语法:
<jsp:useBean id="beanInstanceName"
scope="page|request|session|application"
{
class="package.class"|
type="package.class"|
class="package.class" type="package.class"|
beanName="{package.class|<%=expression %>}"
}>
属性值 | 说明 |
id | Bean的变量名,可以在指定的范围中使用该变量名 |
class | Bean的路径名,必须是严格的package.class,不能指定其父类 |
scope | Bean的有效范围,取值有page,request,session,application |
beanName | 实例化的类名称或序列化模板的名称,指定的名称可以为其接口,父类 |
type | 指定父类或者接口的类型 |
设置Bean属性
语法形式
<jsp:setProperty name="beanInstanceName"
{
property="*"|
property="propertyName"[param="parameterName"]|
property="propertyName" value="{string |<%=expression %>}"
}
/>
属性说明
属性 | 说明 |
name | Bean的名字,用来指定被使用的Bean,它的值必须是<jsp:useBean>的id值 |
property | Bean的属性名,将值赋给Bean类属性 |
param | 表单参数名称 |
value | 要设定的属性值 |
直接利用表达式设置Bean的属性
product01.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<jsp:useBean id="product" class="Bean.User" scope="page"/>
<%--注意问题
按照规范定义Bean类,并给出类属性的相应get和set方法
在页面中要导入相应的Bean类
在JSP页面中利用<jsp:useBean>标签使用Bean类
--%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>设置Bean属性</title>
</head>
<body>
<%--id与name要相同 --%>
<jsp:setProperty name="product" property="username" value="zyy"/>
<jsp:setProperty name="product" property="password" value="248207"/>
<jsp:setProperty name="product" property="sex" value="man"/>
<jsp:setProperty name="product" property="address" value="China"/>
姓名:<%=product.getUsername() %><br>
密码:<%=product.getPassword() %><br>
性别:<%=product.getSex() %><br>
地址:<%=product.getAddress() %><br>
</body>
</html>
通过表单参数名设置Bean的属性值
product02.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="product" class="Bean.User" scope="page"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>通过表单参数设置Bean属性值</title>
</head>
<body>
<form action="">
输入姓名:<input name="username"/><br/>
输入密码:<input name="password"/><br/>
输入性别:<input name="sex"/><br/>
输入地址:<input name="address"/><br/>
<input type="submit" value="提交">
</form>
<jsp:setProperty property="*" name="product"/>
<%-- * 表示所有 --%>
<br/>
姓名:<%=product.getUsername() %><br>
密码:<%=product.getPassword() %><br>
性别:<%=product.getSex() %><br>
地址:<%=product.getAddress() %><br>
</body>
</html>
运行结果:
获取Bean属性
getProduct.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<jsp:useBean id="product" class="Bean.User" scope="page"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>获取Bean属性</title>
</head>
<body>
<jsp:setProperty property="username" name="product" value="zyy"/>
<br>姓名
<jsp:getProperty property="username" name="product"/>
<jsp:setProperty property="password" name="product" value="248207"/>
<br>密码
<jsp:getProperty property="password" name="product"/>
<jsp:setProperty property="sex" name="product" value="man"/>
<br>性别
<jsp:getProperty property="sex" name="product"/>
<jsp:setProperty property="address" name="product" value="China"/>
<br>地址
<jsp:getProperty property="address" name="product"/>
</body>
</html>
Bean的作用域
前面讲过 Bean 的作用域有4个,分别是 page、 request、 session 和 application。 Bean 的作用范围是由标签中的 scope 属性指定的,默认是 page 范围,即该 Bean 在当前页有效。设置为 request时,表示该Bean 对当前用户的当前请求有效。设置为 session 时,表示该 Bean 在当前用户的 session范围内有效。设置为 application 时,表示该 Bean 对该系统的所有页面有效。scope 属性决定了在使用<jsp:useBean>标签时是否要重新创建新的对象。如果某个 Bean 在其有效的范围内又出现一个id和scope 都相同的 Bean,那么就可以重用己经被实例化的 Bean, 而不是重新新建。
四个周期的例子
演示Bean的request生命周期
requestScope.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<jsp:useBean id="product" class="Bean.User" scope="request"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试scope为request</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
String username=request.getParameter("username");
String password=request.getParameter("password");
String sex=request.getParameter("sex");
String address=request.getParameter("address");
if(username==""||username==null)username="默认姓名";
if(password==""||password==null)password="默认密码";
if(sex==""||sex==null)sex="默认性别";
if(address==""||address==null)address="默认地址";
product.setUsername(username);
product.setPassword(password);
product.setSex(sex);
product.setAddress(address);
%>
<form action="" method="post">
输入姓名:<input name="username"/><br/>
输入密码:<input name="password"/><br/>
输入性别:<input name="sex"/><br/>
输入地址:<input name="address"/><br/>
<input type="submit" value="提交">
<br/>
对象:<%=product.toString() %><br>
姓名:<%=product.getUsername() %><br>
密码:<%=product.getPassword() %><br>
性别:<%=product.getSex() %><br>
地址:<%=product.getAddress() %><br>
</form>
</body>
</html>
结果:
填入数据,并点击提交后
从中可以看出,每次提交显示出的User类的对象都是不同的
演示Bean的page生命周期
pageScope.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="product2" class="Bean.User" scope="page"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试scope为page</title>
</head>
<body>
<%
product2.setUsername("zyy");
product2.setPassword("248207");
product2.setSex("man");
product2.setAddress("China");
%>
<br>姓名
<jsp:getProperty property="username" name="product2"/>
<br>密码
<jsp:getProperty property="password" name="product2"/>
<br>性别
<jsp:getProperty property="sex" name="product2"/>
<br>地址
<jsp:getProperty property="address" name="product2"/>
<form action="pageScope2.jsp" method="get">
<input type="submit" value="提交"><br/>
</form>
</body>
</html>
pageScope2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="product2" class="Bean.User" scope="page"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>跳转scope为page2</title>
</head>
<body>
对象:<%=product2.toString() %><br>
<br>姓名
<jsp:getProperty property="username" name="product2"/>
<br>密码
<jsp:getProperty property="password" name="product2"/>
<br>性别
<jsp:getProperty property="sex" name="product2"/>
<br>地址
<jsp:getProperty property="address" name="product2"/>
</body>
</html>
结果:
点击提交后
可以看出,Bean类的作用域为同一页面,如果跳转页面后则失效
演示Bean的session生命周期
sessionScope.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="product3" class="Bean.User" scope="session"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试scope为session</title>
</head>
<body>
<%
product3.setUsername("zyy");
product3.setPassword("248207");
product3.setSex("man");
product3.setAddress("China");
%>
对象:<%=product3.toString() %><br>
<br>姓名
<jsp:getProperty property="username" name="product3"/>
<br>密码
<jsp:getProperty property="password" name="product3"/>
<br>性别
<jsp:getProperty property="sex" name="product3"/>
<br>地址
<jsp:getProperty property="address" name="product3"/>
<form action="sessionScope2.jsp" method="get">
<input type="submit" value="提交"><br/>
</form>
</body>
</html>
sessionScope2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="product3" class="Bean.User" scope="session"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>跳转scope为session2</title>
</head>
<body>
对象:<%=product3.toString() %><br>
<br>姓名
<jsp:getProperty property="username" name="product3"/>
<br>密码
<jsp:getProperty property="password" name="product3"/>
<br>性别
<jsp:getProperty property="sex" name="product3"/>
<br>地址
<jsp:getProperty property="address" name="product3"/>
</body>
</html>
结果:
可以看出,引用的Bean为同一对象,所以取得的属性值一样
演示Bean的application生命周期
applicationScope.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="product4" class="Bean.User" scope="application"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试scope</title>
</head>
<body>
姓名
<jsp:getProperty property="username" name="product4"/>
<br>密码
<jsp:getProperty property="password" name="product4"/>
<br>性别
<jsp:getProperty property="sex" name="product4"/>
<br>地址
<jsp:getProperty property="address" name="product4"/>
<%
product4.setUsername("zyy");
product4.setPassword("248207");
product4.setSex("man");
product4.setAddress("China");
%>
<br>
<br>姓名
<jsp:getProperty property="username" name="product4"/>
<br>密码
<jsp:getProperty property="password" name="product4"/>
<br>性别
<jsp:getProperty property="sex" name="product4"/>
<br>地址
<jsp:getProperty property="address" name="product4"/>
</body>
</html>
结果:
刷新页面后
可以看出,在同一范围内的Bean对象,其引用是同一对象
用户登录验证
如果存在用户且登陆成功,就跳转在欢迎界面,否则显示错误信息。
在本程序中Java Bean极为重要,不仅要完成数据的校验,还要进行错误信息的显示。
admin.java
此类中包含基础的用户名,密码属性,并用Map来保存错误信息
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class Admin implements Serializable{
/**
* @author ZHYYang
*/
private static final long serialVersionUID = 1L;
private String name="";
private String password="";
Map<String, String> adminMap=null;
Map<String, String> errorsMap=null;
public Admin() {
super();
this.name="";
this.password="";
adminMap=new HashMap<String, String>();
errorsMap=new HashMap<String, String>();
adminMap.put("zyy", "123");
adminMap.put("wrr", "123");
}
public boolean isValidate() {
boolean flag=true;
if (!this.adminMap.containsKey(this.name)) {
flag=false;
errorsMap.put("name", "该用户不存在");
this.name="";
}
String password=this.adminMap.get(this.name);
if(password==null||!password.equals(this.password)) {
flag=false;
this.password="";
errorsMap.put("password","密码错误,请重新输入密码");
this.name="";
}
return flag;
}
//获取错误信息
public String getErrors(String key) {
String errorV=this.errorsMap.get(key);
return errorV==null?"":errorV;
}
//以下是get和set
public void setName(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setPassword(String password) {
this.password=password;
}
public String getPassword() {
return password;
}
}
login.jsp
在登录页面login.jsp中引用Admin类,并用表单提交的方式设定Admin属性值。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="admin" class="Bean.Admin" scope="session"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<form action="check.jsp" method="post">
姓名:<input name="name" value="<jsp:getProperty property="name" name="admin"/>"/>
<span style="color: red"><%=admin.getErrors("name") %></span>
<br>
密码:<input name="password" value="<jsp:getProperty property="password" name="admin"/>"/>
<span style="color: red"><%=admin.getErrors("password") %></span>
<br>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>
check.jsp
对调用方法进行判断
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="admin" class="Bean.Admin" scope="session"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>验证用户</title>
</head>
<body>
<jsp:setProperty property="*" name="admin"/>
<%
if(admin.isValidate()){
%>
<jsp:forward page="success.jsp"/>
<%
}else{
%>
<jsp:forward page="login.jsp"/>
<%} %>
</body>
</html>
success.jsp
显示登录成功信息
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="admin" class="Bean.Admin" scope="session"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
<span style="color: blue;">欢饮您:
<jsp:getProperty property="name" name="admin"/>用户
</span>
</body>
</html>
结果:
点击login.jsp运行程序
点击提交,会判断账号密码
如果信息错误,提示错误信息
如果信息正确,显示成功画面