JavaBeans与JSP页面的使用及作用域管理
1. JavaBeans在JSP页面中的基本概念
在JSP页面中使用JavaBeans时,
getSideC
方法用于计算三角形长边的长度,并将结果以字符串形式返回。若三角形任意一边的值为零,该方法会假定用户未输入数据,进而返回错误信息,因为三角形的边长不能为零。同时,由于没有
setSideC
方法,
sideC
属于只读属性。
2. JSP页面中操作JavaBeans的标签
要在JSP页面中使用JavaBeans,需添加特殊标签来创建、设置和获取Bean的属性。以下是这些标签及其说明:
| 标签 | 描述 |
| — | — |
|
<jsp:useBean id="name" class="package.class" />
| 建立对Bean的引用,必要时创建实例。
id
属性指定的名称供其他标签引用该Bean。 |
|
<jsp:getProperty name="name" property="property" />
| 从
name
属性指定的Bean中检索
property
属性的值。 |
|
<jsp:setProperty name="name" property="property" value="value" />
| 将
property
属性设置为
value
属性指定的值。 |
|
<jsp:setProperty name="name" property="property" param="parameter" />
| 将
property
属性设置为
param
属性指定的参数值,该参数通常是表单字段的名称。 |
|
<jsp:setProperty name="name" property="*" />
| 将Bean定义的所有属性设置为相应的参数值,前提是存在名称正确的参数。 |
3. 创建Bean实例
在JSP页面中包含Bean,需添加
<jsp:useBean>
标签。其最简形式如下:
<jsp:useBean id="name" class="package.Class" />
-
id属性为JSP中其他地方引用该Bean提供名称。 -
class属性提供类名,并带有包名。
例如,使用
Triangle
Bean的标签如下:
<jsp:useBean id="triangle" class="calculators.Triangle" />
<jsp:useBean>
标签会在实例不存在时,通过调用无参构造函数创建Bean实例;若实例已存在,则使用现有实例。
使用
<jsp:useBean>
标签还需注意以下几点:
- 该标签可出现在JSP文档的任意位置,但必须在引用该Bean的其他标签之前。
- 所有Bean标签区分大小写,需严格按照示例编写。
- 若运行JSP时Tomcat提示找不到Bean,需检查包名和类名的大小写,并确保Bean的类文件存储在
WEB-INF\classes
下与包名相同的目录中,如
Triangle
Bean的类文件应存储在
WEB-INF\classes\calculators
中。
-
<jsp:useBean>
元素可包含
<jsp:setProperty>
标签,用于初始化属性值。此时,元素形式更像普通HTML,有正确的开始和结束标签。示例如下:
<jsp:useBean id="t1" class="calculators.Triangle" >
<jsp:setProperty name="t1" property="sideA" value="3.0" >
<jsp:setProperty name="t1" property="sideB" value="3.0" >
</jsp:useBean>
需注意,
<jsp:setProperty>
标签仅在
<jsp:useBean>
标签实际创建新的Bean实例时执行;若实例已存在,则不执行。
-
<jsp:useBean>
标签还有
scope
属性,后续会详细介绍。
4. 获取属性值
使用
<jsp:getProperty>
标签获取Bean属性的值,其形式简单:
<jsp:getProperty name="name" property="property" />
例如,获取上一节创建的
Triangle
Bean的
sideC
属性的标签如下:
<jsp:getProperty name="triangle" property="sideC" />
name
属性必须与
<jsp:useBean>
标签中
id
属性的值一致,
property
属性用于确定Getter方法的名称,如
getSideC
。
需注意,属性名应以小写字母开头,否则运行页面时服务器会报错。多数情况下,
<jsp:getProperty>
标签用于将属性值插入页面,也可用于指定JSP文档中其他标签的属性值。例如:
<input type="text" name="sideA" value="<jsp:getProperty name="triangle" property="sideA" />" >
使用时要特别注意引号和标签括号的匹配。
5. 设置属性值
设置属性值可使用
<jsp:setProperty>
标签的几种变体。若要将属性设置为字面字符串,可按如下方式编写标签:
<jsp:setProperty name="triangle" property="sideA" value="4.0" />
name
属性需与
<jsp:useBean>
标签的
id
属性匹配,
property
属性用于确定Setter方法的名称,
value
属性提供要设置的值。
实际开发中,
<jsp:setProperty>
标签的
param
形式更实用,它能将属性设置为用户在表单字段中输入的值或通过查询字符串传递给JSP的值。例如:
<input type="text" name="FirstSide" >
<jsp:setProperty name="triangle" property="sideA" param="FirstSide" />
若用户在
FirstSide
字段输入值,该值将被赋给Bean的
sideA
属性。实际使用中,通常会给表单字段和关联属性设置相同的名称:
<input type="text" name="sideA" >
<jsp:setProperty name="triangle" property="sideA" param="sideA" />
若表单字段名称与属性名称相同,可使用以下标签将所有字段的值赋给对应的属性:
<jsp:setProperty name="triangle" property="*" />
此形式的标签能为包含大量字段的表单节省编码量。
6. 使用JavaBeans的JSP页面示例
以下是一个完整的JSP页面示例,展示了如何使用上述标签:
<html>
<jsp:useBean id="triangle" class="calculators.Triangle" />
<jsp:setProperty name="triangle" property="*" />
<head>
<title>Right Triangle Calculator</title>
</head>
<body>
<h1>The Right Triangle Calculator</h1>
<form action="Triangle.jsp" method="post">
Side A:
<input type="text" name="sideA" value="<jsp:getProperty name="triangle" property="sideA" />" >
<br><br>
Side B:
<input type="text" name="sideB" value="<jsp:getProperty name="triangle" property="sideB" />" >
<br><br>
Side C:
<jsp:getProperty name="triangle" property="sideC" />
<br><br>
<input type="submit" value="Calculate" >
</form>
</body>
</html>
该页面显示两个文本输入字段和一个按钮。用户输入三角形两条短边的长度并点击按钮后,页面将显示Bean的
sideC
属性,即第三条边的长度。
以下是该JSP页面关键代码的详细解释:
-
jsp:useBean
标签创建
calculators.Triangle
Bean的实例,并命名为
triangle
。
-
jsp:setProperty
标签将
sideA
和
sideB
属性设置为对应输入字段的值。
-
form
标签创建一个表单,使用HTTP POST方法将数据提交回同一JSP文件。
- 第一个输入文本字段名为
sideA
,其初始值设置为Bean的
sideA
属性值。
- 第二个输入文本字段名为
sideB
,其初始值设置为Bean的
sideB
属性值。
- 该行代码用于检索
sideC
属性,根据
sideA
和
sideB
的值计算三角形第三条边的长度,并将结果插入文档。
- 提交按钮提交表单,使
Triangle
Bean执行相应操作。
7. JavaBeans的作用域
JavaBeans的作用域表示Bean的存活时间,可通过
<jsp:useBean>
标签的
scope
属性指定。
scope
属性有以下四种值:
| 作用域 | 解释 |
| — | — |
|
page
| Bean与当前页面关联,每次用户请求页面时创建新的Bean实例,页面返回浏览器后销毁,每次往返服务器都会创建新实例。 |
|
request
| 与
page
类似,但Bean可被同一请求处理的其他页面访问,适用于单个请求涉及多个Servlet或JSP的应用程序。 |
|
session
| Bean与用户会话关联,用户首次请求应用程序页面时创建Bean并与用户关联,后续同一用户的请求使用相同的Bean。 |
|
application
| 应用程序的所有用户共享一个Bean实例。 |
默认作用域为
page
,即每次用户请求新页面时创建和销毁Bean。但
session
作用域对于需要在不同页面跟踪用户信息的Web应用非常有用,如购物车应用。
8. 购物车应用示例
以下是一个简单的购物车应用,用户可通过点击三个按钮选择购买三本书。点击按钮时,商品将添加到购物车;若商品已在购物车中,数量将加一。
购物车应用的关键技术如下:
- 购物车本身是一个JavaBean,有两个公共方法:
setBook
用于将书籍添加到购物车,
getList
返回一个字符串,以HTML表格形式展示购物车中的商品。
- 购物车类包含一个内部类
Book
,为简化应用,
Book
类中硬编码了三本书的标题;实际应用中,应使用文件或数据库存储这些值。
- 页面顶部的商品列表由三个独立的表单组成,每个表单通过查询字符串向服务器上的JSP传递参数
book
,其值为用户订购书籍的代码。该参数绑定到购物车Bean的
book
属性,用户点击按钮时,
setBook
方法将被调用,传入
book
参数的值,从而确定用户订购的书籍。
- 书籍列表下方,JSP使用
<jsp:getProperty>
标签获取
list
属性,展示购物车内容。
以下是购物车页面的JSP代码:
<html>
<jsp:useBean id="cart" class="books.BookCart" scope="session"/>
<jsp:setProperty name="cart" property="*" />
<head>
<title>Buy My Books!</title>
</head>
<body>
<h1>Which of my books do you want to buy?</h1>
<form action="BuyMyBook.jsp?book=netfd" method="post">
<input type="submit" value="Buy" >
Networking For Dummies<br><br>
</form>
<form action="BuyMyBook.jsp?book=netaio" method="post">
<input type="submit" value="Buy" >
Networking All-in-One Desk Reference For Dummies
<br><br>
</form>
<form action="BuyMyBook.jsp?book=wordaio" method="post">
<input type="submit" value="Buy" >
Word 2003 All-In-One Desk Reference For Dummies
<br><br>
</form>
<br><h2>Your cart contains:</h2>
<jsp:getProperty name="cart" property="list" />
</body>
</html>
以下是该JSP页面关键代码的详细解释:
-
jsp:useBean
标签加载
books.BookCart
JavaBean,指定其作用域为
session
,确保用户在整个会话期间使用同一Bean实例。
-
jsp:setProperty
标签设置参数属性。用户首次访问
BuyMyBook.jsp
页面时,无参数,该方法不执行;用户点击按钮时,URL末尾添加
book
参数,调用购物车的
setBook
方法,将所选书籍添加到购物车。
- 这是第一本书的表单,每个书籍都有独立表单,包含“Buy”按钮和书籍标题。
action
属性指定点击按钮时,表单以
book
参数值为
netfd
提交到
BuyMyBook.jsp
。
- 第二本书的表单,指定
book
参数值为
netaio
。
- 第三本书的表单,指定
book
参数值为
wordaio
。
- 书籍表单之后,
<jsp:getProperty>
标签调用Bean的
getList
方法,返回包含HTML表格的字符串,展示购物车当前内容。
接下来是
BookCart
JavaBean的Java代码:
package books;
import java.util.ArrayList;
import java.text.NumberFormat;
public class BookCart {
private ArrayList<Book> cart;
private NumberFormat cf = NumberFormat.getCurrencyInstance();
public BookCart() {
cart = new ArrayList<Book>();
}
public void setBook(String code) {
boolean found = false;
for (Book b : cart) {
if (b.getCode().equals(code)) {
b.addQuantity(1);
found = true;
}
}
if (!found) {
cart.add(new Book(code));
}
}
public String getList() {
String list = "<table border=2>";
list += "<tr><td>Title</td><td>Qty</td><td>Price</td><td>Total</td></tr>";
double total = 0.0;
for (Book b : cart) {
list += "<tr><td>" + b.getTitle() + "</td><td>" + b.getQuantity() + "</td><td>" + cf.format(b.getPrice()) + "</td><td>" + cf.format(b.getTotal()) + "</td></tr>";
total += b.getTotal();
}
list += "<tr><td></td><td></td><td>Total:</td><td>" + cf.format(total) + "</td></tr>";
list += "</table>";
return list;
}
private class Book {
private String code;
private int quantity;
public Book(String code) {
this.code = code;
this.quantity = 1;
}
public String getCode() {
return this.code;
}
public String getTitle() {
if (code.equals("netfd")) {
return "Networking For Dummies";
} else if (code.equals("netaio")) {
return "Networking All-in-One Desk Reference For Dummies";
} else if (code.equals("wordaio")) {
return "Word 2003 All-in-One Desk Reference For Dummies";
} else {
return "Unknown book";
}
}
public double getPrice() {
if (code.equals("netfd")) {
return 24.99;
} else if (code.equals("netaio")) {
return 34.99;
} else if (code.equals("wordaio")) {
return 29.99;
} else {
return 0.0;
}
}
public int getQuantity() {
return this.quantity;
}
public void addQuantity(int qty) {
this.quantity += qty;
}
public double getTotal() {
return this.quantity * this.getPrice();
}
}
}
以下是该JavaBean代码的详细解释:
-
BookCart
类位于
books
包中。
- 购物车以私有
ArrayList<Book>
形式存储在
BookCart
Bean中。
- 作为JavaBean,需有无参构造函数,此构造函数初始化购物车列表。
-
setBook
方法用于将书籍添加到购物车,接收书籍代码作为参数。该方法遍历列表,若找到相同代码的书籍,调用其
addQuantity
方法将数量加1;若未找到,则创建新书并添加到购物车。
- 该方法构建包含购物车所有书籍的HTML表格字符串。
<tr>
和
</tr>
标签标记每行的开始和结束,
<td>
和
</td>
标签标记每行中每个单元格的开始和结束。表格为购物车中的每本书包含一行,每行包含标题、数量、价格和总计的单元格。构建每行时,计算购物车的总金额,并在表格底部单独一行显示。表格开头显示标题行。
-
Book
类作为内部类定义,用于表示列表中的书籍。
-
Book
类仅存储每本书的两个信息:书籍代码和数量,其他值通过方法计算返回。
- 构造函数接受书籍代码并初始化实例字段,数量初始化为1。
-
getCode
方法简单返回代码变量。
-
getTitle
方法根据代码返回三本书籍标题之一,若代码不是预定义的三个代码之一,则返回“Unknown book”。
- 同样,
getPrice
方法根据代码返回三个价格之一,若代码不在允许范围内,书籍免费。
-
getQuantity
方法返回数量变量。
-
addQuantity
方法将值添加到数量变量。
-
getTotal
方法通过价格乘以数量计算总计。
综上所述,通过合理使用JavaBeans和JSP标签,结合不同的作用域设置,可以开发出功能丰富、高效的Web应用程序,如购物车应用。在实际开发中,可根据具体需求灵活运用这些技术,提升应用的性能和用户体验。
JavaBeans与JSP页面的使用及作用域管理
9. 操作流程总结
为了更清晰地理解在JSP页面中使用JavaBeans的过程,下面通过一个mermaid流程图展示其主要操作步骤:
graph LR
A[开始] --> B[创建Bean实例]
B --> C{实例是否存在}
C -- 否 --> D[调用无参构造函数创建实例]
C -- 是 --> E[使用现有实例]
D --> F[可选择初始化属性值]
E --> F
F --> G[设置属性值]
G --> H[获取属性值]
H --> I[展示结果]
I --> J[结束]
这个流程图展示了在JSP页面中使用JavaBeans的基本流程,从创建实例开始,根据实例是否存在进行不同处理,接着设置和获取属性值,最后展示结果。
10. 不同作用域的使用场景分析
不同的JavaBeans作用域适用于不同的应用场景,下面详细分析:
| 作用域 | 使用场景 |
| — | — |
|
page
| 当Bean仅在当前页面使用,且每次页面请求需要全新的状态时使用。例如,一个简单的页面计数器,每次页面刷新都重新计数。 |
|
request
| 当一个请求涉及多个页面,且需要在这些页面间共享Bean数据时使用。比如,一个搜索请求,从搜索页面到结果页面,需要共享搜索关键词等信息。 |
|
session
| 对于需要跟踪用户会话信息的应用非常有用。如购物车应用,用户在不同页面浏览商品并添加到购物车,整个会话期间购物车数据保持一致。 |
|
application
| 当应用程序的所有用户需要共享某些全局数据时使用。例如,统计网站的总访问量,所有用户的访问都会影响这个数据。 |
11. 代码优化建议
在使用JavaBeans和JSP标签时,为了提高代码的可读性和可维护性,可参考以下建议:
-
标签编写规范
:虽然JSP标签可以写在一行,但对于较长的标签,适当换行可以提高可读性。例如:
<jsp:setProperty
name="triangle"
property="sideA"
value="4.0"
/>
-
注释使用
:在关键代码处添加注释,解释代码的功能和作用。如在
<jsp:useBean>标签旁注释说明创建的Bean用途。
<!-- 创建Triangle Bean实例,用于计算三角形边长 -->
<jsp:useBean id="triangle" class="calculators.Triangle" />
-
方法封装
:在JavaBean中,将一些复杂的计算逻辑封装到方法中,提高代码的复用性。例如,在
BookCart类中,将计算总金额的逻辑封装到一个单独的方法中。
private double calculateTotal() {
double total = 0.0;
for (Book b : cart) {
total += b.getTotal();
}
return total;
}
然后在
getList
方法中调用该方法:
public String getList() {
String list = "<table border=2>";
list += "<tr><td>Title</td><td>Qty</td><td>Price</td><td>Total</td></tr>";
double total = calculateTotal();
for (Book b : cart) {
list += "<tr><td>" + b.getTitle() + "</td><td>" + b.getQuantity() + "</td><td>" + cf.format(b.getPrice()) + "</td><td>" + cf.format(b.getTotal()) + "</td></tr>";
}
list += "<tr><td></td><td></td><td>Total:</td><td>" + cf.format(total) + "</td></tr>";
list += "</table>";
return list;
}
12. 错误处理与调试
在开发过程中,可能会遇到各种错误,以下是一些常见错误及解决方法:
-
找不到Bean错误
:若Tomcat提示找不到Bean,按照以下步骤检查:
1. 确认包名和类名的大小写是否正确。
2. 检查Bean的类文件是否存储在
WEB-INF\classes
下与包名相同的目录中。
-
属性名大小写错误
:使用
<jsp:getProperty>
和
<jsp:setProperty>
标签时,属性名必须以小写字母开头,否则会导致服务器报错。
-
作用域使用错误
:不同的作用域有不同的生命周期和访问范围,使用时要根据需求选择合适的作用域,避免数据丢失或共享异常。
13. 扩展应用思路
除了购物车应用,JavaBeans和JSP标签还可以应用于更多场景:
-
用户登录系统
:使用
session
作用域的JavaBean存储用户登录信息,在不同页面验证用户身份,实现用户登录、注销等功能。
-
投票系统
:使用
application
作用域的JavaBean统计投票结果,所有用户的投票都会影响最终结果。
-
新闻发布系统
:使用
request
作用域的JavaBean在不同页面传递新闻信息,如从新闻列表页面到新闻详情页面。
14. 总结回顾
通过前面的介绍,我们深入了解了在JSP页面中使用JavaBeans的方法,包括创建实例、设置和获取属性值,以及不同作用域的使用。以下是对关键知识点的总结列表:
- 掌握JSP操作JavaBeans的标签,如
<jsp:useBean>
、
<jsp:getProperty>
和
<jsp:setProperty>
。
- 理解JavaBeans不同作用域的含义和适用场景,合理选择作用域。
- 学会编写JavaBean类,包含必要的方法和属性,满足应用需求。
- 能够编写完整的JSP页面,结合JavaBeans实现具体功能,如购物车应用。
在实际开发中,要根据具体需求灵活运用这些知识,不断优化代码,提高应用的性能和用户体验。同时,要注意错误处理和调试,确保应用的稳定性。通过不断实践和探索,我们可以利用JavaBeans和JSP标签开发出更加复杂和强大的Web应用程序。
超级会员免费看
1567

被折叠的 条评论
为什么被折叠?



