1.查询全部商品
1.1搭建项目环境
1.创建Dynamic Web Project项目,名称为day42
2.打开mysql,将案例所需资料db.sql复制进去,生成category,product两张表
3.修改c3p0配置文件,保存JDBCUtils正确性
4.创建模块程序
1.2功能分析
1.效果图
用户输入网址localhost:8080/day42,敲回车向服务端发起请求
服务端响应到浏览器的如下结果
2.执行流程分析
1.3步骤实现
1.web项目配置单独首页
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
2.index.jsp通过JSP动作实现转发
请求转发不需要加项目名
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:forward page="/ProductServlet"></jsp:forward>
3.实现ProductServlet中代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用业务层功能:查询全部商品,返回集合<Product>
ProductService productService = new ProductService();
List<Product> list = null;
try {
list = productService.findAllProducts();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//将查询到的全部商品放入request
request.setAttribute("allProducts", list);
//转发到/product_list.jsp页面,完成响应
request.getRequestDispatcher("/product_list.jsp").forward(request, response);
}
4.实现ProductService代码
public List<Product> findAllProducts() throws SQLException {
ProductDao productDao = new ProductDao();
return productDao.findAllProducts();
}
5.实现ProductDao代码
public List<Product> findAllProducts() throws SQLException {
String sql = "select * from product";
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
return qr.query(sql, new BeanListHandler<Product>(Product.class));
}
此处要注意,Product类需要提供无参构造,因为会通过反射调用无参来构建Product实例
此时会报这个错误:不能创建Product类
java.sql.SQLException: Cannot create cn.itcast.domain.Product: cn.itcast.domain.Product Query: select * from product Parameters: []
6.实现product_list.jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>显示全部商品信息</title>
</head>
<body>
<table border="1" width="80%" align="center">
<tr>
<th>序号</th>
<th>商品名称</th>
<th>市场价格</th>
<th>商场价格</th>
<th>图片</th>
<th>上架时间</th>
<th>是否热门</th>
<th>商品描述</th>
<th>是否有货</th>
</tr>
<!-- -->
<c:if test="${empty allProducts}">
<tr><td colspan="9">暂无商品信息</td></tr>
</c:if>
<c:if test="${not empty allProducts}">
<c:forEach items="${allProducts}" var="p" varStatus="status">
<tr>
<td>${status.count}</td>
<td>${p.pname}</td>
<td>${p.market_price}</td>
<td>${p.shop_price}</td>
<td><img src="${pageContext.request.contextPath}/${p.pimage}" width="50px"></td>
<td>${p.pdate}</td>
<td>${p.is_hot == 1?"是":"否"}</td>
<td>${p.pdesc}</td>
<td>${p.pflag == 0?"未下架":"已下架"}</td>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>
2.查询全部分类
2.1功能分析
效果图:用户点击添加商品链接,向服务端发起请求,跳转到addProduct.jsp页面
服务端响应一个添加商品的页面,页面中有查询到的分类信息
2.2流程图
2.3代码实现
1.新增"添加商品"链接
在Product_list.jsp中新增"添加商品"链接,此链接并不直接请求addProduct.jsp,而是先请求CategoryServlet,获取到分类信息,将信息保存到request以后请求转发到addProduct.jsp
<center><a href="/day42/CategoryServlet">添加商品</a></center>
2.实现CategoryServlet
3.实现CategoryService
4.实现CategoryDao
5.实现Cateogry
步骤2-5可以参考Product
3.添加商品功能
3.1 效果图
用户在表单中录入数据,选择好商品对应的分类信息,点击提交向服务端发起请求
服务端接收到请求之后,调用服务端功能之后,再次向客户端响应回所有的商品信息
3.2 流程图分析
3.3 代码实现
1.product_add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>增加商品</title>
</head>
<body>
<!-- 请求路径属于服务器外跳转,所以需要写上项目名 -->
<form method="post" action="${pageContext.request.contextPath}/Product_addServlet">
<table border="1" width="50%" align="center">
<tr><td>商品名称:<input type="text" name="pname"/></td></tr>
<tr><td>市场价格:<input type="text" name="market_price"/></td></tr>
<tr><td>商城价格:<input type="text" name="shop_price"/></td></tr>
<tr><td>商品图片:<input type="text" name="pimage" value="products/1/c_0004.jpg"/></td></tr>
<tr><td>是否热门:
<input type="radio" name="is_hot" value="1" checked="checked"/>是
<input type="radio" name="is_hot" value="0"/>否</td></tr>
<tr><td>商品描述:<textarea cols="20" rows="10" name="pdesc"></textarea></td></tr>
<tr><td>是否有货:
<input type="radio" name="pflag" value="0" checked="checked"/>是
<input type="radio" name="pflag" value="1"/>否</td></tr>
<tr><td>所属分类
<select name="cid">
<c:forEach items="${allCats}" var="c">
<option value="${c.cid}">${c.cname}</option>
</c:forEach>
</select></td></tr>
<tr><td><button>添加</button></td></tr>
</table>
</form>
</body>
</html>
2.Product_addServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//接收表单参数
Product product = MyBeanUtils.populate(Product.class, request.getParameterMap());
product.setPid(UUIDUtil.getUUID());
product.setPdate(new Date());
//调用业务层功能:添加商品
ProductService productService = new ProductService();
try {
productService.addProduct(product);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*//重定向到项目首页
response.sendRedirect("/day42");*/
//
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
3.ProductService
public void addProduct(Product product) throws SQLException {
ProductDao productDao = new ProductDao();
productDao.addProduct(product);
}
4.ProductDao
public void addProduct(Product product) throws SQLException {
String sql = "INSERT INTO product VALUES (?,?,?,?,?,?,?,?,?,?)";
Object[] params = {product.getPid(),product.getPname(),product.getMarket_price()
,product.getShop_price(),product.getPimage(),product.getPdate()
,product.getIs_hot(),product.getPdesc(),product.getPflag(),product.getCid()};
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
qr.update(sql, params);
}
注意:本案例如果在添加商品成功之后,不能使用请求转发到index.jsp,而应该用重定向
原因:重定向到index.jsp后,显示的路径是http://localhost:8081/day42/,刷新页面(重新发起请求)也不会造成什么问题,而使用了转发,显示的路径是http://localhost:8081/day42/Product_addServlet,当我们刷新页面时,就会给Product_addServlet发起一个不携带任何请求参数的get请求,会导致数据的重复提交
4.查询一件商品信息
4.1 功能分析
用户点击修改链接,会将待修改商品的pid发送到服务端
服务端接收到商品的pid,在数据库中找到商品信息,响应到客户端
4.2 执行流程
4.3 代码实现
1.修改Product_list.jsp,新增修改链接
在url中,EL表达式和字符串不需要+号就能能拼接,此处的${pageContext.request.contextPath}表示本项目路径,即/day42
<td><a href="${pageContext.request.contextPath}/Product_findOneProductServlet?pid=${p.pid}">修改</a></td>
2.实现Product_findOneProductServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收待删除商品的pid
String pid = request.getParameter("pid");
ProductService productService = new ProductService();
CategoryService categoryService = new CategoryService();
Product product = null;
List<Category> categorys = null;
try {
//2.调用业务层方法,获取pid对应的商品信息,返回product对象
product = productService.findOneProduct(pid);
//3.调用业务层方法,查询全部分类,返回category集合
categorys = categoryService.findAllCategorys();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//4.如果执行sql报错,查询到的结果为null
request.setAttribute("product", product);
request.setAttribute("allCats", categorys);
//5.转发到product_info.jsp
request.getRequestDispatcher("/product_info.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
3.实现ProductService
public Product findOneProduct(String pid) throws SQLException {
ProductDao productDao = new ProductDao();
return productDao.findOneProduct(pid);
}
4.实现ProductDao
public Product findOneProduct(String pid) throws SQLException {
String sql = "select * from product where pid = ?";
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
return qr.query(sql, new BeanHandler<Product>(Product.class),pid);
}
5.实现Product_info.jsp
注意点:在显示所属分类时,不能简单的遍历Category集合,比如我们查找的是一款手机,那么在所属分类时,默认选中的得是手机数码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>增加商品</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/Product_updateServlet">
<table border="1" width="50%" align="center">
<tr><td>商品名称:<input type="text" name="pname" value="${product.pname}"/></td></tr>
<tr><td>市场价格:<input type="text" name="market_price" value="${product.market_price}"/></td></tr>
<tr><td>商城价格:<input type="text" name="shop_price" value="${product.shop_price}"/></td></tr>
<tr><td>商品图片:<input type="text" name="pimage" value="${product.pimage}"/></td></tr>
<tr><td>是否热门:
<c:if test="${product.is_hot == 1}">
<input type="radio" name="is_hot" value="1" checked="checked"/>是
<input type="radio" name="is_hot" value="0"/>否
</c:if>
<c:if test="${product.is_hot != 1}">
<input type="radio" name="is_hot" value="1"/>是
<input type="radio" name="is_hot" value="0" checked="checked"/>否
</c:if>
</td></tr>
<tr><td>商品描述:<textarea cols="20" rows="10" name="pdesc">${product.pdesc}</textarea></td></tr>
<tr>
<td>是否有货:
<c:if test="${product.pflag == 0}">
<input type="radio" name="pflag" value="0" checked="checked"/>是
<input type="radio" name="pflag" value="1"/>否
</c:if>
<c:if test="${product.pflag != 0}">
<input type="radio" name="pflag" value="0" />是
<input type="radio" name="pflag" value="1" checked="checked"/>否
</c:if>
</td>
</tr>
<tr><td>所属分类
<input type="hidden" name="pid" value="${product.pid}"/>
<select name="cid">
<c:forEach items="${allCats}" var="c">
<c:if test="${product.cid == c.cid}">
<option selected="selected" value="${c.cid}">${c.cname}</option>
</c:if>
<c:if test="${product.cid != c.cid}">
<option value="${c.cid}">${c.cname}</option>
</c:if>
</c:forEach>
</select></td></tr>
<tr><td><button>修改</button></td></tr>
</table>
</form>
</body>
</html>
5.修改商品信息
5.1 效果图
1.用户录入待修改的商品信息,点击修改按钮向服务端发起请求
2.服务端接收到表单参数后,调用修改功能,向客户端浏览器显示修改后的商品界面信息
5.2 流程图
5.3 代码实现
1.实现Product_updateServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收表单参数
request.setCharacterEncoding("utf-8");
Product product = MyBeanUtils.populate(Product.class, request.getParameterMap());
//2.调用业务层功能:修改商品
ProductService productService = new ProductService();
try {
productService.updateProduct(product);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//3.重定向到首页
response.sendRedirect("/day42");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
2.实现ProductService
public void updateProduct(Product product) throws SQLException {
ProductDao productDao = new ProductDao();
productDao.updateProduct(product);
}
3.实现ProductDao
public void updateProduct(Product product) throws SQLException {
String sql = "UPDATE product SET pname = ? , market_price =? ,shop_price = ? "
+ ", pimage =? , is_hot =? , pdesc= ? , pflag = ? ,cid= ? WHERE pid= ?";
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
Object[] params={product.getPname(),
product.getMarket_price(),product.getShop_price(),
product.getPimage(),product.getIs_hot(),product.getPdesc(),
product.getPflag(),product.getCid(),product.getPid()};
qr.update(sql,params);
}
6.删除商品
6.1 效果图
用户点击删除商品链接,触发js弹框,确认用户在做删除操作
用户点击确定,向服务端发起请求,将待删除商品的PID发送到服务端
服务端接收待删除商品的PID之后,调用服务端功能,向客户端响应会全部商品信息
6.2 流程图
6.3 代码实现
1.添加删除链接
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>显示全部商品信息</title>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
</head>
<body>
<table border="1" width="80%" align="center">
<tr>
<th>序号</th>
<th>商品名称</th>
<th>市场价格</th>
<th>商场价格</th>
<th>图片</th>
<th>上架时间</th>
<th>是否热门</th>
<th>商品描述</th>
<th>是否有货</th>
<th>修改</th>
<th>删除</th>
</tr>
<!-- -->
<c:if test="${empty allProducts}">
<tr><td colspan="9">暂无商品信息</td></tr>
</c:if>
<c:if test="${not empty allProducts}">
<c:forEach items="${allProducts}" var="p" varStatus="status">
<tr>
<td>${status.count}</td>
<td>${p.pname}</td>
<td>${p.market_price}</td>
<td>${p.shop_price}</td>
<td><img src="${pageContext.request.contextPath}/${p.pimage}" width="50px"></td>
<td>${p.pdate}</td>
<td>${p.is_hot == 1?"是":"否"}</td>
<td>${p.pdesc}</td>
<td>${p.pflag == 0?"未下架":"已下架"}</td>
<td><a href="" id="delPro">修改</a></td>
<td>
<a href="" class="delPro" id= "${p.pid}" title="${p.pid}">删除</a>
<input type="hidden" value="${p.pid}">
</td>
</tr>
</c:forEach>
</c:if>
</table>
<center><a href="/day42/CategoryServlet">添加商品</a></center>
</body>
<script>
$(function(){
//错误的写法,id选择器只能选择页面一个标签
//$("#delPro").click(function(){alert("TTT")})
//页面加载完毕后,为删除链接绑定点击事件,class选择器
/* $(".delPro").click(function(){
alert("TTT")
}) */
//选择内容中包含删除的a链接
$("a:contains('删除')").click(function(){
if(confirm("忍心删除?")){
//alert(this.id);
//alert(this.title);
var pid = $(this).next().val();
location.href="/day42/Product_delServlet?pid="+pid;
}
})
});
</script>
</html>
注意:.location.href在IE中支持,但是在谷歌浏览器中不跳转。解决方法就很简单。在事件中加return false来阻止冒泡
$("a:contains('删除')").click(function(){
if(confirm("忍心删除?")){
//alert(this.id);
//alert(this.title);
var pid = $(this).next().val();
location.href="/day42/Product_delServlet?pid="+pid;
return false;
}
})
2.实现Product_delServlet
3.实现ProductService
4.实现ProductDao
2-4步骤参考之前