您的位置:首页 > Web前端 > JavaScript

###Jsp+Servlet购物商城day03.2:生成订单。重点笔记

2017-09-12 17:28 543 查看
生成订单:

功能入口:购物车页面cart.jsp,“提交订单”按钮,

功能出口:订单信息页面orderInfo.jsp

<div style="text-align:right;margin-top:10px;margin-bottom:10px;">
<a href="${pageContext.request.contextPath}/CartServlet?method=delAll" id="clear" class="clear">清空购物车</a>

<%--===######===页面显示的所有购物车数据都在session的cart里。所以这里不需要传递任何参数。 --%>
<a href="${pageContext.request.contextPath}/OrderServlet?method=save">
<input type="submit" width="100" value="提交订单" name="submit" border="0"
style="background: url('${pageContext.request.contextPath}/images/register.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0);
height:35px;width:100px;color:white;">
</a>
</div>


OrderServlet的save()方法:

package cn.itcast.servlet;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.junit.Test;

import cn.itcast.domain.Cart;
import cn.itcast.domain.CartItem;
import cn.itcast.domain.OrderItem;
import cn.itcast.domain.Orders;
import cn.itcast.domain.Product;
import cn.itcast.domain.User;
import cn.itcast.service.OrderService;
import cn.itcast.service.impl.OrderServiceImpl;
import cn.itcast.utils.C3p0Utils;
import cn.itcast.utils.UUIDUtils;

public class OrderServlet extends BaseServlet {
private static final long serialVersionUID = 1L;

//====多层数据的封装,必须自己总结一套 套路。思路清晰熟练。?下面
public String save(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

User user = (User) request.getSession().getAttribute("logingUser");
if (user==null) {
//				response.sendRedirect("/login.jsp");//==###=重定向,后面代码不会再执行。
return "/login.jsp";
}
Cart cart = (Cart) request.getSession().getAttribute("cart");
/*===######==数据封装。购物项==订单项,购物车==Order。对应数据关系。
【总体思想:把session里的cart信息,取出来封装到 order里】
①cartItem信息和OrderItem页面信息基本完全一样,只是个别表字段多加了几个特有外键属性。
表结构不同, 因此OrderItem不能直接使用 CartItem的Bean类。
②cart和Order相似。都对内容进行封装。都有总价。很相似。
====总结===Cart.jsp到OrderInfo.jsp的过渡:
本质就是:Session购物车数据 Cart取出来重新封装在Order里,再在页面显示重新Order信息。
=====难点也就是逐层封装的具体过程。需要非常熟练。
*/
Orders order = new Orders();
//
order.setOid(UUIDUtils.getUUID());
order.setDate(new Date());
order.setState(0);
order.setTotal(cart.getTotalMoney());
order.setUser(user);
//
//OrderItem orderItem = new OrderItem();//===放在外面,Map永远只存了最后一个OrderItem
LinkedHashMap<String, OrderItem> map = new LinkedHashMap<String, OrderItem>();

Collection<CartItem> items = cart.getItems();
for (CartItem cartItem : items) {
OrderItem orderItem = new OrderItem();//===放在外面,Map永远只存了最后一个OrderItem
//System.out.println("cartItem:"+cartItem.getPro().getPname()+"="+cartItem.getTotal());
orderItem.setCount(cartItem.getCount());
orderItem.setItemid(cartItem.getPro().getPid());
orderItem.setOrder(order);
orderItem.setPro(cartItem.getPro());
map.put(cartItem.getPro().getPid(), orderItem);
}
System.out.println("===map"+map);//===ok===
order.setOrderItems(map);

//===测试。
Collection<OrderItem> orderItems = order.getOrderItems();
for (OrderItem item : orderItems) {
System.out.println("一个orderItem:【");
System.out.println("==="+item.getItemid());
System.out.println("==="+item.getCount());
System.out.println("==="+item.getSubtotal());
System.out.println("==="+item.getPro().getPname());
System.out.println("】");
}
System.out.println();//===重写toString()
OrderService os = new OrderServiceImpl();
try {
boolean b = os.save(order);
if (b) {
request.getSession().removeAttribute("cart");
}
//===
request.setAttribute("order", order);
} catch (Exception e) {
e.printStackTrace();
}
return "order_info.jsp";
}

}


-----------------------------------------------------BaseServlet理解:(本节无关内容)---------------------------

====这里使用到的BaseServlet会做单独笔记。要理解起来,需要牢固的Java反射知识:
创建子类对象调用父类方法时,子类对象getClass()拿到的是子类对象的字节码对象。

BaseServlet里子类对象用this代替,很容易让人以为是this代表的是当前类对象(也就是BaseServlet对象)。

其实这里忽略了一点:请求第一次访问的是XxxServlet (extends BaseServlet),所以服务器会先创建XxxServlet对象(也就是子类对象)。

然后service()根据请求类型 处理,再去调doGet()或doPost(),子类XxxServlet继承了BaseServlet的doGet()和doPost(),所以根据继承特性。

子类对象 调用父类的doGet()。

只不过这里的子类对象是反射生成的。-----------------说多了容易把自己绕进去。

总之:记住BaseServlet 里this.getClass(),this代表的是子类对象(【其实是:当前调用这个doGet()方法的对象!!】this所在的doGet()方法)。

然后:通常所讲的 “this代表当前所在类的对象”,好像和这个有点冲突。

=====我是这样理解的:可以看作 “this代表的是 当前所在类(同类型)的对象”。这样的话,子类对象调继承父类的方法时,其实就是多态。

【有个结论:记住的(Java常见面试题):】

B extends A.。

A  b =new B();

system.out.println( b.getClass() )//===打印的是  B类型的字节码对象。(已测)

所以这里BaseServlet里反射生成子类对象,调用子类方法时,this.getClass()代表的就是 多态情况下,子类的字节码对象。所以才能调子类方法。

如果this代表的是 父类对象,那么this。getClass()拿到的父类对象是不能调用子类特有的方法的。

事实是可以调用子类特有的方法。事实胜于雄辩。用多了也就熟练了。

这里进行一番分析,以便加深理解。而不只是会用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐