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

生成订单:

功能入口:购物车页面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()拿到的父类对象是不能调用子类特有的方法的。

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


这里进行一番分析,以便加深理解。而不只是会用。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值