目录
前言
jsp页面可以将数据的处理过程指派到一个文件中去,这个文件就被叫为javabean,即JSP页面调用这些bean来完成数据的处理,并将有关处理的结果存放到bean中,然后JSP页面负责显示这些Bean中的数据.
5.1 编写和使用JavaBean
5.1.1 编写JavaBean
编写JavaBean就是编写一个Java 的类,所以只要会写类就能编写一个JavaBean。这个类创建的一个对 象称为一个JavaBean,简称bean,分配给bean的变量(成员变量),也称bean的属性。为了能让使用bean的应用程序构建工具(比如Tomcat服务器)使用JSP动作标记知道bean的属性和方法,在类的命名上需要遵守以下规则:
(1) 如果类的成员变量(也称bean的属性)的名字是xxx,那么为了获取或更改bean的属性的值,类中必须提供两个方法:
getXx(), 用来获取属性xxx。
setXxx(),用来修改属性xXX。
(2)类中定义方法必须是public型
(3)类中必须有一个构造方法
例如下面参考代码:
package tom.jiafei;
public class Circle {
double radius;
public Circle() {
radius=1;
}
public double getRadius() {
return radius;
}
public void setRadius(double newRadius) {
radius=newRadius;
}
public double circleArea() {
return Math.PI*radius*radius;
}
public double circleLength() {
return 2.0*Math.PI*radius;
}
}
编码方法为ANSI.
5.1.2 保存bean的字节码
为了使JSP页面使用bean, Tomcat服务器必须使用相应的字节码文件创建一个对象,即创建一个bean。为了让Tomcat服务器能找到字节码文件,字节码文件必须保存在特定的目录中
在Tomcat目录下,JavaBean的字节码通常保存在WEB-INF/classes目录下。根据包名对应的路径,可以在该目录下建立相应的子目录。
5.1.3 创建与使用bean
1.使用bean
具体格式为:
<jsp:useBean id="beanName" class="packageName.className" scope="scopeType" />
2.bean的加载原理
当使用jsp:useBean标记加载JavaBean对象时,JSP容器会检查是否已经存在指定名称和作用域的JavaBean对象。如果存在,则直接返回该对象;如果不存在,则创建一个新的JavaBean对象,并将其存储到指定作用域中。
- 检查指定名称和作用域的JavaBean对象是否已经存在。
- 如果存在,则返回该JavaBean对象。
- 如果不存在,则创建一个新的JavaBean对象。
- 根据指定作用域,将新创建的JavaBean对象存储到相应作用域中。
- 返回新创建的JavaBean对象。
3.bean的有效范围和生命周期
下面就JSP动作标记useBean中scope取值的不同情况进行说明:
(1) page bean。scope 取值为page的bean称为page bean,page bean 的有效范围是用户访问的当前页面,存活时间直到当前页面执行完毕。Tomeat 服务器分配给每个JSP页面的page bean是互不相同的。也就是说,尽管每个JSP页面的page bean的功能相同,但它们占有不同的内存空间。page bean的有效范围是当前页面.当页面执行完毕,Tomcat服务器取消分配的page bean,即释放page bean所占有的内存空间。需要注意的是,不同用户(浏览器)的page bean也是互不相同的。也就是说,当两个用户同时访问同一个JSP页面时,一个用户对自己pegebean的属性的改变.不会影响到另一-个用户。
(2) session bean。scope 取值为session的bean 称为session bean,session bean的有效范围是用户访问的Web服务目录下的各个页面,存活时间是用户的会话期(session)间,直到用户的会话消失(session对象达到了最大生存时间或用户关闭自己的浏览器以及服务器关闭,见4.3.1节)。如果用户访问Web服务目录多个页面,那么每个页面id相同的session bean是同一个bean(占有相同的内存空间)。因此,用户在某个页面更改了这个session bean的属性值,其他页面的这个sessionbean的属性值也将发生同样的变化。当用户的会话(session)消失,Tomcat服务器取消所分配的session bean, 即释放session bean所占有的内存空间。需要注意的是,不同用户(浏览器)的session bean是互不相同的(占有不同的内存空间)。也就是说,当两个用户同时访问同一个Web服务目录,一个用户对自己session bean属性的改变,不会影响到另一个用户(一个用户在不同Web服务目录的session bean互不相同)。
(3) request bean. scope 取值为request的ben称为request bean, request bean的有效范围是用户道求的当前页面,存活时间是从用户的请求产生到请求结束。Tomeat 服务器分配给每个ISP页面的rques bean是互不相同的。Tomcat服务器对请求作出响应之后,取消分配给这个ISP页面的roues ben简单地说trqwet bean只在当前页面有效,直到响应销火,M存质时回前长干 Ple的存话时间,原因是 Tomal服务器认为页面执行后。职应才的的来,国爱注意的总,不同用户的r ben的也处业不用同的山就是说,当两个用户同时请求同一个JSP页面时,个用户对自己 requet ben属性的改变,不会影响到另一个用户。
(4)application bean.有效范围为当期web服务目录下的各个页面.
使用session bean时,要保证支持Cookie.
参考代码如下:
example5_2_a.jsp
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=cyan>
<p style="font-family:宋体;font-size:36;color:blue">
<%--通过JSP标记,用户获得一个id是girl的session bean: --%>
<jsp:useBean id="girl" class="tom.jiafei.Circle" scope="session" />
<br>这里是example5_2_a.jsp页面。
<br>圆的半径是<%=girl.getRadius()%>
<br>单击超链接,到其他页面看圆的半径。
<a href="example5_2_b.jsp"><br>example5_2_b.jsp</a>
</p></body></HTML>
example5_2_b.jsp
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor= #ffccff>
<p style="font-family:黑体;font-size:36;color:blue">
<%--用户的id是girl的session bean: --%>
<jsp:useBean id="girl" class="tom.jiafei.Circle" scope="session"/>
<i><br>这里是example5_2_b.jsp页面
<br>当前圆的半径是: <%=girl.getRadius()%>
<% girl.setRadius(1.618);
%>
<br>修改后的圆的半径是<%=girl.getRadius()%></i>
<br>单击超链接,到其他页面看圆的半径。
<a href="example5_2_a.jsp"><br>example5_2_a.jsp</a>
</p></body></HTML>
结果:
5.2 获取和修改bean的属性
5.2.1 getProperty动作标记
使用getProperty动作标记可以获得bean的属性值,并将这个值用串的形式发送给用户的浏览器。使用getProperty动作标记之前,必须使用useBean 动作标视频i记获得相应的bean。
具体格式为:
<jsp:getProperty name="beanName" property="propertyName"/>
5.2.2 setProperty动作标记
JSP页面中用于设置JavaBean对象属性值的标记。它的语法格式为:
<jsp:setProperty name="beanName" property="propertyName" value="propertyValue"/>
5.3 bean的辅助类
在写一个创建bean的类时,除了需要用import语句引入JDK提供的类,可能还需要自己编写一些其他的类,只要将这样类的包名和bean类的包名致即可(也可以和创建bean的类写在一个Java源文件中)。在下面的例5_ 5中,使用一个bean列出Tomcat服务器驻留的计算机上某目录中特定扩展名的文件.
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<% request.setCharacterEncoding("utf-8");
%>
<style>
#textStyle{
font-family:宋体;font-size:36;color:blue
}
</style>
<jsp:useBean id="file" class="tom.jiafei.ListFile" scope="request"/>
<HTML><body id=textStyle bgcolor = #ffccff>
<form action="" Method="post">
输入目录名(例如D:/2000)<input type=text name="dir" id=textStyle size=15/><br>
输入文件的扩展名(例如java)<input type=text name="extendsName" id=textStyle size=6>
<input type=submit id=textStyle value="提交"/>
</form>
<jsp:setProperty name="file" property="dir" param="dir"/>
<jsp:setProperty name="file" property="extendsName" param="extendsName"/>
<br><b>目录 <jsp:getProperty name="file" property="dir"/>中
扩展名是 <jsp:getProperty name="file" property="extendsName"/> 的文件有:
<% String [] fileName = file.getAllFileName();
if(fileName!=null) {
for(int i=0;i<fileName.length;i++) {
out.print("<br>"+fileName[i]);
}
}
%>
</body></HTML>
package tom.jiafei;
import java.io.*;
class FileExtendName implements FilenameFilter {
String str=null;
FileExtendName (String s) {
str="."+s;
}
public boolean accept(File dir,String name) {
return name.endsWith(str);
}
}
public class ListFile {
String extendsName=null;
String [] allFileName=null;
String dir=null;
public void setDir(String dir) {
this.dir =dir;
}
public String getDir() {
return dir;
}
public void setExtendsName(String s) {
extendsName=s;
}
public String getExtendsName() {
return extendsName;
}
public String [] getAllFileName() {
if(dir!=null) {
File mulu=new File(dir);
FileExtendName help=new FileExtendName(extendsName);
allFileName=mulu.list(help);
}
return allFileName;
}
}
结果:
5.4 JSP与bean结合的简单例子
JSP页面中调用bean可以将数据的处理从页面中分离出来,实现代码复用 ,以便更有效地维护一个WEB应用
5.4.1 三角形bean
例子中的jsp页面提供一个form表,单用户可以通过form表单将三角形的三边的长度提交给该页面用户,提交form表单后,jsp页面将计算三角形面积的任务交给一个request,bean去完成。
参考代码如下:
Triangle.java
package red.star;
public class Triangle {
double sideA=-1,sideB=-1,sideC=-1;
String area;
boolean isTriangle;
public void setSideA(double a) {
sideA=a;
}
public double getSideA() {
return sideA;
}
public void setSideB(double b) {
sideB=b;
}
public double getSideB() {
return sideB;
}
public void setSideC(double c) {
sideC=c;
}
public double getSideC() {
return sideC;
}
public String getArea() {
double p=(sideA+sideB+sideC)/2.0;
if(isTriangle){
double result= Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC));
area = String.format("%.2f",result);//保留2位小数。
}
return area;
}
public boolean getIsTriangle(){
if(sideA<sideB+sideC&&sideB<sideA+sideC&&sideC<sideA+sideB)
isTriangle=true;
else
isTriangle=false;
return isTriangle;
}
}
example_5_6.jsp
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#textStyle{
font-family:宋体;font-size:36;color:blue
}
</style>
<% request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="triangle" class="red.star.Triangle" scope="request"/>
<HTML><body id = textStyle bgcolor=#ffccff>
<form action="" method="post" >
输入三角形三边:
边A:<input type=text name="sideA" id = textStyle value=0 size=5/>
边B:<input type=text name="sideB" id = textStyle value=0 size=5/>
边C:<input type=text name="sideC" id = textStyle value=0 size=5/>
<br><input type=submit id = textStyle value="提交"/>
</form>
<jsp:setProperty name="triangle" property="*"/>
三角形的三边是:
<jsp:getProperty name="triangle" property="sideA"/>,
<jsp:getProperty name="triangle" property="sideB"/>,
<jsp:getProperty name="triangle" property="sideC"/>.
<br><b>这三个边能构成一个三角形吗?<jsp:getProperty name="triangle" property="isTriangle"/>
<br>面积是:<jsp:getProperty name="triangle" property="area"/></b>
</body></HTML>
结果:
5.4.2 四则运算bean
参考代码如下:
example5_7.jsp
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#textStyle{
font-family:宋体;font-size:36;color:blue
}
</style>
<% request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="computer" class="red.star.ComputerBean" scope="session"/>
<HTML><body id = textStyle bgcolor=#ffccff>
<jsp:setProperty name="computer" property="*"/>
<form action="" method=post >
<input type=text name="numberOne" id = textStyle size=6/>
<select name="operator" id = textStyle >
<option value="+" id = textStyle>+
<option value="-" id = textStyle>-
<option value="*" id = textStyle>*
<option value="/" id = textStyle>/
</select>
<input type=text name="numberTwo" id = textStyle size=6/>
<br> <input type="submit" value="提交" id = textStyle "/>
</form>
<b>
<jsp:getProperty name="computer" property="numberOne"/>
<jsp:getProperty name="computer" property="operator"/>
<jsp:getProperty name="computer" property="numberTwo"/> =
<jsp:getProperty name="computer" property="result"/></b>
</body></HTML>
ComputerBean.java
package red.star;
public class ComputerBean {
double numberone,numbertwo,result,numberthree;
String operator1="+";
String operator2= "+";
public void setNumberOne(double n) {
numberone=n;
}
public double getNumberOne() {
return numberone;
}
public void setNumberTwo(double n) {
numbertwo=n;
}
public double getNumberTwo() {
return numbertwo;
}
public void setOperator1(String s) {
operator1=s.trim();
}
public String getOperator1() {
return operator1;
}
public void setNumberThree(double n) {
numberthree=n;
}
public double getNumberThree() {
return numberthree;
}
public void setOperator2(String s) {
operator2=s.trim();
}
public String getOperator2() {
return operator2;
}
public double getResult() {
if(operator1.equals("+"))
result=numberone+numbertwo;
else if(operator1.equals("-"))
result=numberone-numbertwo;
else if(operator1.equals("*"))
result=numberone*numbertwo;
else if(operator1.equals("/"))
result=numberone/numbertwo;
if(operator2.equals("+"))
result=result+numberthree;
else if(operator2.equals("-"))
result=result-numberthree;
else if(operator2.equals("*"))
result=result*numberthree;
else if(operator2.equals("/"))
result=result/numberthree;
return result;
}
}
结果:
5.4.3 浏览图像bean
example5_8.jsp
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#textStyle{
font-family:宋体;font-size:36;color:blue
}
</style>
<% request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="play" class="red.star.Play" scope="session" />
<%
String webDir = request.getContextPath();//获取当前Web服务目录的名称
webDir = webDir.substring(1); //去掉名称前面的目录符号:/
%>
<jsp:setProperty name="play" property="webDir" value="<%= webDir %>"/>
<jsp:setProperty name="play" property="index" param = "index" />
<HTML><body bgcolor = cyan><p id = textStyle>
<image src =
image/<jsp:getProperty name="play" property="showImage"/> width =300 height =200>
</image><br>
<a href ="?index=<%=play.getIndex()+1 %>">下一张</a>
<a href ="?index=<%=play.getIndex()-1 %>">上一张</a>
</p></body></HTML>
Play.java
package red.star;
import java.io.*;
public class Play {
String pictureName[]; //存放全部图片文件名字的数组。
String showImage; //存放当前要显示的图片。
String webDir=""; //web服务目录的名字,例如ch5
String tomcatDir; //tomcat的安装目录,例如apache-tomcat-9.0.26。
int index = 0; //存放图片文件的序号
public Play() {
File f= new File(""); //该文件认为在Tomcat服务器启动的目录中即bin目录中。
String path = f.getAbsolutePath();
int index = path.indexOf("bin");//bin是tomcat的安装目录下的子目录。
tomcatDir = path.substring(0,index); //得到tomcat的安装目录的名字。
}
public void setWebDir(String s) {
webDir = s;
File dirImage = new File(tomcatDir+"/webapps/"+webDir+"/image");
pictureName = dirImage.list();
}
public String getShowImage() {
showImage = pictureName[index];
return showImage;
}
public void setIndex(int i) {
index = i;
if(index>=pictureName.length)
index = 0;
if(index < 0)
index = pictureName.length-1;
}
public int getIndex() {
return index ;
}
}
结果:
5.4.4日历bean
example5_9.jsp
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#textStyle{
font-family:宋体;font-size:18;color:blue
}
</style>
<% request.setCharacterEncoding("utf-8");
%>
<HTML><body id = textStyle bgcolor = #ffccff>
<jsp:useBean id="calendar" class="red.star.Calendar" scope="session" />
<jsp:setProperty name="calendar" property="year" param = "year"/>
<jsp:setProperty name="calendar" property="month" param = "month" />
<jsp:getProperty name="calendar" property="year" /> 年
<jsp:getProperty name="calendar" property="month" />月的日历:<br>
<jsp:getProperty name="calendar" property="saveCalender" />
<br><a href ="?month=<%=calendar.getMonth()+1 %>">下一月</a>
<a href ="?month=<%=calendar.getMonth()-1 %>">上一月</a>
<form action="" method = get >
输入年份<input type=text name="year" id = textStyle size=6 />
选择月份 <select name="month" id = textStyle size =1>
<option value="1">1月</option>
<option value="2">2月</option>
<option value="3">3月</option>
<option value="4">4月</option>
<option value="5">5月</option>
<option value="6">6月</option>
<option value="7">7月</option>
<option value="8">8月</option>
<option value="9">9月</option>
<option value="10">10月</option>
<option value="11">11月</option>
<option value="12">12月</option>
</select><br>
<input type="submit" value="提交" id = textStyle "/>
</form>
</body></HTML>
Calender.java
package red.star;
import java.time.LocalDate;
import java.time.DayOfWeek;
public class Calendar {
int year ,month ;
String saveCalender; //存放日历
public Calendar(){
year = LocalDate.now().getYear();
month = LocalDate.now().getMonthValue();
}
public void setYear(int y){
year = y;
}
public int getYear(){
return year;
}
public void setMonth(int m){
month = m;
if(month>12){
year++;
month = 1;
}
if(month<1){
month = 12;
year--;
}
}
public int getMonth(){
return month;
}
public String getSaveCalender(){
LocalDate date = LocalDate.of(year,month,1);
int days = date.lengthOfMonth(); //得到该月有多少天。
int space = 0; //存放空白字符的个数
DayOfWeek dayOfWeek = date.getDayOfWeek(); //得到1号是星期几
switch(dayOfWeek) {
case SUNDAY: space = 0;
break;
case MONDAY: space = 1;
break;
case TUESDAY: space = 2;
break;
case WEDNESDAY: space = 3;
break;
case THURSDAY: space = 4;
break;
case FRIDAY: space = 5;
break;
case SATURDAY: space = 6;
break;
}
String [] c = new String[space+days];
for(int i=0;i<space;i++)
c[i]="--";
for(int i = space,n=1;i<c.length;i++){
c[i] = String.valueOf(n) ;
n++;
}
String head =
"<tr><th>星期日</th><th>星期一</th><th>星期二</th><th>星期三</th>"+
"<th>星期四</th><th>星期五</th><th>星期六</th> </tr>";
StringBuffer buffer = new StringBuffer();
buffer.append("<table border = 0>");
buffer.append(head);
int n = 0;
while(n<c.length){
buffer.append("<tr>");
int increment = Math.min(7,c.length-n);
for(int i=n;i<n+increment;i++) {
buffer.append("<td align= center>"+c[i]+"</td>");
}
buffer.append("</tr>");
n = n+increment;
}
buffer.append("</table>");
saveCalender = new String(buffer);
return saveCalender;
}
}
结果:
总结
本章讲述了第五章JSP与javaBean.JSP与JavaBean的结合可以方便地实现数据的封装和操作,提高代码的可维护性和可读性。JSP与JavaBean的结合是Web开发中常用的技术,掌握它们可以让我们更加高效地开发Web应用程序。