文章目录
十九、书城项目第六阶段(1)
001-登陆—显示用户名
要求:在登录之后,在上面的页面的韩总的位置,显示真实的用户名称。
以及 点击 我的订单,也同样显示真实的用户名称。
需要修改的是 pages/common/login_success_menu.jsp中的:
看UserServlet中的login方法,在上面的页面登录成功之后,会跳转到“韩总”那个页面
那么只要将用户名保存在request域中就好了
但是仅仅保存在request域中是不行的,因为点击我的订单,也要显示用户名。
当request域不够用时,使用session。将用户名保存在session中。
如下:修改UserServlet中的login方法:
修改login_success_menu.jsp:
注意:在登录成功之后,要将首页的 登录|注册 也换成用户名
如下图:
这里就需要修改 pages/client/index.jsp:
002-登出—注销用户
实现注销用户功能,注销用户之后,回到未登录时的状态。
1、销毁 Session 中用户登录的信息(或者销毁 Session)
2、重定向到首页(或登录页面)。(这里重定向到首页)
首先在UserServlet中编写注销 logout 方法:
然后修改 login_success_menu.jsp的注销地址:
然后修改 pages/client/index.jsp的注销地址:即首页的注销
这里有一个问题:注册用户之后,如上操作的功能没有实现,老师没讲。
不知道会不会讲。
可以自己实现一下,很简单,UserServlet的register方法做如下修改即可:
003-表单重复提交之-----验证码
(1)表单重复提交的常见的三种情况
(2)通过验证码解决表单重复提交问题
在使用重定向的基础上,二、三情况没有解决。
在使用重定向的基础上,通过验证码解决表单重复提交的常见情况中的二、三。
004-谷歌 kaptcha 图片验证码的使用
验证码需求常用,不需要自己写,使用第三方写好的。
这里使用谷歌的kaptcha
第三方已经帮我们完成了如下:
在书城项目的注册功能下实现验证码:
首先将kaptcha-2.3.2.jar导入到lib下
然后在web.xml中配置用于生成验证码的 Servlet 程序:
然后 在注册表单中使用 img 标签去显示验证码图片并使用它:
修改 register.jsp 中的 表单的 验证码的 img标签 的路径:
然后调整一下验证码和输入验证码框的大小:
然后修改UserServlet的register方法,添加验证码相关代码:
005-验证码的切换
验证码可能看不清,这时点击验证码的图片来实现切换验证码。
在register.jsp中:
首先给验证码图片的img 标签加一个id值:
然后给验证码图片,绑定单击事件:
但是这里出现了一个问题:
如果按照上述写法,谷歌浏览器可以实现点击验证码照片切换验证码,但是火狐和IE浏览器无法实现,原因如下:
因为切换验证码会在缓存中找要已经存在的验证码,而不会到Servlet中生成新的验证码。
解决办法:
让缓存每次都不一样
换成名称有最后的资源名和参数组成
可以在随意添加一个参数,让每次都是不同的值。
如下:
十九、书城项目第六阶段(2)——购物车模块
001-购物车模块分析
使用session版本,没有涉及到与数据库交互,也就没有dao和service层,直接web层servlet。
002-购物车模型编写
package com.atguigu.bean;
import java.math.BigDecimal;
//购物车的商品项
public class CartItem {
private Integer id;
private String name;
private Integer count;
private BigDecimal price;
private BigDecimal totalPrice;
public CartItem() {
}
public CartItem(Integer id, String name, Integer count, BigDecimal price, BigDecimal totalPrice) {
this.id = id;
this.name = name;
this.count = count;
this.price = price;
this.totalPrice = totalPrice;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public BigDecimal getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
@Override
public String toString() {
return "CartItem{" +
"id=" + id +
", name='" + name + '\'' +
", count=" + count +
", price=" + price +
", totalPrice=" + totalPrice +
'}';
}
}
package com.atguigu.bean;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
//购物车
public class Cart {
// private Integer totalCount; 在getTotalCount()中定义,不需要在此定义
// private BigDecimal totalPrice; 在getTotalPrice()中定义,不需要在此定义
//key是商品编号,value是商品信息(使用Map集合操作更方便)
private Map<Integer, CartItem> items = new LinkedHashMap<Integer, CartItem>();
//添加商品项
public void addItem(CartItem cartItem){
//先查看购物车中是否已经添加过此商品,如果已添加,则数量累加,总金额更新,
//如果没有添加过,直接放到集合中即可
CartItem item = items.get(cartItem.getId());
if (item == null) {
// 之前没添加过此商品
items.put(cartItem.getId(), cartItem);
} else {
// 已经添加过的情况
item.setCount( item.getCount() + 1 ); // 数量 累加
item.setTotalPrice( item.getPrice().multiply(new BigDecimal( item.getCount() )) ); // 更新总金额
}
}
//删除商品项
public void deleteItem(Integer id){
items.remove(id);
}
//清空购物车
public void clear(){
items.clear();
}
//修改商品数量
public void updateCount(Integer id, Integer count){
// 先查看购物车中是否有此商品。如果有,修改商品数量,更新总金额
CartItem cartItem = items.get(id);
if (cartItem != null) {
cartItem.setCount(count);// 修改商品数量
cartItem.setTotalPrice( cartItem.getPrice().multiply(new BigDecimal( cartItem.getCount() )) ); // 更新总金额
}
}
public Integer getTotalCount() {
Integer totalCount = 0;
for (Map.Entry<Integer,CartItem> entry : items.entrySet()) {
totalCount += entry.getValue().getCount();
}
return totalCount;
}
/* 不需要setTotalCount()方法,直接在get方法中实现
public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
}*/
public BigDecimal getTotalPrice() {
BigDecimal totalPrice = new BigDecimal(0);
for (Map.Entry<Integer,CartItem> entry : items.entrySet()) {
totalPrice = totalPrice.add(entry.getValue().getTotalPrice());
}
return totalPrice;
}
/* 不需要setTotalPrice()方法,直接在get方法中实现
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}*/
public Map<Integer, CartItem> getItems() {
return items;
}
public void setItems(Map<Integer, CartItem> items) {
this.items = items;
}
@Override
public String toString() {
return "Cart{" +
"totalCount=" + getTotalCount() +
", totalPrice=" + getTotalPrice() +
", items=" + items +
'}';
}
}
package com.atguigu.test;
import com.atguigu.bean.Cart;
import com.atguigu.bean.CartItem;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.*;
class CartTest {
@Test
void addItem() {
Cart cart = new Cart();
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(2, "数据结构与算法", 1, new BigDecimal(100),new BigDecimal(100)));
System.out.println(cart);
}
@Test
void deleteItem() {
Cart cart = new Cart();
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(2, "数据结构与算法", 1, new BigDecimal(100),new BigDecimal(100)));
cart.deleteItem(1);
System.out.println(cart);
}
@Test
void clear() {
Cart cart = new Cart();
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(2, "数据结构与算法", 1, new BigDecimal(100),new BigDecimal(100)));
cart.deleteItem(1);
cart.clear();
System.out.println(cart);
}
@Test
void updateCount() {
Cart cart = new Cart();
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.addItem(new CartItem(2, "数据结构与算法", 1, new BigDecimal(100),new BigDecimal(100)));
cart.deleteItem(1);
cart.clear();
cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000),new BigDecimal(1000)));
cart.updateCount(1, 10);
System.out.println(cart);
}
}
003-加入购物车功能实现
pages/client/index.jsp中修改如下:
在src/web中新建 CartServlet:
关于Referer:
004-购物车的展示功能实现
实现以上页面
修改cart.jsp:
005-删除购物车的商品功能实现
修改cart.jsp:
点击删除,跳转到CartServlet 调用deleteItem方法 并传递商品id
CartServlet 中创建deleteItem方法:
006-清空购物车功能实现
修改cart.jsp:
点击清空购物车,跳转到CartServlet 调用 clear方法,在clear方法中调用Cart的clear方法
CartServlet 中创建 clear方法:
007-修改购物车的商品数量功能实现
修改cart.jsp:
CartServlet中创建updateCount方法,在updateCount方法中调用Cart的updateCount方法:
008-首页,购物车数据回显
要输出最后一个商品的名字,
在CartServlet的addItem方法中将最后一个商品的名字保存到session域中,
这样主页面就可以共享到,不使用request域是因为使用重定向,request域中的数据无法共享。
修改CartServlet的addItem方法:
在 pages/client/index.jsp 页面中输出购物车信息: