notys's blog
大道至简
Jsp中使用JavaBean

JavaBean 的导入

1.通过page指令导入

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaBean</title>
</head>
<!-- 使用page指令将userbean导入showbean.jsp页面 -->
  	<%@ page import = "xyz.zzjava.bean.userbean" %>
<body>
	<% 
	userbean ub = new userbean();
	 	ub.setName("Amy");
		ub.setPassword("123"); 
	%> 	
	用户名: <%=ub.getName() %></br>
	密码: <%=ub.getPassword() %></br> 
</body>
</html>

2.通过jsp的标签指令导入

使用标签指令指令将userbean导入showbean.jsp页面 .格式:<jsp:useBean id="xxx" class="xxx" scop="xx"/>称为jsp动作,在jsp页面中调用JavaBean有3个标准动作标签:jsp:useBeanjsp:setPropertyjsp:getProperty

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaBean</title>
</head>
<body>
	<jsp:useBean id="ub" class="xyz.zzjava.bean.userbean" scope="page"/>
	<% 
		ub.setName("Bob");
		ub.setPassword("456");
		%>
	用户名: <%=ub.getName() %></br>
	密码: <%=ub.getPassword() %></br>
</body>
</html>

jsp:useBean动作

jsp:useBean动作的目的是实例化一个JavaBean类
语法:

<jsp:useBean id="name" scope="page" class="package.class"/>或<jsp:useBean id="name" scope="page|request|session|application" typeSpec>body</jsp:useBean>

  • id是用户定义的该实例在指定范围中的名称,表示一个JavaBean对象实例。

  • scope参数用于指明该JavaBean起作用的范围,限定Bean的有效范围,有page、request、session、application,默认是page,即Bean在当前页面有效。

  • class参数用于指定需要实例化的类,指定Bean所在的包名和类名。

  • type属性的值必须和类名或父类名、或类所实现的接口相匹配,值由id属性设置。

  • beanName 给bean设定名称,据此来实例化相应的Bean
    定义一个JavaBean的实例之后,jsp通过id来识别这个JavaBean,通过id.method语句来操作JavaBean

在执行的过程中,jsp:useBean首先寻找是否有已经存在的具有相同id和scope值的JavaBean实例,如果没有就会自动创建一个新的实例。
其中,typeSpec定义如下:

typeSpec ::=class="className"|class="className" type="typeName"|type="typeName" class="className"|beanName="beanName" type="typeName"|type="typeName" beanName="beanName"|type="typeName"

jsp:setProperty动作

引入javabean以后为javabean中的属性赋值。javaServer Pages中调用的语法如下:

<jsp:setProperty name="beanName"last_syntax />

name 属性代表已经存在并且具有一定生存范围(scope)的JavaBean实例,name是必须的,表示通过jsp:useBean标签定义的JavaBean对象实例,该值指定的参数为jsp:useBean中的id参数,且jsp:useBean必须出现在jsp:setProperty之前。

last_syntax 表示属性的指定:

property="*"|property="propertyName"|property="propertyName" param="parameterName"|property="propertyName" value="propertyValue"

param 可选的,他指定用哪个请求参数作为Bean属性的值。

value 可选的,设定了属性的值。该属性具有数据类型自动转换的功能 字符串->数值、布尔、字节等类型。不能同时设定value和param属性。

property 必须的,表示设置值的属性property名字。如果使用property="*",程序就会查找当前的ServerRequest所有参数,匹配JavaBean中相同名字的属性property,并通过JavaBean中属性的set方法赋值value给这个属性。

使用jsp:setProperty可以设定Bean中各个参数的值,及调用Bean中的set方法。
实现该功能两种方式:

jsp:useBean的后面使用jsp:setProperty:

<jsp:useBean id="myName" .../>
...
<jsp:setProperty name="beanInstanceName"{
	property="*"|property="propertyName" [param="parameterName"]|property="propertyName" value="{string | <%= expression %>}"
}/>

在这种情况下,jsp:setProperty无论该页面中使用的Bean是否初次被实例化,都会执行该语句。

将该动作放在jsp:setProperty内部进行执行:

<jsp:useBean id="myName" ...>
...
<jsp:setProperty name="beanInstanceName"{
	property="*" | property="propertyName" [param="parameterName"]|property="propertyName" value="{string | <%= expression %>}"
}/>
</jsp:useBean>

在这种情况下,只有在Bean首次被实例化的情况下,才会执行设置属性的方法。如果使用的是已有的JavaBean实例,则不会执行该方法。

利用Property属性设置JavaBean属性有4种方式。

方式一:通过自省的方式来设置属性,最常用。语法:

<jsp:setProperty name="beanName" property="*">

name 属性就是找到JavaBean中定义的id信息

property="*" 所有属性都在这里根据参数的名称自动进行设置。注意参数名称和属性名称一致(表单的参数和JavaBean的属性名称要一致)。类似于对于JavaBean实例化后的对象tt设置属性值,执行tt.setXXX()方法。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="newname" class="xyz.zzjava.bean.UserInfo" scope="page" />
<!-- 通过自省的方式来设置JavaBean属性,并显示出来。 -->
<jsp:setProperty name="newname" property="*" />
	获取的用户名:<jsp:getProperty property="username" name="newname"/><br/>
	获取的邮箱:<jsp:getProperty property="email" name="newname" /><br/>
	获取的手机号:<jsp:getProperty property="mobile" name="newname" /><br/>
	
</body>
</html>

方式二:指定一个属性进行设置

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="newname" class="xyz.zzjava.bean.UserInfo" scope="page" />
<!--指定一个属性进行设置,并显示出来。 -->
<jsp:setProperty name="newname" property="username" />
	获取的用户名:<jsp:getProperty property="username" name="newname"/><br/>
	获取的邮箱:<jsp:getProperty property="email" name="newname" /><br/>
	获取的手机号:<jsp:getProperty property="mobile" name="newname" /><br/>
	
</body>
</html>

方式三:将指定的参数给指定的属性

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="newname" class="xyz.zzjava.bean.UserInfo" scope="page" />
<!--将指定的参数给指定的属性,并显示出来。 -->
<jsp:setProperty name="newname" property="username" value="email"/>
<jsp:setProperty name="newname" property="email" param="username"/>
<jsp:setProperty name="newname" property="mobile" param="mobile"/>

	获取的用户名:<jsp:getProperty property="username" name="newname"/><br/>
	获取的邮箱:<jsp:getProperty property="email" name="newname" /><br/>
	获取的手机号:<jsp:getProperty property="mobile" name="newname" /><br/>
	
</body>
</html>

方式四:设置指定的值给指定的属性

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 将指定的值给指定的属性 -->
<%
	String namestr="Bob";
%>
<jsp:useBean id="newname" class="xyz.zzjava.bean.UserInfo" scope="page" />
<jsp:setProperty name="newname" property="username" value="<%=namestr%>" />
<jsp:setProperty name="newname" property="email" param="username"/>
<jsp:setProperty name="newname" property="mobile" param="mobile"/>

	获取的用户名:<jsp:getProperty property="username" name="newname"/><br/>
	获取的邮箱:<jsp:getProperty property="email" name="newname" /><br/>
	获取的手机号:<jsp:getProperty property="mobile" name="newname" /><br/>
	
</body>
</html>

jsp:getProperty动作

jsp:getPropertyjsp:setProperty相对应,用于从JavaBean中获取指定的属性值。只需要指定name参数和property参数(这两个参数为必要值),其中name属性指明了通过jsp:useBean引用的Bean的id属性,property属性指定了想要获取的属性名。

jsp:getProperty得到JavaBean实例的属性值,并将他们转换为java.lang.String,放置在隐含的out对象中。
JavaBean的实例必须在jsp:getProperty前面定义。语法如下:

<jsp:getProperty name="name" property="propertyName"/>

name 表示要获得属性值的Bean实例,Bean必须在前面用jsp:useBean标签定义,否则会抛NullPointerException 异常

Property 表示要获得值的property的名字。

JavaBean Scope

JavaBean存在四种有效范围 page、request、session、application
默认是 page 即Bean在当前页面有效(存储PageContext的当前页)。
设为request表明Bean只对当前用户的请求范围内(存储在ServletRequest对象中)有效。
设为session表明Bean在当前HttpSession生命周期的范围内对所有页面均有效。
设为application表明可以设置所有的页面都使用相同的ServletContext。

page范围的JavaBean

page范围的JavaBean存储在pageContext中,所以page范围的bean仅在创建他们的页面中才能访问。
当响应返回到客服端或请求指向另一资源时,对该page范围对象的引用将会被释放,从而无法再被引用。

以计数器为例,说明在不同范围内计数器的有效性及其产生的不同效果,该该计数器用来记录用户单击按钮的次数。

JavaBean

package xyz.zzjava.bean;
/*
 * 网站计数器JavaBean
 */
public class counter {
	
	int count = 0;
	//获取单击次数
	public  int getCount() {
		count++;
		return this.count;
	}
	//设置单击 次数
	public void setCount(int count) {
		this.count = count;
	}
}

pagebean.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<jsp:useBean id="counters" scope="page" class="xyz.zzjava.bean.counter" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PageBean</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="page" class="xyz.zzjava.bean.counter"></jsp:useBean>
		page范围的JavaBean<br>
		第一个页面中提交次数是:<%=cn.getCount() %><br></br>
		
	</body>
</html>

请求指向另一资源,加入转向第2个页面的代码:<jsp:forward page="pagebean2.jsp"></jsp:forward>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<jsp:useBean id="counters" scope="page" class="xyz.zzjava.bean.counter" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PageBean</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="page" class="xyz.zzjava.bean.counter"></jsp:useBean>
		page范围的JavaBean<br>
		第一个页面中提交次数是:<%=cn.getCount() %><br></br>
		<jsp:forward page="pagebean2.jsp"></jsp:forward>
	</body>
</html>

pagebean2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<jsp:useBean id="counters" scope="page" class="xyz.zzjava.bean.counter" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PageBean</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="page" class="xyz.zzjava.bean.counter"></jsp:useBean>
		page范围的JavaBean<br>
		第2个页面中提交次数是:<%=cn.getCount() %><br></br>
	</body>
</html>

将JavaBean的有效范围设为page,当单击提交按钮一次或者刷新一次页面时,原来在内存中的实例就会被释放,新的页面会重新实例化一个JavaBean,这样,页面中显示的记录会一直保持为 1。

request范围的JavaBean

request范围的JavaBean在客户端的一次请求响应过程中均有效。
再一次请求过程中,当一个页面提交以后,响应它的过程可以经过一个或者一系列页面,最后所有页面都处理完返回客户端。因此,只要是在一个请求过程中的页面,都可以共享request。

requestbean.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="request" class="xyz.zzjava.bean.counter"></jsp:useBean>
		request范围的JavaBean<br>
			第一个页面中提交次数是:<%=cn.getCount() %><br>
		<!--使用<jsp:forward>动作实现页面的跳转,跳转前后的两个页面处于同一个请求中-->
		<jsp:forward page="requestbean2.jsp"></jsp:forward>
	</body>
</html>

加入一行转向第2个页面的代码:<jsp:forward page="requestbean2.jsp"></jsp:forward>

requestbean2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="request" class="xyz.zzjava.bean.counter"></jsp:useBean>
		request范围的JavaBean<br>
			第2个页面中提交次数是:<%=cn.getCount() %><br>		
	</body>
</html>

从第1个页面跳转到第2个页面过程中就可以在一个请求过程中实现JavaBean共享。

session范围的JavaBean

session范围的JavaBean表示JavaBean对象被创建后,存在于当前会话中,在同一个会话中,共享一个JavaBean。分配给每个客户的JavaBean不同,但在同一客户打开多个jsp页面,即一次会话期间,用的是同一个JavaBean。
如果在同一客户的不同Jsp页面中,声明了相同id的JavaBean且范围仍为session,更改JavaBean的成员变量值,则其他页面中的id名相同的Bean的成员变量也会被改变。
当客户从服务器请求的所有网页都被关闭是时,与该客户这一次会话对应的JavaBean也会被取消。

sessionbean.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="session" class="xyz.zzjava.bean.counter"></jsp:useBean>
			session范围的JavaBean<br>
		<% session.setMaxInactiveInterval(10); %>
			第1个页面中提交次数是:<%=cn.getCount() %><br>
	</body>
</html>

运行时不断刷新,提交次数每次增加 1。

加入转向第2个页面的代码:<jsp:forward page="sessionbean2.jsp"></jsp:forward>

sessionbean2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="session" class="xyz.zzjava.bean.counter"></jsp:useBean>
			session范围的JavaBean<br>
			第2个页面中提交次数是:<%=cn.getCount() %></br>
	</body>
</html>

运行时第2个页面的次数从2开始,随着每次刷新而增加2。是因为将JavaBean的有效范围设为session,在这次会话过程中所有页面获得的JavaBean是同一个,累加次数被所有页面共享。
但是,等待10秒以后再单击按钮,则会从1开始计数,是因为setMaxInactiveInterval(10)设置了session的有效期为10秒。过了有效期,session范围的JavaBean就会重新在内存中生成实例。

如果新打开一个浏览器访问 sessionbean.jsp ,即使是在10秒有效期内,计数仍会从1开始。因为JavaBean的实例存储在客户端的session里,每个客户端实例创建自己的HttpSession对象,服务器为新打开的浏览器创建新的HttpSession,创建新的JavaBean,所以不能从原来的计数值基础上继续增加。

application范围的JavaBean

application范围内的JavaBean一旦建立,除非服务器重新启动,否则JavaBean实例将一直驻留在服务器内存中。不同浏览器、客户端、时间访问,都将共享此实例中存储的信息。

applicationbean.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>applicationbean</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="application" class="xyz.zzjava.bean.counter"></jsp:useBean>
		application范围的JavaBean<br>
		第1个页面中提交次数是:<%=cn.getCount() %><br>
	</body>
</html>

每次刷新页面,次数加 1。
加入转向第2个页面的代码:<jsp:forward page="applicationbean2.jsp"></jsp:forward>

applicationbean2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>applicationbean2</title>
</head>
	<body>
		<jsp:useBean id="cn" scope="application" class="xyz.zzjava.bean.counter"></jsp:useBean>
		application范围的JavaBean<br>
		第2个页面中提交次数是:<%=cn.getCount() %><br>
	</body>
</html>

第2个页面的次数从2开始,每次刷新增加2。在这次的会话过程中所有页面获得的JavaBean是同一个,累加次数被所有页面共享。即使关闭浏览器,重新打开,甚至在不同客户端访问applicationbean2.jsp 提交次数都会持续增加,这是因为它们使用的JavaBean是同一个,在客户端向服务器请求页面的过程中将会请求已经存在的实例而不是重新创建实例。