day4
1 . 模块分析
案例1-我的订单
需求: 在任意页面上,点击 "我的订单" 将当前用户的订单(包含订单项列表)分页展示出来
步骤分析:
1.修改 head.jsp 上"我的订单"的连接 /store/order?method=findMyOrdersByPage&pageNumber=1
2.在orderservlet中编写 findMyOrdersByPage
获取pagenumber 设置pagesize 获取当前用户的id
调用service完成分页查询操作:返回pagebean
将pagebean放入request域中,请求转发 order_list.jsp
3. service中操作 创建pagebean 设置总条数 设置当前页数据
4. dao中操作: 获取当前页订单数据
sql:只能查询订单的基本信息,没有订单项
select * from orders where uid = ? order by ordertime desc limit ?,?
执行上面的sql,返回的 List<Order>
遍历orderlist集合,获取到每一个订单,关联查询订单项和商品表,将该订单下的所有信息查询出来,
封装成orderItem,将每一个orderitem放入当前order的订单项列表中
SELECT * FROM orderitem oi,product p WHERE oi.pid = p.pid AND oi.oid = '8727C1B22C214E6D865ECFB3B118E330'
上面的结果用什么封装???
使用maplisthandler封装, 将查询结果的每一条记录封装成map
( key:字段名(和bean属性名一样),value:具体指),将所有的map放入list中返回
遍历map的list,获取每一个订单的详情,使用beanutils进行封装即可 封装orderitem和product对象,
最后将orderitem对象放入订单项列表中
[{itemid=xxxx,pname=华为,...},{itemid=uyyyyx,pname=中兴,...}]
案例2-订单详情
需求:
在订单列表页面上点击 "去付款",展示出当前的订单的详情.
步骤分析:
1.修改 "去付款" 连接 /store/order?method=getById&oid=xxxx
2.在orderservlet编写getById方法
获取oid
调用service查询单个订单 返回值:order
将order放入request域中,请求转发到order_info.jsp
3.service中操作
4.dao中操作
先查询订单信息(没有订单项)
select * from orders where oid = ?
再查询当前订单的订单项
select * from orderitem oi,product p where oi.pid = p.pid and oi.oid=?
使用maplisthandler进行封装
获取每一个订单项详情,封装成orderitem,最后将orderitem添加到订单的订单项列表项即可
案例3-在线支付
需求:
在详情页面上 输入收货人信息,选择支付的银行,点击确认订单,保存收获人信息,跳转到银行页面,输入用户名(卡号),点击支付,
最后跳转到商城,提示 订单支付成功,(修改订单的状态)
技术分析:
在线支付在线支付:
1.对银行 2.对第三方
注:在线支付注意问题:
1. 给第三方支付那些数据和第三方返回给用户和商城的数据有那些?
2. 如何保证数据的有效性? 电子签名
3. 商城将发给第三方的数据经过算法和密钥进行加密(不可逆),生成一个字符串,将原始的数据和加密后生成的字符串一并发送给第三方.
4. 第三方拿到数据之后,将原来的数据使用同样的算法和密码重新生成一个字符串,
5. 将其和商城发送过来的加密后的字符串进行比对,若数据是一样的,则证明数据没有被篡改过.
6. 商城开户: 商户编码 密钥 算法 要到易宝支付申请
支付步骤的分析:
1.在订单详情页面上 填写收货人信息, 选择支付银行,点击"确认订单",向商城发送请求
表单提交 收货人信息 支付银行 订单号 路径: /store/order?method=pay
2.在orderservlet中 编写pay方法 接受收货人信息 订单号
调用service获取订单, 设置收货人信息 更新订单
拼接重定向的字符串
支付成功之后的步骤分析:
编写callback方法
获取第三方发送过来的数据(order_id)
通过id获取订单
修改订单的状态 =1
更新订单
案例4-权限过滤
需求: 访问购物车的时候,需要判断用户是否登录,若没有登录,则提示
技术分析: 过滤器
过滤器编写步骤:
1.编写一个类 PrivilegeFilter 实现filter接口 重写方法(主要doFilter)
2.编写配置文件 filter filter-mapping
步骤分析:
1. doFilter方法中的逻辑
从session中获取用户,
判断用户是否为空
若为空: 提示"请先登录",请求转发到 /jsp/msg.jsp return
2.代码区
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>会员登录</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css" type="text/css" /> <script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js" type="text/javascript"></script> <script src="${pageContext.request.contextPath}/js/bootstrap.min.js" type="text/javascript"></script> <!-- 引入自定义css文件 style.css --> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css" /> <style> body { margin-top: 20px; margin: 0 auto; } .carousel-inner .item img { 100%; height: 300px; } </style> </head> <body> <%@include file="/jsp/head.jsp" %> <div class="container"> <div class="row"> <div style="margin:0 auto;margin-top:10px;950px;"> <strong>订单详情</strong> <table class="table table-bordered"> <tbody> <tr class="warning"> <th colspan="2">订单编号:${bean.oid } </th> <th colspan="1"> <c:if test="${bean.state == 0 }">去付款</c:if> <c:if test="${bean.state == 1 }">已付款</c:if> <c:if test="${bean.state == 2 }">确认收货</c:if> <c:if test="${bean.state == 3 }">已完成</c:if> </th> <th colspan="2">时间:<fmt:formatDate value="${bean.ordertime }" pattern="yyyy-MM-dd HH:mm:ss"/> </th> </tr> <tr class="warning"> <th>图片</th> <th>商品</th> <th>价格</th> <th>数量</th> <th>小计</th> </tr> <c:forEach items="${bean.items }" var="oi"> <tr class="active"> <td width="60" width="40%"> <input type="hidden" name="id" value="22"> <img src="${pageContext.request.contextPath}/${oi.product.pimage}" width="70" height="60"> </td> <td width="30%"> <a target="_blank">${oi.product.pname}</a> </td> <td width="20%"> ¥${oi.product.shop_price} </td> <td width="10%"> ${oi.count} </td> <td width="15%"> <span class="subtotal">¥${oi.subtotal}</span> </td> </tr> </c:forEach> </tbody> </table> </div> <div style="text-align:right;margin-right:120px;"> 商品金额: <strong style="color:#ff6600;">¥${bean.total }元</strong> </div> </div> <div> <hr/> <form action="${pageContext.request.contextPath }/order" id="orderForm" method="post" class="form-horizontal" style="margin-top:5px;margin-left:150px;"> <!-- 提交的方法 --> <input type="hidden" name="method" value="pay"> <!-- 订单号 --> <input type="hidden" name="oid" value="${bean.oid }"> <div class="form-group"> <label for="username" class="col-sm-1 control-label">地址</label> <div class="col-sm-5"> <input type="text" name="address" class="form-control" id="username" placeholder="请输入收货地址"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-1 control-label">收货人</label> <div class="col-sm-5"> <input type="text" name="name" class="form-control" id="inputPassword3" placeholder="请输收货人"> </div> </div> <div class="form-group"> <label for="confirmpwd" class="col-sm-1 control-label">电话</label> <div class="col-sm-5"> <input type="text" name="telephone" class="form-control" id="confirmpwd" placeholder="请输入联系方式"> </div> </div> <hr/> <div style="margin-top:5px;margin-left:150px;"> <strong>选择银行:</strong> <p> <br/> <input type="radio" name="pd_FrpId" value="ICBC-NET-B2C" checked="checked" />工商银行 <img src="${pageContext.request.contextPath}/bank_img/icbc.bmp" align="middle" /> <input type="radio" name="pd_FrpId" value="BOC-NET-B2C" />中国银行 <img src="${pageContext.request.contextPath}/bank_img/bc.bmp" align="middle" /> <input type="radio" name="pd_FrpId" value="ABC-NET-B2C" />农业银行 <img src="${pageContext.request.contextPath}/bank_img/abc.bmp" align="middle" /> <br/> <br/> <input type="radio" name="pd_FrpId" value="BOCO-NET-B2C" />交通银行 <img src="${pageContext.request.contextPath}/bank_img/bcc.bmp" align="middle" /> <input type="radio" name="pd_FrpId" value="PINGANBANK-NET" />平安银行 <img src="${pageContext.request.contextPath}/bank_img/pingan.bmp" align="middle" /> <input type="radio" name="pd_FrpId" value="CCB-NET-B2C" />建设银行 <img src="${pageContext.request.contextPath}/bank_img/ccb.bmp" align="middle" /> <br/> <br/> <input type="radio" name="pd_FrpId" value="CEB-NET-B2C" />光大银行 <img src="${pageContext.request.contextPath}/bank_img/guangda.bmp" align="middle" /> <input type="radio" name="pd_FrpId" value="CMBCHINA-NET-B2C" />招商银行 <img src="${pageContext.request.contextPath}/bank_img/cmb.bmp" align="middle" /> </p> <hr/> <p style="text-align:right;margin-right:100px;"> <a href="javascript:document.getElementById('orderForm').submit();"> <img src="${pageContext.request.contextPath}/images/finalbutton.gif" width="204" height="51" border="0" /> </a> </p> <hr/> </div> </div> </form> </div> <div style="margin-top:50px;"> <img src="${pageContext.request.contextPath}/image/footer.jpg" width="100%" height="78" alt="我们的优势" title="我们的优势" /> </div> <div style="text-align: center;margin-top: 5px;"> <ul class="list-inline"> <li><a>关于我们</a></li> <li><a>联系我们</a></li> <li><a>招贤纳士</a></li> <li><a>法律声明</a></li> <li><a>友情链接</a></li> <li><a target="_blank">支付方式</a></li> <li><a target="_blank">配送方式</a></li> <li><a>服务声明</a></li> <li><a>广告声明</a></li> </ul> </div> <div style="text-align: center;margin-top: 5px;margin-bottom:20px;"> Copyright © 2005-2016 传智商城 版权所有 </div> </body> </html>
package com.itheima.web.servlet; import java.io.IOException; import java.util.Date; import java.util.ResourceBundle; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.itheima.constant.Constant; import com.itheima.domain.Cart; import com.itheima.domain.CartItem; import com.itheima.domain.Order; import com.itheima.domain.OrderItem; import com.itheima.domain.PageBean; import com.itheima.domain.User; import com.itheima.service.OrderService; import com.itheima.utils.BeanFactory; import com.itheima.utils.PaymentUtil; import com.itheima.utils.UUIDUtils; import com.itheima.web.servlet.base.BaseServlet; /** * 订单模块 */ public class OrderServlet extends BaseServlet { private static final long serialVersionUID = 1L; /** * 获取订单详情 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String getById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //1.获取oid String oid = request.getParameter("oid"); //2.调用service 查询单个订单 OrderService os = (OrderService) BeanFactory.getBean("OrderService"); Order order = os.getById(oid); //3.请求转发 request.setAttribute("bean",order); } catch (Exception e) { e.printStackTrace(); request.setAttribute("msg", "查询订单详情失败"); return "/jsp/msg.jsp"; } return "/jsp/order_info.jsp"; } /** * 我的订单 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String findMyOrdersByPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //1.获取pageNumber 设置pagesize 获取userid int pageNumber = Integer.parseInt(request.getParameter("pageNumber")); int pageSize=3; User user=(User)request.getSession().getAttribute("user"); if(user == null){ //未登录 提示 request.setAttribute("msg", "请先登录"); return "/jsp/msg.jsp"; } //2.调用service获取当前页所有数据 pagebean OrderService os = (OrderService) BeanFactory.getBean("OrderService"); PageBean<Order> bean = os.findMyOrdersByPage(pageNumber,pageSize,user.getUid()); //3.将pagebean放入request域中,请求转发 order_list.jsp request.setAttribute("pb", bean); } catch (Exception e) { e.printStackTrace(); request.setAttribute("msg", "获取我的订单失败"); return "/jsp/msg.jsp"; } return "/jsp/order_list.jsp"; } /** * 保存订单 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String save(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //-1.从session中获取user User user=(User) request.getSession().getAttribute("user"); if(user == null){ //未登录 提示 request.setAttribute("msg", "请先登录!"); return "/jsp/msg.jsp"; } //0.获取购物车 Cart cart=(Cart) request.getSession().getAttribute("cart"); //1.封装订单对象 //1.1创建对象 Order order = new Order(); //1.2设置oid order.setOid(UUIDUtils.getId()); //1.3设置ordertime order.setOrdertime(new Date()); //1.4设置total 购物车中 order.setTotal(cart.getTotal()); //1.5设置state order.setState(Constant.ORDER_WEIFUKUAN); //1.6设置user order.setUser(user); //1.7设置items(订单项列表) 遍历购物项列表 for (CartItem ci : cart.getCartItems()) { //1.7.1封装成orderitem //a.创建orderitem OrderItem oi = new OrderItem(); //b.设置itemid uuid oi.setItemid(UUIDUtils.getId()); //c.设置count 从ci中获取 oi.setCount(ci.getCount()); //d.设置subtotal 从ci中获取 oi.setSubtotal(ci.getSubtotal()); //e.设置product 从ci中获取 oi.setProduct(ci.getProduct()); //f.设置order oi.setOrder(order); //1.7.2 将orderitem加入order 的items中 order.getItems().add(oi); } //2.调用orderservice完成保存操作 OrderService os = (OrderService) BeanFactory.getBean("OrderService"); os.save(order); //2.9 清空购物车 //request.getSession().getAttribute("cart") cart.clearCart(); //3.请求转发到 order_info.jsp request.setAttribute("bean", order); } catch (Exception e) { } return "/jsp/order_info.jsp"; } /** * 在线支付 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String pay(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取收获信息 获取oid 获取银行 //2.调用service获取订单 修改收获人信息 更新订单 //3.拼接给第三方的url //4.重定向 try { //接受参数 String address=request.getParameter("address"); String name=request.getParameter("name"); String telephone=request.getParameter("telephone"); String oid=request.getParameter("oid"); //通过id获取order OrderService s=(OrderService) BeanFactory.getBean("OrderService"); Order order = s.getById(oid); order.setAddress(address); order.setName(name); order.setTelephone(telephone); //更新order s.update(order); // 组织发送支付公司需要哪些数据 String pd_FrpId = request.getParameter("pd_FrpId"); String p0_Cmd = "Buy"; String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId"); String p2_Order = oid; String p3_Amt = "0.01"; String p4_Cur = "CNY"; String p5_Pid = ""; String p6_Pcat = ""; String p7_Pdesc = ""; // 支付成功回调地址 ---- 第三方支付公司会访问、用户访问 // 第三方支付可以访问网址 String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("responseURL"); String p9_SAF = ""; String pa_MP = ""; String pr_NeedResponse = "1"; // 加密hmac 需要密钥 String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue"); String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue); //发送给第三方 StringBuffer sb = new StringBuffer("https://www.yeepay.com/app-merchant-proxy/node?"); sb.append("p0_Cmd=").append(p0_Cmd).append("&"); // 业务类型 sb.append("p1_MerId=").append(p1_MerId).append("&");// 商户编号 sb.append("p2_Order=").append(p2_Order).append("&");//商户订单号 sb.append("p3_Amt=").append(p3_Amt).append("&");// 支付金额 sb.append("p4_Cur=").append(p4_Cur).append("&");// 交易币种 sb.append("p5_Pid=").append(p5_Pid).append("&");// 商品名称 sb.append("p6_Pcat=").append(p6_Pcat).append("&");// 商品种类 sb.append("p7_Pdesc=").append(p7_Pdesc).append("&");// 商品描述 sb.append("p8_Url=").append(p8_Url).append("&");// 商户接收支付成功数据的地址 sb.append("p9_SAF=").append(p9_SAF).append("&");// 送货地址 sb.append("pa_MP=").append(pa_MP).append("&");// 商户扩展信息 sb.append("pd_FrpId=").append(pd_FrpId).append("&");// 支付通道编码 指哪一家银行 sb.append("pr_NeedResponse=").append(pr_NeedResponse).append("&");// 应答机制 sb.append("hmac=").append(hmac);//签名数据 加密密钥 response.sendRedirect(sb.toString()); } catch (Exception e) { e.printStackTrace(); request.setAttribute("msg", "支付失败"); return "/jsp/msg.jsp"; } return null; } /** * 支付成功之后的回调 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String callback(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取第三方发送过来的数据 //2.获取订单 修改订单状态 //3.更新订单 try { String p1_MerId = request.getParameter("p1_MerId");//商户编号 String r0_Cmd = request.getParameter("r0_Cmd");//业务类型 String r1_Code = request.getParameter("r1_Code");//支付结果 String r2_TrxId = request.getParameter("r2_TrxId");// 易宝支付交易流水号 String r3_Amt = request.getParameter("r3_Amt");// 支付金额 String r4_Cur = request.getParameter("r4_Cur");// 交易币种 String r5_Pid = request.getParameter("r5_Pid");// 商品名称 String r6_Order = request.getParameter("r6_Order");//商户订单号 String r7_Uid = request.getParameter("r7_Uid");// 易宝支付会员ID String r8_MP = request.getParameter("r8_MP");// 商户扩展信息 String r9_BType = request.getParameter("r9_BType");// 交易结果返回类型 String rb_BankId = request.getParameter("rb_BankId");// 支付通道编码 String ro_BankOrderId = request.getParameter("ro_BankOrderId");//银行订单号 String rp_PayDate = request.getParameter("rp_PayDate");//支付成功时间 String rq_CardNo = request.getParameter("rq_CardNo");// 神州行充值卡序列号 String ru_Trxtime = request.getParameter("ru_Trxtime");// 交易结果通知时间 // 身份校验 --- 判断是不是支付公司通知你 String hmac = request.getParameter("hmac");// 加密后的码 String keyValue = ResourceBundle.getBundle("merchantInfo").getString( "keyValue"); // 自己对上面数据进行加密 --- 比较支付公司发过来hamc boolean isValid = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid, r8_MP, r9_BType, keyValue); if (isValid) { // 响应数据有效 if (r9_BType.equals("1")) { // 浏览器重定向 System.out.println("111"); request.setAttribute("msg", "您的订单号为:"+r6_Order+",金额为:"+r3_Amt+"已经支付成功,等待发货~~"); } else if (r9_BType.equals("2")) { // 服务器点对点 --- 支付公司通知你 System.out.println("付款成功!222"); // 修改订单状态 为已付款 // 回复支付公司 response.getWriter().print("success"); } //修改订单状态 OrderService s=(OrderService) BeanFactory.getBean("OrderService"); Order order = s.getById(r6_Order); order.setState(Constant.ORDER_YIFUKUAN); s.update(order); } else { // 数据无效 System.out.println("数据被篡改!"); } } catch (Exception e) { e.printStackTrace(); request.setAttribute("msg", "支付失败"); } return "/jsp/msg.jsp"; } }
package com.itheima.web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.itheima.domain.User; public class PrivilegeFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //1.强转 HttpServletRequest request =(HttpServletRequest) req; HttpServletResponse response =(HttpServletResponse) resp; //2.逻辑 //从session中获取用户 User user = (User) request.getSession().getAttribute("user"); if(user == null){ //未登录 request.setAttribute("msg", "请先登录"); request.getRequestDispatcher("/jsp/msg.jsp").forward(request, response); return; } //3.放行 chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }