本片主要内容是实现一个小购物车的主要思路及部分代码:
主要功能:
①登录验证
②展示数据库中的商品
③添加商品到购物车操作
④计算产品数量以及结算总价
⑤将购物车数据存入数据库
功能实现思路:
1.登录验证
从页面传入用户名和密码,通过Servlet调用service层的用户匹配方法;与数据库中的已有数据进行匹配,匹配成功即返回该用户并保存在session中。匹配不成功转发到登录页面。
该环节需要做三件事:
1. 验证登录
2. 保存用户
3. 取到用户已有的购物车
页面展示:
1.1 login.jsp 页面部分
<form action="LoginServlet" method="post">
<label for="loginID">用户名:</label><input type="text" name="loginID" id="loginID" value="" /><br />
<label for="loginPWD">密 码:</label><input type="text" name="loginPWD" id="loginPWD" value="" /><br />
<input type="submit" value="提交"/>
</form>
1.2 LoginServlet核心操作代码:
//取到表单数据
String loginID = request.getParameter("loginID");
String loginPWD = request.getParameter("loginPWD");
//1.不为空,调用UserServcie的匹配方法
if (loginID!=""&&loginPWD!="") {
UserService userService = new UserService();
User user = null;
user = userService.matchingUser(loginID, loginPWD);
//如果匹配成功,保存该对象,并转发到下一步
if (user!=null) {
//1.存用户
HttpSession session = request.getSession();
session.setAttribute("user", user);
//2.存购物车
CartService cartService = new CartService();
if (cartService.selectCarts(user.getUid())!=null) {
List<Cart> list = cartService.selectCarts(user.getUid());
session.setAttribute("cartList", list);
}
response.sendRedirect("Product");
}else {
request.setAttribute("message", "用户名或密码错误!");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}else {
request.setAttribute("message", "用户名或密码不能为空!");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
1.3 dao层,查询用户的方法,与数据库匹配,成功返回该对象所有信息,失败返回空
//匹配用户根据用户名和用户密码
public User matchingUser(String loginID,String loginPWD){
User user = null;
String sql = "SELECT * FROM tb_user WHERE uname = ? and upwd = ?";
Object[] params = new Object[2];
params[0] = loginID;
params[1] = loginPWD;
ResultSet re = DBManage.getResultSet(sql, params);
try {
if (re.next()) {
user = new User();
user.setUid(re.getInt(1));
user.setLoginID(re.getString(2));
user.setLoginPWD(re.getString(3));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}
2.展示商品
与上一篇的思路一致,就不在写一遍了
详情请看:纯session购物车
3.添加到购物车
这是该购物车的功能核心,所有的操作也都是围绕着这个功能展开。
从页面提交要添加的物品id,传入CartServlet,然后保存在session
3.1 商品展示页:
//sessionScope.products是在2阶段保存的商品list集合
<c:if test="${!empty sessionScope.products }" var="state">
<c:forEach items="${sessionScope.products }" varStatus="status"
var="product">
<form action="cart" method="post">
<ul >
<li>名字:${product.pName }</li>
<li>价格:${product.price }</li>
<li>详情:${product.details }</li>
<li>
<input type="hidden" name = "pid" value="${product.pid }"/>
<input type="submit" value="加入购物车" />
</li>
</ul>
</form>
</c:forEach>
3.2 CartServlet主要代码
//获取页面请求信息
int pid = Integer.valueOf(request.getParameter("pid"));
int uid = ((User)request.getSession().getAttribute("user")).getUid();
//将请求信息存入Cart对象
Cart cart = new Cart();
cart.setPid(pid);
cart.setUid(uid);
//创建list<Cart>引用,接收已存在的购物车
List<Cart> list = null;
list = (ArrayList<Cart>)request.getSession().getAttribute("cartList");
//判断该用户有无历史购物车记录
if (list.size()!=0) {
//1.有,再判断当前商品是否已存在
boolean state = false;//判断是否存在的状态值
for (int i = 0; i < list.size(); i++) {
if (pid==list.get(i).getPid()) {
int number = list.get(i).getNumber();
list.get(i).setNumber(number+1);
state = true;
}
}
if (!state) {
list.add(cart);
}
}else {
//没有存在购物车,创建一个
list = new ArrayList<Cart>();
list.add(cart);
}
//将保存后的购物车重新存入session
request.getSession().setAttribute("cartList", list);
request.getSession().setAttribute("message1", "添加成功");
response.sendRedirect("index.jsp");
3.3 购物车监听器:CartListListener(核心)
该监听器的主要作用是:
- 当产品集合生成后,就计算一次历史购物车总价
- 当购物车集合cartList发生改变的时候,将数据库中该登录用户的购物车清空,然后把更新后的cartList存入数据库
- 计算更新后的总价
CartListener.java
//sessionScope.cartList每次发生替换的时候
public void attributeReplaced(HttpSessionBindingEvent event) {
String name = event.getName();//获取发生替换的session名
int uid = ((User)event.getSession().getAttribute("user")).getUid();//获取当前用户id
List<Cart> list = (ArrayList<Cart>)event.getSession().getAttribute("cartList");//获取购物车集合
if (name.equals("cartList")) {//判断是否为购物车集合发生改变
cartService.delCart(uid);//通过用户id清空购物车
for (int i = 0; i < list.size(); i++) {//遍历插入替换后的购物车到数据库
cartService.insertCart(list.get(i));
}
double sum = 0;//保存总计的临时变量
//获取商品集合
List<Product> products = (ArrayList<Product>)event.getSession().getAttribute("products");
//嵌套循环,找到购物车物品id对应的物品价格
for (int i = 0; i < carts.size(); i++) {
for (int j = 0; j < products.size(); j++) {
//找到了就把购物车里存的数量乘以商品集合存的价格
if (carts.get(i).getPid()==products.get(j).getPid()) {
sum += carts.get(i).getNumber()*products.get(j).getPrice();
}
}
}
//将总价保存到session
event.getSession().setAttribute("sum", sum);
}
}
CartDao.java
//dao层代码
//根据uid删除数据
public void delCart(int uid){
String sql = "DELETE FROM tb_cart where uid="+uid;
Object[] params = new Object[0];
DBManage.modifyEntiy(sql, params);
}
//插入购物车
public void insertCart(Cart cart){
String sql = "INSERT tb_cart (uid,productid,number) VALUE (?,?,?)";
Object[] params = new Object[3];
params[0] = cart.getUid();
params[1] = cart.getPid();
params[2] = cart.getNumber();
DBManage.modifyEntiy(sql, params);
}
4.购物车页面商品删减操作
cart.jsp
购物车展示页代码如下:
<c:forEach items="${sessionScope.cartList }" var="cart" varStatus="x">
<tr
<c:if test="${x.index % 2 == 1 }">style="background-color:rgb(219,241,212);"</c:if>>
<c:forEach items="${sessionScope.products }" var = "product">
<c:if test="${cart.pid==product.pid }">
<td>${product.pName }</td>
<td>${product.price }</td>
<td>
<a href="Handle?method=del&index=${x.index}">-</a><!--减数量-->
${cart.number }
<a href="Handle?method=add&index=${x.index}">+</a><!--加数量-->
</td>
</c:if>
</c:forEach>
<!--删除所有相同商品-->
<td><a href="Handle?method=delAll&index=${x.index}" onclick="ock()">删除</a></td>
</tr>
</c:forEach>
<tfoot><td rowspan="2">总价:${sessionScope.sum}</td></tfoot>
HandleServlet.java
String method = "";
method = request.getParameter("method");//取到参数名
HttpSession session = request.getSession();
List<Cart> list = (ArrayList<Cart>)session.getAttribute("cartList");
CartService cartService = new CartService();
int index = Integer.valueOf(request.getParameter("index"));
if (method.equals("del")) {//做减数操作
int number = list.get(index).getNumber();
if (number>=1) {
list.get(index).setNumber(number-1);//取到该list的元素,将总数减一
}else {
list.remove(index);
}
}
else if (method.equals("add")) {//做加操作
int number = list.get(index).getNumber();//取到该list的元素,将总数减一
list.get(index).setNumber(number+1);
}
else if (method.equals("delAll")) {//做删除所有操作
list.remove(index);
}
session.setAttribute("cartList", list);//再次保存到cartList集合
response.sendRedirect("cart.jsp");//购物车界面
实现图如下:
总结(改进):
1.用户登录匹配部分:
(old)起初思维凝固,总想着先从数据库取到所有的用户集合,然后和页面上的信息进行遍历匹配。虽然效果一样但是多做了不少无用功
select * from tb_user(返回很多个用户)
(new)从页面传入用户id和用户密码,在通过这两个条件传入一条数据库语句,如果存在就直接返回该用户所有信息。
select * from tb_user where uid = ? and upwd = ?(仅用取一条)
2.servlet部分:
(old)不知道可以在跳转地址后面加?xxx==xxx,老想着用form来提交表单传值。
<form action="xxx">
<input type="hidden" name = "xxx" value="xxx"/>
</form>
(new)像上面的减、加操作,如果在地址里加上一个method=xx,我就可以在一个servlet里面写多个类似操作了,只用几个if判断即可
<a href="Handle?method=del&index=${x.index}">-</a><!--减数量-->
<a href="Handle?method=add&index=${x.index}">+</a><!--加数量-->
<a href="Handle?method=delAll&index=${x.index}" onclick="ock()">删除</a>
if (method.equals(“del”))&&if (method.equals(“add”))&&if (method.equals(“delAll”))
结束。
该睡觉了,期待明天,哦不今天