Java Web之JSP使用Java Bean

Java Web之JSP使用Java Bean
write:2022-4-21

前文我们学习了java的会话:Java Web之Session,这节课我们学习java bean,如果在java文件中嵌入大量的java程序片段,会降低jsp的可读性并使jsp的调试跟踪维护变得复杂,因此需要将这些java片段放在java bean中,只需在jsp中通过标签访问这些java bean即可。

文章目录

  • 1.了解JavaBean的概念
  • 2. Java Bean的特征(规范)
  • 3. 掌握JSP访问JavaBean的语法
    • 3.1 导入JavaBean类
    • 3.2 声明JavaBean对象
    • 3.3 读取以及设置JavaBean属性
  • 4. 理解JavaBean的四种范围
    • 4.1 JavaBean在page范围内
    • 4.2 JavaBean在request范围内
    • 4.3 JavaBean在session范围内
    • 4.4 JavaBean在application范围内
  • 5. JSP与JavaBean搭配使用的优点
  • 6. 练习题

1.了解JavaBean的概念

1)JavaBean是一种可重复使用、且跨平台的软件组件。
2)JavaBean可分为两种:
一种是有用户界面(UI,User Interface)的JavaBean;
还有一种是没有用户界面,主要负责表示业务数据或者处理事务(如数据运算,操纵数据库)的JavaBean。
3)JSP通常访问的是后一种JavaBean。

2. Java Bean的特征(规范)

一个标准的JavaBean有以下几个特性:
JavaBean是一个公共的(public)类
JavaBean有一个不带参数的构造方法
JavaBean通过setXXX方法设置属性,通过getXXX方法获取属性。如果属性名为“xyz”,那么get方法名为“getXyz”,set方法名为“setXyz”,属性名中的第一个字母在方法名中改为大写。

为什么要有上述的规范:因为Java Bean的出现就是为了使它能够像标准零件一样具有广泛的通用性,都遵守一样得规范,才能被jsp页面以同样的方式访问。

eg:

package mypack;
public class CounterBean{
	private int count=0;   //定义count属性
	public CounterBean(){}   //不带参数的构造方法
	public int getCount(){   //读取count属性
		return count;
    }
	public void setCount(int count){   //设置count属性
		this.count=count;
    }
}

假定把CounterBean类发布到helloapp应用中,它的存放位置是:
helloapp/WEB-INF/classes/mypack/CounterBean.class

3. 掌握JSP访问JavaBean的语法

Java Web之JSP使用Java Bean_第1张图片

3.1 导入JavaBean类

通过<%@ page import>指令导入JavaBean类,例如: <%@ pageimport=“mypack.CounterBean” %>
(注意:名字必须完整,因此包名也必须包含进来)

3.2 声明JavaBean对象

jsp:useBean标签用来声明JavaBean对象,例如:

id:为所声明的Java Bean对象所提供的唯一的标识符(也就是存放范围内的属性名);scope:Java Bean存在的范围(有四个可选值:page(默认值),request,session,application)

以上jsp:useBean标签和以下Java程序片段的作用是等价的:

<%
mypack.CounterBean myBean = null; //定义myBean局部变量
//试图从会话范围内读取myBean属性 
myBean = (mypack.CounterBean) session.getAttribute("myBean");
if (myBean == null){ //如果会话范围内不存在myBean属性
  myBean = new mypack.CounterBean();
  session.setAttribute("myBean", myBean);
} %>

显然使用jsp:useBean标签代码更简洁。

3.3 读取以及设置JavaBean属性

  1. 访问Java Bean属性
    JSP提供了访问JavaBean属性的标签,如果要将JavaBean的某个属性输出到网页上,可以用jsp:getProperty标签,例如:

    name:待访问的Java Bean的名字(与前面jsp:useBean标签的id对应);property:待访问的Java Bean的属性名
  2. 属性赋值
    如果要给JavaBean的某个属性赋值,可以用jsp:setProperty标签,例如:

    这个标签是把名为myBean的Java Bean的count属性赋值为0.

4. 理解JavaBean的四种范围

中的scope属性,scope属性决定了JavaBean对象存在的范围。scope的可选值包括:
page(默认值)页面范围
request 请求范围
session 会话范围
application 应用范围

同一个Java Bean可以被多个web组件访问,但因被访问的范围不同有不同的生命周期。

4.1 JavaBean在page范围内

客户每次请求访问JSP页面时,都会创建一个JavaBean对象。JavaBean对象的有效范围是客户请求访问的当前JSP网页。
Java Web之JSP使用Java Bean_第2张图片
JavaBean对象在以下两种情况下都会结束生命期:
客户请求访问的当前JSP网页通过jsp:forward标记将请求转发到另一个文件
客户请求访问的当前JSP页面执行完毕并向客户端发回响应。

eg:
pageCounter.jsp

<%@ page import="mypack.CounterBean" %>
<html><head><title>Counter</title></head><body>

<jsp:useBean id="myPageBean" scope="page"class="mypack.CounterBean" />

<%-- 把myPageBean的count属性的值加1 --%>
<jsp:setProperty name="myPageBean" property="count"
	value="<%=myPageBean.getCount()+1 %>" />

<%-- 打印myPageBean的count属性 --%>
Current count value is :<jsp:getProperty name="myPageBean" property="count" />
<%
String scopeNames[]={"No scope","page","request","session","application"};
//寻找myPageBean的范围
int scope=pageContext.getAttributesScope("myPageBean");   //getAttributesScope()方法获得某个Java Bean的范围
%>
<%--打印myPageBean的范围 --%>
<p>scope=<%=scopeNames[scope]%></p>

</body></html>

运行:
(1)通过浏览器第一次访问
http://localhost:8080/helloapp/pageCounter.jsp,将会看到网页上的内容如下:
Current count value is :1
scope=page
(2)通过浏览器多次访问pageCounter.jsp,会看到CounterBean对象的count属性的值始终为1。(因为每次访问jsp:useBean标签都创建一个新的CounterBean对象,count属性初始值为0)

4.2 JavaBean在request范围内

  1. 客户每次请求访问JSP页面时,都会创建新的JavaBean对象。

  2. JavaBean对象的有效范围为:
    客户请求访问的当前JSP网页;
    和当前JSP网页共享同一个客户请求的网页,即当前JSP网页中<%@ include>指令以及jsp:forward标签包含的其他JSP文件
    Java Web之JSP使用Java Bean_第3张图片

  3. 当所有共享同一个客户请求的JSP页面执行完毕并向客户端发回响应时,JavaBean对象结束生命周期。

  4. JavaBean对象作为属性保存在HttpServletRequest对象中,属性名为jsp:useBean标签中JavaBean的id,属性值为JavaBean对象。相当于执行以下语句:request.setAttribute(“myBean”,mybean);

  5. JSP还可以通过HttpServletRequest.getAttribute()方法
    取得JavaBean对象,例如:
    <%CounterBean obj=(CounterBean)request.getAttribute(“myBean”);%>

  6. eg:requestCounter1.jsp

<%@ page import="mypack.CounterBean" %>

<html><head><title>Counter</title></head><body>

<jsp:useBean id="myRequestBean" scope="request" class="mypack.CounterBean" />

<jsp:setProperty name="myRequestBean" property="count"
	value="<%=myRequestBean.getCount()+1 %>" />

Current count value is :<jsp:getProperty name="myRequestBean" property="count" />

<%
String scopeNames[]={"No scope","page","request","session","application"};
int scope=pageContext.getAttributesScope("myRequestBean");
%>

<p>scope=<%=scopeNames[scope]%></p>

</body></html>

运行:
(1)通过浏览器第一次访问
http://localhost:8080/helloapp/requestCounter1.jsp,将会看到网页上的内容如下:
Current count value is :1
scope=request
(2)通过浏览器多次访问requestCounter1.jsp,会看到CounterBean对象的count属性的值始终为1。

接下来
修改requestCounter1.jsp:

<p>scope=<%=scopeNames[scope]%></p>
<jsp:forward page="requestCounter2.jsp" /> 

requestCounter2.jsp:

<%@ page import="mypack.CounterBean" %>

<html>
<head>
<title>
Counter
</title>
</head>
<jsp:useBean id="myRequestBean" scope="request" class="mypack.CounterBean" />
<body>

Current count value is :<jsp:getProperty name="myRequestBean" property="count" />

</body>
</html>

运行:
(1)通过浏览器第一次访问
http://localhost:8080/helloapp/requestCounter1.jsp,将会看到网页上的内容如下:
Current count value is :1
scope=request
Java Web之JSP使用Java Bean_第4张图片
执行requestCounter1.jsp,Servlet容器创建名为myRequestBean的Java Bean对象,count值为1,请求转发到requestCounter2.jsp,发现已经有名为myRequestBean的Java Bean对象,因此Servlet容器不再创建新的Java Bean对象,因为requestCounter1.jsp与requestCounter2.jsp共享HttpServletRequest对象,也共享存放在HttpServletRequest里的myRequestBean以及属性,因此count值为1,当requestCounter2.jsp响应结果回到客户端,因此本次请求完全结束,HttpServletRequest对象结束生命周期,存放在其中的myRequestBean也结束生命周期。
(2)通过浏览器多次访问requestCounter1.jsp,会看到CounterBean对象的count属性的值始终为1。

4.3 JavaBean在session范围内

  1. JavaBean对象被创建后,它存在于整个Session的生命周期内,同一个Session中的JSP文件共享这个JavaBean对象。(只创建一个Java Bean对象)
  2. 一个HTTP会话中会包含多个“请求/响应”回合。
  3. JavaBean对象作为属性保存在HttpSession对象中,属性名为jsp:useBean标签中的JavaBean的id,属性值为JavaBean对象。相当于执行以下语句:session.setAttribute(“myBean”,mybean);
  4. JSP也可以通过HttpSession.getAttribute()方法取得JavaBean对象,例如:
    <%CounterBean obj=(CounterBean)session.getAttribute(“myBean”);%>
  5. eg:
    sessionCounter.jsp:
<%@ page import="mypack.CounterBean" %>

<html><head><title>Counter</title></head>
<body>
<jsp:useBean id="mySessionBean" scope="session" class="mypack.CounterBean" />

<jsp:setProperty name="mySessionBean" property="count"
	value="<%=mySessionBean.getCount()+1 %>" />

Current count value is :<jsp:getProperty name="mySessionBean" property="count" />

<%
String scopeNames[]={"No scope","page","request","session","application"};
int scope=pageContext.getAttributesScope("mySessionBean");
%>

<p>scope=<%=scopeNames[scope]%></p>

</body></html>

运行:
1)通过浏览器第一次访问
http://localhost:8080/helloapp/sessionCounter.jsp,将会看到网页上的内容如下:
Current count value is :1
scope=session
(2)通过当前浏览器多次访问sessionCounter.jsp,会看到CounterBean对象的count属性的值不断递增。
(3)再打开一个新的浏览器,通过它多次访问sessionCounter.jsp,会看到CounterBean对象的count属性的值从1开始不断递增。(新的浏览器开始新的会话,两个会话独立的,拥有各自的Java Bean对象,不过名字都叫mysessionBean)

4.4 JavaBean在application范围内

  1. JavaBean对象被创建后,它存在于整个Web应用的生命周期内,Web应用中的所有JSP文件在任何时候都能共享同一个JavaBean对象。
  2. JavaBean对象作为属性保存在ServletContext对象中,属性名为jsp:useBean标签中JavaBean的id,属性值为JavaBean对象,相当于执行以下语句:application.setAttribute(“myBean”,mybean);
  3. JSP中也可以通过application.getAttribute()方法取得JavaBean对象,例如:
    <%CounterBean obj=(CounterBean)application.getAttribute(“myBean”);%>
  4. eg:
    applicationCounter.jsp:
<%@ page import="mypack.CounterBean" %>

<html><head><title>Counter</title></head><body>

<jsp:useBean id="myApplicationBean" scope="application" class="mypack.CounterBean" />

<jsp:setProperty name="myApplicationBean" property="count"
	value="<%=myApplicationBean.getCount()+1 %>" />

Current count value is :<jsp:getProperty name="myApplicationBean" property="count" />

<%
String scopeNames[]={"No scope","page","request","session","application"};
int scope=pageContext.getAttributesScope("myApplicationBean");
%>

<p>scope=<%=scopeNames[scope]%></p>

</body></html>

运行:
(1)通过浏览器第一次访问
http://localhost:8080/helloapp/applicationCounter.jsp,将会看到网页上的内容如下:
Current count value is :1
scope=application
(2)通过当前浏览器多次访问applicationCounter.jsp,会看到CounterBean对象的count属性的值不断递增。(当前应用范围内只有一个名为myApplicationBean的对象)
(3)再打开一个新的浏览器,通过它多次访问applicationCounter.jsp,会看到CounterBean对象的count属性的值在第一个浏览器中看到的最后值的基础上不断递增。(不同的浏览器访问的始终是同一个myApplicationBean对象)
(4)重新启动helloapp应用,再通过浏览器多次访问applicationCounter.jsp,会看到CounterBean对象的count属性的值又从1开始不断递增。(上次一关闭应用时,与它关联的JavaBean对象也就终止生命周期,重新启动,Servlet容器会创建新的JavaBean对象)

5. JSP与JavaBean搭配使用的优点

1)使得HTML与Java程序分离,这样便于维护代码。如果把所有的程序代码都写到JSP网页中,会使得代码繁杂,难以维护
2)可以降低开发JSP网页人员对Java编程能力的要求
3)JSP侧重于生成动态网页,事务处理由JavaBean来完成,这样可以充分利用JavaBean组件的可重用性特点,提高开发网站的效率

6. 练习题

  1. 问题:以下jsp:useBean等价于哪段JSP程序代码?
    scope=“session” />
    选项 (A)
    <%
    CounterBean myBean=(CounterBean)session.getAttribute(“myBean”);
    if(myBeannull){
    myBean=new CounterBean();
    session.setAttribute(“myBean”,myBean);
    }
    %>
    选项 (B)
    <%
    CounterBean myBean=(CounterBean)session.getAttribute(“CounterBean”);
    if(myBean
    null){
    myBean=new CounterBean();
    session.setAttribute(“CounterBean”,myBean);
    }
    %>
    scope=“session” />
    选项 ©
    <%
    CounterBean myBean=(CounterBean)session.getAttribute(“myBean”);
    if(myBean==null)
    myBean=new CounterBean();
    }
    %>
    答案: A
  2. 问题:对于:
    class=“mypack.CounterBean” scope=“application" />
    如何输出myBean的count属性?
    选项:
    (A)
    (B)
    <% CounterBean counterBean=(CounterBean)application.getAttribute(“myBean”); %>
    <%=counterBean.getCount()%>
    ©
    <% CounterBean counterBean=application.getAttribute(“myBean”);%>
    <%=counterBean.getCount()%>

答案:A,B
注意:application.getAttribute()方法的返回类型是object类型,需要进行强制类型转换,转换为CounterBean类型

  1. 问题:mypack.CounterBean类的类文件应该发布到helloapp应用的什么目录下?
    选项:
    (A) /helloapp
    (B) /helloapp/WEB-INF/
    © /helloapp/WEB-INF/classes
    (D) /helloapp/WEB-INF/classes/mypack
    答案:D

  2. 问题:在JSP页面中通过jsp:useBean标签来访问JavaBean,而不是通过<% …%>Java程序片段来访问JavaBean,有什么好处?
    答案:把程序代码与JSP网页分离,使JSP网页更加简洁,可维护。

  3. 问题:为什么JavaBean必须遵守特定的规范,比如对于CounterBean的count属性,其get和set方法应该为getCount()和setCount()方法,而不能随心所欲的定义为getCOunt()、insertcount()等等其他名字?
    答案:当所有JavaBean遵守相同的规范,jsp:getProperty和jsp:setProperty标签就能自动根据JavaBean的属性来推断出它的get和set访问方法。(因为如果JavaBean遵守相同的规范,那么使用Java Bean的系统就可以按照统一的方式来访问Java Bean)

你可能感兴趣的:(Java,web,java,tomcat,开发语言,web,app,web)