本篇文章主要讲的是实现一个简易的购物车操作
效果图如下:
我的实现思路:
1.在mysql创建一张商品表(自动增长的id、名字、价格)
2.利用jdbc连接数据库,取到该表的数据
jdbc的连接就不在说了,不晓得的请点这《Java从入门到放弃》JavaSE入门篇:JDBC(入门版)
3.创建一个商品的实体类,然后将得到的数据保存在list集合你面
//实体商品类
public class Goods {
private String name;//物品名
private double money;//物品价格
private int count;//物品数量
public Goods(){
this.count = 1;//初始化数量为1
}
//此处省略set,get
}//商品类结束
//将所有的商品信息保存到list集合里面
public List<Goods> selectAll(){
List<Goods> list = new ArrayList<Goods>();
//定义一个查询所有的数据库语句
String sql = "select * from tb_product";
try {
ResultSet resultSet = dB.executeQuery(sql);//调用DB查询方法,传入sql语句,返回结果集
//遍历得到的结果集
while(resultSet.next()){
Goods good = new Goods();//创建一个物品对象
//将得到的数据赋给物品对象
good.setName(resultSet.getString("productname"));
good.setMoney(resultSet.getDouble("productprice"));
//将物品对象添加到list集合
list.add(good);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;//返回这个list
}
4.利用servlet实现java代码与jsp的交互
(1).carServlet.java是从页面收到请求后,从数据库中获得商品数据的list集合,并保存在session里面,最后转发到商品展示页面。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
GoodsService goodsService = new GoodsService();//创建一个实例对象
List<Goods> list = goodsService.selectALL();//调用查询所有方法,返回一个list
HttpSession session = request.getSession();//创建一个session对象
/**
* 判断数据库是否有商品
* 有就保存数据
* 没有就返回一个没有商品的消息
*/
if(list.size()!=0){
session.setAttribute("product", list);//保存到session里面
response.sendRedirect("/shoppingcart/shop2.jsp");
}
else{
request.setAttribute("message1", "商城没有商品");//设置一个消息
request.getRequestDispatcher("/shoppingcart/shop2.jsp").forward(request, response);
}
}
(2)商品展示页
在首页里发送查看商城的请求
- index.jsp
<body>
<a href="/shoppingcart/GoodsServerlet">商城</a>
</body>
- shop2.jsp
利用EL表达式和JSTL使页面更加的简介(如果看不懂建议去百度一下就OK了)
<body>
<!--判断是否为空保存在session里的product是否为空-->
<c:if test="${!empty sessionScope.product }" var="state">
<!--不为空就循环遍历打印到页面上去-->
<c:forEach items="${sessionScope.product }" varStatus="status" var="product">
<form action="/shoppingcart/CartServlet" method="post">
<ul >
<li>名字:${product.name }</li>
<li>价格:${product.money }</li>
<li><input type="hidden" name="productname" value="${product.name }" />
<input type="hidden" name="productprice" value="${product.money }" />
<input type="submit" value="加入购物车" /></li>
</ul>
</form>
</c:forEach>
</c:if>
<!--添加成功就弹出一个窗口-->
<c:if test="${!empty requestScope.message2 }">
<script type="text/javascript">
alert("添加成功");
</script>
</c:if>
<a href="/shoppingcart/list.jsp">前往购物车</a>
</body>
界面效果:
5.购物车页面以及实现逻辑的servlet代码
servlet部分:
首先分析一下,购物车里面的东西是不可以消失的,这里我还是用session来保存一个购物车商品集合
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = "";//接受客户请求的商品名字符串
Double price = 0.0;//接受客户请求的商品价格
Goods good = new Goods();//创建一个商品对象,用来保存数据
List<Goods> list = null;//创建一个只能保存商品的list集合
double sumMoney = 0; //统计总价的临时变量
boolean state = false; //判断状态的一个临时布尔类型
HttpSession session = request.getSession(); //创建一个session对象
//从客户端取到商品名,赋给name和price
name = request.getParameter("productname");
price = Double.valueOf(request.getParameter("productprice"));
//转码
name = URLEncoder.encode(name, "ISO-8859-1");
name = URLDecoder.decode(name, "utf-8");
//将得到的值传给good对象
good.setMoney(price);
good.setName(name);
//假设服务器上已经存在购物车列表,并赋给list
list = (ArrayList<Goods>) session.getAttribute("listcart");
//判断list不为空
if (list != null) {
for (int i = 0; i < list.size(); i++) {
//判断当前物品是否存在,存在就仅将该商品数量count加1,并将状态置位true
if (list.get(i).getName().equals(name)) {
list.get(i).setCount(list.get(i).getCount() + 1);
state = true;
}
}
//判断是为新的物品,是就直接添加商品对象
if (!state) {
list.add(good);
}
//保存到session
session.setAttribute("listcart", list);
sum(list, sumMoney, session);
request.setAttribute("message", "添加成功");//将总价保存到request里面
request.getRequestDispatcher("/shop2.jsp").forward(request, response);
} else {
//如果购物车列表为空,就创建一个ArrayList对象,并直接将商品添加到list
list = new ArrayList<Goods>();
list.add(good);
sum(list, sumMoney, session);
//保存到session
session.setAttribute("listcart", list);
request.setAttribute("message", "添加成功");
request.getRequestDispatcher("/shop2.jsp").forward(request, response);
}
}
//计算总价
private void sum(List<Goods> list, double sumMoney, HttpSession session) {
for (int i = 0; i < list.size(); i++) {
sumMoney += list.get(i).getMoney() * list.get(i).getCount();
}
session.setAttribute("sum", sumMoney);
}
(2)购物车部分:list.jsp
从session里取到购物车list集合,并打印到页面显示
<body>
<c:if test="${!empty sessionScope.listcart }">
<table>
<thead>
<th>名字</th>
<th>价格</th>
<th>数量</th>
</thead>
<c:forEach items="${sessionScope.listcart }" var="product"
varStatus="x">
<tr
<c:if test="${x.index % 2 == 1 }">style="background-color:rgb(219,241,212);"</c:if>>
<td>${product.name }</td>
<td>${product.money }</td>
<td>${product.count }</td>
</tr>
</c:forEach>
<tfoot><td rowspan="2">总价:${sessionScope.sum}</td></tfoot>
</table>
</c:if>
<a href="/shoppingcart/shop2.jsp">返回购物</a>
</body>
一个粗糙的购物车操作结到此结束了。
遇到的问题:
- 重定向和转发:重定向后保存的request信息会丢失,转发不会
- 中文字符串乱码:
1.URLEncoder.encode(String s, String enc) 使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式
URLDecoder.decode(String s, String enc) 使用指定的编码机制对
application/x-www-form-urlencoded 字符串解码。2.发送的时候使用URLEncoder.encode编码,接收的时候使用URLDecoder.decode解码,都按指定的编码格式进行编码、解码,可以保证不会出现乱码
3.主要用来http get请求不能传输中文参数问题。http请求是不接受中文参数的。
这就需要发送方,将中文参数encode,接收方将参数decode,这样接收方就能收到准确的原始字符串了。
-
JSTL的forEach:刚开始都是用来打印list集合,但是突然想直接打印字符串集合,打印不出来。
解决的代码,需要用一个<c:out>来取到每一个元素的值
<c:forEach items="字符串集合" var="strs" varStatus="x">
<c:out value="${strs}" /> <!-- 得到数值 -->
</c:forEach>