一:订单提交的分析和实体的创建
1. servlet中
将订单的信息存储到数据库
详细分析:
1)保证用户登录,用户没有登录不能提交订单
用户是否登录的标志:session中是否存在user对象
2)需要封装什么对象,Product对象---product表
OrderItem对象---orderitem表:pid,count,subtotal,oid
Order对象---orders表:oid,total,uid
2.实体类
public class OrderItem{
private String itemid;//订单项的id
private int count;//订单项内商品的购买数量
private double subtotal;//订单项小计
private Product product;//订单项内部的商品
private Order order;//该订单属于哪个订单
getter和setter
}
public class Order{
private String oid;//该订单的订单号
private Date ordertime;//下单时间
private double total;//该订单的总金额
private int state;//订单的支付状态
private String address;//收货地址
private String name;//收货人
private String telephone;//收货人电话
private User user;//该订单属于哪个用户
//该订单中有多少订单项
List
getter和setter
}
二:订单提交的业务分析
1.web层:
封装Order对象
submitOrder(Order order);
2.service层:
开启事务:
调用dao层存储order数据的方法
调用dao层存储orderitem数据的方法
提交事务
3.dao层
将那些数据放到数据库中?
订单的信息--orders表
insert into orders values(?,?,?,?,?)
订单项信息---orderitem表
insert into orderitem values (?,?,?,?)
三:订单提交的代码实现
1.cart.jsp中
href="${pageContext.request.contextPath}/product?method=submitOrder"
type="button"
2.productServlet中
//提交订单
submitOrder{
HttpSession session = request.getSession();
//判断用户是否已经登录
User user = (User)session.getAttribute("user");
if(user==null){
//没有登录
response.sendRedirect(request.getContextPath()+"/login.jsp");
return ;
}
//目的:封装好一个Order对象,传递给service层
Order order = new Order();
String oid = CommonUtils.getUUID();
order.setOid(oid);
order.setOrdertime(new Date());
Cart cart = (Cart) session.getAttribute("cart");
double total = cart.getTotal();
order.setTotal(total);
order.setState(0);
order.setAddress(null);
order.setName(null);
order.setTelephone(null);
order.setUser(user);
//获得购物车中的购物项
Map
for(Map.Entry
CartItem cartItem = entry.getValue();
OrderItem orderItem = new OrderItem();
orderItem.setItemid(CommonUtils.getUUID());
orderItem.setCount(cartItem.getBuyNum());
orderItem.setSubtotal(cartItem.getSubtotal());
orderItem.setProduct(cartItem.getProduct());
orderItem.setOrder(order);
//将该订单项添加到订单的订单项集合中
order.getOrderItems().add(orderItem);
}
//order对象封装完毕
//传递数据到service层
ProductService service = new ProductService();
service.submitOrder(order);
session.setAttribute("order", order);
//页面跳转
response.sendRedirect(request.getContextPath()+"/order_info.jsp");
}
3.ProductService中
//提交订单,将订单的数据和订单项的数据存储到数据库中
public void submitOrder(Order order){
ProductDao dao = new ProductDao();
//1.开启事务
DataSourceUtils.startTransaction();
//2.调用dao存储order表数据的方法
dao.addOrders(order);
//3.调用dao存储orderitem表数据的方法
dao.addOrderItem(order);
DataSourceUtils.rollback();
DataSourceUtils.commitAndRelease();
//有异常加try...catch
}
4.ProductDao 中
//向orders表插入数据
public void addOrders(Order order) throws SQLException{
QueryRunner runner = new QueryRunner();
String sql = "insert into orders values(?, ?,?,?,?,?,?,?)";
Connection con = DataSourceUtils.getConnection();
runner.update(con,sql,order.getOid(),order.getOrdertime(),order.getTotal(),order.getState(),order.getAddress(),order.getName(),order.getTelephone(),order.getUser().getUid());
}
//向orderitem表插入数据
public void addOrderItem(Order order)throws SQLException{
QueryRunner runner = new QueryRunner();
String sql = "insert into orderitem values(?,?,?,?,?)";
Connection con = DataSourceUtils.getConnection();
List
for(OrderItem item : orderItems){
runner.update(con,sql,item.getItemid(),item.getCount(),item.getSubtotal(),item.getProduct().getPid(),item.getOrder().getOid());
}
}
四:更新收货人信息
1.order_info.jsp中
订单编号:${order.oid}
form 的action="${pageContext.request.contextPath}/product" method="post" id="orderForm"
电话:name="telephone"
2.点击确认订单
将收货人的信息更新到数据库
在线支付的功能(跳转到银行的网银支付页面进行支付)
支付成功后修改数据的state状态
3.ProductServlet中
//确认订单---更新收货人的信息+在线支付
public void confirmOrder(){
Map
Order order = new Order();
BeanUtils.populate(order,properties);
ProductService service = new ProductService();
service.updateOrderAddr(order);
}
4.ProductService中
public void updateOrderAddr(Order order){
ProductDao dao = new ProductDao();
dao.updateOrderAddr(order);
}
5.ProductDao 中
public void updateOrderAddr(Order order)throws SQLException{
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "update orders set address=?,name=?,telephone=? where oid=?";
runner.update(sql,order.getAddress(),order.getName(),order.getTelephone(),order.getOid());
}
五:在线支付简介
使用易宝支付提供的API
六:在线支付代码实现
1.ProductServlet中
在confirmOrder方法中
String orderid = request.getParameter("oid");
//String money = order.getTotal()+"";//支付金额
String money = "0.01";//支付金额
// 银行
String pd_FrpId = request.getParameter("pd_FrpId");
// 发给支付公司需要哪些数据
String p0_Cmd = "Buy";
String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId");
String p2_Order = orderid;
String p3_Amt = money;
String p4_Cur = "CNY";
String p5_Pid = "";
String p6_Pcat = "";
String p7_Pdesc = "";
// 支付成功回调地址 ---- 第三方支付公司会访问、用户访问
// 第三方支付可以访问网址
String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("callback");
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);
String url = "https://www.yeepay.com/app-merchant-proxy/node?pd_FrpId="+pd_FrpId+
"&p0_Cmd="+p0_Cmd+
"&p1_MerId="+p1_MerId+
"&p2_Order="+p2_Order+
"&p3_Amt="+p3_Amt+
"&p4_Cur="+p4_Cur+
"&p5_Pid="+p5_Pid+
"&p6_Pcat="+p6_Pcat+
"&p7_Pdesc="+p7_Pdesc+
"&p8_Url="+p8_Url+
"&p9_SAF="+p9_SAF+
"&pa_MP="+pa_MP+
"&pr_NeedResponse="+pr_NeedResponse+
"&hmac="+hmac;
//重定向到第三方支付平台
response.sendRedirect(url);
2.merchantInfo.properties中
p1_MerId=10001126856
keyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl
callback=http://localhost/HeimaShop/callback
3.CallbackServlet中/callback
public class CallbackServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获得回调所有数据
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");
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")) {
//修改订单状态
ProductService service= new ProductService();
service.updateOrderState(r6_Order);
// 浏览器重定向
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("