Java Bean的基本概念与JSP中使用Bean
在开发软件过程中,应尽量将业务逻辑和表现层分开,从而达到完全解耦,这是软件分层设计的基本理念。在JSP中,经常利用Java Bean实现核心的业务逻辑,而JSP页面用于表现层。
Java Bean的特点:
支持反射机制:利用反射机制可以分析出Java Bean是如何运行的。
支持事件:事件是一种简单的通信机制,利用它可以将相应的信息通知给Java Bean。
支持属性:可以自定义属性,利用标准标签与JSP页面交互数据。
支持持久性:持久性是指可以将Java Bean进行保存,在需要的时候又可以重新载入。
遵循的规范:
Java Bean类必须是public类。
提供给JSP页面调用的方法,必须赋予public访问权限。
Java Bean类中的属性,提供给JSP页面调用是必须提供public的get和set方法。
必须拥有不带参数的构造方法。
在JSP页面中,要正确使用Bean,应注意以下3个问题:
按照规范定义Bean类,并给出类属性的相应的get和set方法。
在页面中要导入相应的Bean类。
在JSP页面中利用 < < <jsp:useBean > > >标签使用Bean类
Bean类部署的两种方法;
一种是将Bean的Class文件部署在Web服务器的公共目录中。
另一种是将Class文件部署在Web服务器的特定项目的目录中。例如ch09\web\WEB-INF\classes\com\eshore\pojo\User.class。
Bean的作用域:
默认是Page范围,即该Bean在当前页有效。设置request时,表示该Bean对当前用户的当前请求有效。设置为session时,表示该Bean在当前用户的session范围内有效。设置为application时,表示该Bean对系统的所有的页面有效,但是刷新当前界面就不是一个application。
访问Bean属性
直接利用表达式设置Bean属性:
package com.eshore.pojo;
import java.io.Serializable;
public class Product implements Serializable{
private static final long serialVersionUID = 1L;
private String product_id; //产品号
private String product_name; //产品名称
private double price; //产品价格
private String info; //产品信息
public Product() {
//无参构造方法
}
public String getProduct_id() {
return product_id;
}
public void setProduct_id(String productId) {
product_id = productId;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String productName) {
product_name = productName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="product" class="com.eshore.pojo.Product" scope="page"/>
<!DOCTYPE HTML >
<html>
<head>
<title>设置Bean属性</title>
</head>
<body>
<!-- 设置产品名称 -->
<jsp:setProperty name="product" property="product_name" value="struts开发教程"/>
<br/>产品名称是:
<!-- 获取产品名称 -->
<%--<%=product.getProduct_name() %>--%>
<jsp:getProperty name="product" property="product_name"></jsp:getProperty>
<!-- 设置产品编号 -->
<jsp:setProperty name="product" property="product_id" value="111100123689"/>
<br/>产品编号是:
<!-- 获取产品编号 -->
<%--<%=product.getProduct_id() %>--%>
<jsp:getProperty name="product" property="product_id"></jsp:getProperty>
<!-- 设置产品价格 -->
<%
double price = 68.23;
%>
<jsp:setProperty name="product" property="price" value="<%=price+23.67 %>"/>
<br/>产品价格是:
<!-- 获取产品价格 -->
<%--<%=product.getPrice() %>--%>
<jsp:getProperty name="product" property="price"></jsp:getProperty>
<!-- 设置产品信息 -->
<jsp:setProperty name="product" property="info" value="Struts开发教程是一本介绍,如何使用Struts的专业书籍......"/>
<br/>产品信息是:
<!-- 获取产品信息 -->
<%--<%=product.getInfo() %>--%>
<jsp:getProperty name="product" property="info"></jsp:getProperty>
</body>
</html>
通过表单参数名设置Bean属性值:
要注意添加Tomacat包:
<%@ page language="java" import="java.util.*,com.eshore.pojo.Product" pageEncoding="UTF-8"%>
<!-- 设定参数编码 -->
<%
request.setCharacterEncoding("UTF-8");
%>
<!-- 导入引用的bean -->
<jsp:useBean id="product" class="com.eshore.pojo.Product" scope="page"/>
<!DOCTYPE HTML >
<html>
<head>
<title>通过表单参数设置Bean属性值</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
<body>
<form action="" method="post">
<br>
输入产品名称:<input name="product_name"/><br/>
输入产品编号:<input name="product_id"/><br/>
输入产品价格:<input name="price"/><br/>
输入产品信息:<input name="info"/><br/>
<input type="submit" value="提交"/>
</form>
<!-- 设定product的属性值 -->
<jsp:setProperty property="*" name="product"/>
<br/>产品名称是:
<!-- 获取产品名称 -->
<%=product.getProduct_name() %>
<br/>产品编号是:
<!-- 获取产品编号 -->
<%=product.getProduct_id() %>
<br/>产品价格是:
<!-- 获取产品价格 -->
<%=product.getPrice() %>
<br/>产品信息是:
<!-- 获取产品信息 -->
<%=product.getInfo() %>
</body>
</html>
通过表单参数值设置Bean属性值:
<%@ page language="java" import="java.util.*,com.eshore.pojo.Product" pageEncoding="UTF-8"%>
<!-- 设定参数编码 -->
<%
request.setCharacterEncoding("UTF-8");
%>
<!-- 导入引用的bean -->
<jsp:useBean id="product" class="com.eshore.pojo.Product" scope="page"/>
<!DOCTYPE HTML >
<html>
<head>
<title>通过表单参数值设置Bean属性值</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
<body>
<form action="" method="post">
<br>
输入产品名称:<input name="product_name1"/><br/>
输入产品编号:<input name="product_id1"/><br/>
输入产品价格:<input name="price1"/><br/>
输入产品信息:<input name="info1"/><br/>
<input type="submit" value="提交"/>
</form>
<!-- 设置产品名称 -->
<jsp:setProperty name="product" property="product_name" param="product_name1"/>
<br/>产品名称是:
<!-- 获取产品名称 -->
<%=product.getProduct_name() %>
<!-- 设置产品编号 -->
<jsp:setProperty name="product" property="product_id" param="product_id1"/>
<br/>产品编号是:
<!-- 获取产品编号 -->
<%=product.getProduct_id() %>
<!-- 设置产品价格 -->
<jsp:setProperty name="product" property="price" param="price1"/>
<br/>产品价格是:
<!-- 获取产品价格 -->
<%=product.getPrice() %>
<!-- 设置产品信息 -->
<jsp:setProperty name="product" property="info" param="info1"/>
<br/>产品信息是:
<!-- 获取产品信息 -->
<%=product.getInfo() %>
</body>
</html>
取得属性: < < <jsp:getProperty > > >。在例9.1中有例子。
Bean的作用域
Bean的request生命周期
package com.eshore.pojo;
import java.io.Serializable;
public class Circle implements Serializable{
private static final long serialVersionUID = 1L;
private double radius =1.0d; //半径
private double circleArea = 0.0d; //圆面积
private double circumference=0.0d; //圆周长
public Circle() {
//无参的构造方法
super();
// TODO Auto-generated constructor stub
}
//属性的get和set方法
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getCircleArea() {
circleArea = Math.PI*radius*radius;//设置圆面积
return circleArea;
}
public void setCircleArea(double circleArea) {
this.circleArea = circleArea;
}
public double getCircumference() {
circumference = 2*Math.PI*radius;//设置圆周长
return circumference;
}
public void setCircumference(double circumference) {
this.circumference = circumference;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="circle" class="com.eshore.pojo.Circle" scope="request"/>
<!DOCTYPE HTML >
<html>
<head>
<title>测试scope为request</title>
</head>
<%
//获取页面获得的圆半径,如果没有默认是1
String radius = request.getParameter("radius");
if(radius==null||radius.equals("")){
radius = "1";
}
double rad = Double.parseDouble(radius);
//设置圆半径
circle.setRadius(rad);
%>
<body>
<form action="" method="post">
请输入圆的半径:<input name="radius"/><br/>
<input type="submit" value="提交"/><br/>
该Bean类对象为:<%=circle.toString()%><br/>
<br/>圆的半径为:<jsp:getProperty property="radius" name="circle"/>
<br/>圆的周长为:<jsp:getProperty property="circumference" name="circle"/>
<br/>圆的面积为:<jsp:getProperty property="circleArea" name="circle"/>
</form>
</body>
</html>
设置request时,表示该Bean对当前用户的当前请求有效。
演示Bean的Page生命周期:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="circle" class="com.eshore.pojo.Circle" scope="page"/>
<!DOCTYPE HTML >
<html>
<head>
<title>测试scope为page</title>
</head>
<body>
pageScope.jsp页面信息:<br/>
该Bean类对象为:<%=circle.toString()%><br/>
设置该Bean的半径为20:
<%
circle.setRadius(20);
%>
<!-- 获取Bean的属性值,该Bean只在当前页有效 -->
<br/>圆的半径为:<jsp:getProperty property="radius" name="circle"/>
<br/>圆的周长为:<jsp:getProperty property="circumference" name="circle"/>
<br/>圆的面积为:<jsp:getProperty property="circleArea" name="circle"/>
<!-- 跳转pageScope2.jsp页面 -->
<form action="pageScope2.jsp" method="get">
<input type="submit" value="跳转pageScope2.jsp页面"/><br/>
</form>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="circle" class="com.eshore.pojo.Circle" scope="page"/>
<!DOCTYPE HTML >
<html>
<head>
<title>测试scope为page</title>
</head>
<body>
pageScope2.jsp页面信息:<br/>
该Bean类对象为:<%=circle.toString()%><br/>
<!--这里的半径是circle类中初始化的半径,因为该Bean只在当前页有效-->
<br/>圆的半径为:<jsp:getProperty property="radius" name="circle"/>
<br/>圆的周长为:<jsp:getProperty property="circumference" name="circle"/>
<br/>圆的面积为:<jsp:getProperty property="circleArea" name="circle"/>
</body>
</html>
演示Bean的session生命周期:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="circle" class="com.eshore.pojo.Circle" scope="session"/>
<!DOCTYPE HTML >
<html>
<head>
<title>测试scope为session</title>
</head>
<body>
sessionScope.jsp页面信息:<br/>
该Bean类对象为:<%=circle.toString()%><br/>
.toString()%><br/>
设置该Bean的半径为20:
<%
circle.setRadius(20);
%>
<!-- 获取Bean的属性值 -->
<br/>圆的半径为:<jsp:getProperty property="radius" name="circle"/>
<br/>圆的周长为:<jsp:getProperty property="circumference" name="circle"/>
<br/>圆的面积为:<jsp:getProperty property="circleArea" name="circle"/>
<!-- 跳转sessionScope2.jsp页面 -->
<form action="sessionScope2.jsp" method="get">
<input type="submit" value="跳转sessionScope2.jsp页面"/><br/>
</form>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="circle" class="com.eshore.pojo.Circle" scope="session"/>
<!DOCTYPE HTML >
<html>
<head>
<title>测试scope为session</title>
</head>
<body>
sessionScope2.jsp页面信息:<br/>
该Bean类对象为:<%=circle.toString()%><br/>
<br/>圆的半径为:<jsp:getProperty property="radius" name="circle"/>
<br/>圆的周长为:<jsp:getProperty property="circumference" name="circle"/>
<br/>圆的面积为:<jsp:getProperty property="circleArea" name="circle"/>
</body>
</html>
虽然跳转了页面,但是在同一个session。
演示Bean的application生命周期:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入引用的bean -->
<jsp:useBean id="circle" class="com.eshore.pojo.Circle" scope="application"/>
<!DOCTYPE HTML >
<html>
<head>
<title>测试scope为application</title>
</head>
<body>
applicationScope.jsp页面信息:<br/>
application访问Bean类对象为:<%=circle.toString()%><br/>
获取Bean的半径:<jsp:getProperty property="radius" name="circle"/><br/>
设置该Bean的半径为30:
<%
circle.setRadius(30);
%>
<%--<jsp:setProperty name="circle2" property="radius" value="30"/>--%>
<!-- 获取Bean的属性值 -->
<br/>圆的半径为:<jsp:getProperty property="radius" name="circle"/>
<br/>圆的周长为:<jsp:getProperty property="circumference" name="circle"/>
<br/>圆的面积为:<jsp:getProperty property="circleArea" name="circle"/>
</body>
</html>
刷新界面,发现更改被保留了下来:
DAO设计模式
首先创建表:
建立db包,该包 下建立DBConnection类来建立连接池:
package com.eshore.db;
import java.sql.Connection;
import java.sql.DriverManager;
public class DBConnection {
//加载MySQL数据库固定的Driver和URL,mydb是我建表的数据库
private static final String Driver = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/mydb";
private static final String USER = "root";
private static final String PASSWORD = "1234";
private Connection conn = null;
public DBConnection() throws Exception {
//进行数据库连接
try {
Class.forName(Driver); //用反射加载数据库驱动
this.conn = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (Exception e) {
throw e; // 抛出异常
}
}
public Connection getConnection() {
return this.conn; // 取得数据库连接
}
public void close() throws Exception {
// 关闭数据库
if (this.conn != null) {
try {
this.conn.close();
} catch (Exception e) {
throw e;
}
}
}
}
设计DAO接口类,建立DAO包,建立ProductDao类:
package com.eshore.dao;
import java.util.List;
import com.eshore.pojo.Product;
public interface ProductDao {
/**
*数据库 新增数据
*@param product 要增加的数据对象
*@return 是否增加成功的的标记
*@throws Exception 如果有异常,将直接抛出
*/
public boolean addProduct(Product product)throws Exception ;
/**
*查询全部的Product数据
*@param product_name 产品名称
*@return 返回全部的查询结果,每一个product表示表的一行记录
*@throws Exception 如果有异常,将直接抛出
*/
public List<Product> findAll(String product_name)throws Exception;
/**
* 根据产品编号查询产品
*@param product_id 产品编号
*@return 产品的vo对象
*@throws Exception 如果有异常,将直接抛出
*/
public Product findByProductId(String product_id)throws Exception;
}
数据操作实现类,在DAO中建立ProductDaoImpl类:
package com.eshore.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.eshore.pojo.Product;
public class ProductDaoImpl implements ProductDao {
private Connection conn = null; // 数据库连接对象
private PreparedStatement pstmt = null; // 数据库操作对象
// 通过构造方法取得数据库的链接
public ProductDaoImpl(Connection conn) {
this.conn = conn;
}
public boolean addProduct(Product product) throws Exception {
boolean flag = false; // 定义标识
String sql = "insert into product(product_id,product_name,price,info) values(?,?,?,?)";
this.pstmt = this.conn.prepareStatement(sql);// 实例化PrepareStatement对象
this.pstmt.setString(1,product.getProduct_id());// 设置产品id
this.pstmt.setString(2,product.getProduct_name());// 设置产品名称
this.pstmt.setDouble(3, product.getPrice());// 设置产品价格
this.pstmt.setString(4,product.getInfo());// 设置产品信息
if (this.pstmt.executeUpdate() > 0) {
// 更新记录的行数大于0
flag = true; //修改标识
}
this.pstmt.close(); // 关闭PreparedStatement操作
return flag;
}
public List<Product> findAll(String product_name) throws Exception {
List<Product> list = new ArrayList<Product>();// 定义集合,接收返回的数据
String sql = "select product_id,product_name,price,info from product ";
if(product_name!=null&&!"".equals(product_name)){
sql = "select product_id,product_name,price,info from product where product_name like? ";
this.pstmt = this.conn.prepareStatement(sql);// 实例化PreparedStatement
this.pstmt.setString(1, "%" + product_name + "%");// 设置产品查询的名称
}else{
this.pstmt = this.conn.prepareStatement(sql);// 实例化PreparedStatement
}
ResultSet rs = this.pstmt.executeQuery();// 执行查询操作
Product product = null;
while (rs.next()) {
product = new Product();// 实例化新的product对象
product.setProduct_id(rs.getString(1));
product.setProduct_name(rs.getString(2));
product.setPrice(rs.getDouble(3));
product.setInfo(rs.getString(4));
list.add(product); // 向集合中增加product对象
}
this.pstmt.close();
return list; // 返回全部结果
}
public Product findByProductId(String product_id) throws Exception {
Product product = null;
String sql = "select product_id,product_name,price,info from product where product_id=?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, product_id); // 设置产品编号
ResultSet rs = this.pstmt.executeQuery();
if (rs.next()) {
product = new Product();
product.setProduct_id(rs.getString(1));
product.setProduct_name(rs.getString(2));
product.setPrice(rs.getDouble(3));
product.setInfo(rs.getString(4));
}
this.pstmt.close();
return product; // 如果查询不到结果,则返回null,默认值为null
}
}
在上述代码中的数据操作实现类中没有针对数据库的打开和连接操作,只是由构造方法取得连接的数据库,而针对数据库的打开和关闭由业务操作实现类完成,建立一个service包,在该包下建立一个ProductService类:
package com.eshore.service;
import java.util.List;
import com.eshore.dao.ProductDao;
import com.eshore.dao.ProductDaoImpl;
import com.eshore.db.DBConnection;
import com.eshore.pojo.Product;
public class ProductService implements ProductDao{
private DBConnection dbconn = null; // 定义数据库连接类
private ProductDao dao = null; // 声明DAO对象
// 在构造方法中实例化数据库连接,同时实例化dao对象
public ProductService() throws Exception {
this.dbconn = new DBConnection();
this.dao = new ProductDaoImpl(this.dbconn.getConnection());// 实例化ProductDao的实现类
}
public boolean addProduct(Product product) throws Exception {
boolean flag = false; // 标识
try {
if (this.dao.findByProductId(product.getProduct_id()) == null) {
// 如果插入的产品编号不存在
flag = this.dao.addProduct(product);// 新增一条产品信息
}
} catch (Exception e) {
throw e;
} finally {
this.dbconn.close();
}
return flag;
}
public List<Product> findAll(String keyWord) throws Exception {
List<Product> all = null; // 定义产品返回的集合
try {
all = this.dao.findAll(keyWord);// 调用实现方法
} catch (Exception e) {
throw e;
} finally {
this.dbconn.close();
}
return all;
}
public Product findByProductId(String product_id) throws Exception {
Product product = null;
try {
product = this.dao.findByProductId(product_id);
} catch (Exception e) {
throw e;
} finally {
this.dbconn.close();
}
return product;
}
}
定义DAO工厂类,来获得业务操作类,在后续的客户端中就可以直接通过工厂类获得DAO接口的实例对象,建立factory包,在该包下建立DAOFactory类:
package com.eshore.factory;
import com.eshore.dao.ProductDao;
import com.eshore.service.ProductService;
public class DAOFactory {
public static ProductDao getIEmpDAOInstance()throws Exception {
return new ProductService();//取得业务操作类
}
}
测试添加产品类TestInsertProduct:
package com.eshore.test;
import com.eshore.factory.DAOFactory;
import com.eshore.pojo.Product;
public class TestInsertProduct {
public static void main(String[] args){
Product product = null;
try{
for(int i=0;i<5;i++){
product = new Product();
product.setProduct_id("350115001010"+i);
product.setProduct_name("水杯"+i);
product.setPrice(100+i);
product.setInfo("这是一个精美的被子"+i);
DAOFactory.getIEmpDAOInstance().addProduct(product);
}
}catch(Exception e){
e.printStackTrace();
e.printStackTrace();
}
}
}
运行测试的Java程序:
JSP中调用DAO
在JSP中增加产品信息:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML >
<html>
<head>
<title>添加产品信息</title>
</head>
<body>
<form action="product_insert.jsp" method="post">
产品编号:<input name="product_id"/><br>
产品名称:<input name="product_name"/><br>
产品价格:<input name="price"/><br>
产品信息:<textarea rows="" cols="" name="info"></textarea><br/>
<input type="submit" value="添加">
<input type="reset" value="重置">
</form>
</body>
</html>
<%@ page import="java.util.*,com.eshore.pojo.Product" pageEncoding="UTF-8"%>
<%@ page import="com.eshore.factory.DAOFactory" %>
<%
request.setCharacterEncoding("utf-8");//解决中文乱码
%>
<!DOCTYPE HTML >
<html>
<head>
<title>执行添加产品</title>
</head>
<body>
<%
Product product = new Product(); //实例化Product对象
product.setProduct_id(request.getParameter("product_id"));
product.setProduct_name(request.getParameter("product_name"));
product.setPrice(Double.parseDouble(request.getParameter("price")));
product.setInfo(request.getParameter("info"));
boolean flag = DAOFactory.getIEmpDAOInstance().
addProduct(product); //执行添加操作
if(flag){
%>
<h4>添加产品信息成功</h4>
<%
}else{
%>
<h4>添加产品信息失败</h4>
<%} %>
</body>
</html>
在JSP中查询产品信息:
<%@ page import="java.util.*,com.eshore.pojo.Product" pageEncoding="UTF-8"%>
<%@ page import="com.eshore.factory.DAOFactory" %>
<%
request.setCharacterEncoding("utf-8");//解决中文乱码
%>
<!DOCTYPE HTML >
<html>
<head>
<title>查询产品列表</title>
</head>
<body>
<%
String product_name = request.getParameter("product_name");//
List<Product> list = DAOFactory.getIEmpDAOInstance().findAll(product_name);
%>
<form action="product_list.jsp" method="post">
请输入产品名称:<input name="product_name"/>
<input type="submit" value="提交">
</form>
<table border="1">
<tr>
<td>产品编号</td>
<td>产品名称</td>
<td>产品价格</td>
<td>产品信息</td>
</tr>
<%
for(int i=0;i<list.size();i++){
Product p = list.get(i); //取出每一个产品
%>
<tr>
<td><%=p.getProduct_id() %></td>
<td><%=p.getProduct_name() %></td>
<td><%=p.getPrice() %></td>
<td><%=p.getInfo() %></td>
</tr>
<%} %>
</table>
</body>
</html>