使用 JSP+Servlet 模仿京东页面实现购物车功能 您所在的位置:网站首页 购物脚本程序怎么写好看 使用 JSP+Servlet 模仿京东页面实现购物车功能

使用 JSP+Servlet 模仿京东页面实现购物车功能

2024-06-30 22:18| 来源: 网络整理| 查看: 265

可能很多人看到标题都不会点进来,因为 JSP 这种老掉牙的技术很多人根本不学,所以我有些感想写在下面。

这是在学校选课老师让做的实验报告,可能大家会觉得这些东西毫无意义,因为 JSP 早就没人使用了,原因是因为写页面太繁琐,执行速度慢,消耗内存,响应速度慢不能处理高并发等原因;但是我想觉得不能因为他现在被淘汰了就不去学他,更不能抱着轻蔑的态度去学习这门技术,我自己在学习的过程中一直在惊叹 JSP 太强了,真的简化了很多后台开发,还有那些标签技术,真的是独具匠心,发明出这项技术的人真的非常厉害。现在越来越多的 Java 开发相关人员上来直接学习 SpringBoot 等框架,然后快速开发出一个网页,看起来很厉害,但这是不对的,也是错误的,我也学过 Spring 和 SpringBoot 等流行框架,但是现在还是在老老实实的跟着学校的进度学习 JSP,因为我觉得经典的东西一定有学习的价值,只有搞懂基础才能提高境界,这些高大上的框架确实极大的简化了我们的开发,但是有没有想过,如果你一直学习这些别人封装好的框架,其实你根本没有一点核心竞争力,这些东西你会,别人一样也可以学习,而且也是速成,所以我们要掌握基础,学习底层,这样就算别人想超过你也要付出很长时间,久而久之你就有你的核心竞争力了,所以,不要看不起任何一项技术,每一项技术都有他存在的意义。其实仔细想想,我们到底会什么?全都是用的别人封装好的框架,我们只会调用接口,我们写 Java 程序调用 JDK 的接口,然后 Servlet 封装了 JDK,接着 Spring 封装了 Servlet ,简化我们的开发,后来 SpringBoot 进而封装了 Spring 框架,让我们开发网页触手可得······我相信将来还会有一层一层的封装,到最后我们写网页可能是几行代码就搞定了,那个时候可能有的 Java 程序员看似写了一个网页,他可能都不知道 JDK 是什么(夸张的比喻一下),因为封装太多太多层了。换个视角,我甚至觉得人类本来就是调用接口生活,比如我们想吃饭,不想自己做,怎么办?好办,调用美团外卖的接口,传入参数20元,返回一份盖浇饭。说了那么多,就想表明一个观点,就是调用接口虽然方便,但是谁都会调,请问你的核心竞争力是什么?当然我也是个巨菜,没有核心竞争力可言,目前在阅读 JDK 源码和学习算法,感兴趣的朋友可以一起阅读 源码 和算法 交流。

下面开始正文。

实验一 Servlet基础操作

先来看一下最终效果:

在这里插入图片描述在这里插入图片描述一、基础功能1、项目结构

首先来看一下项目的整体结构:

image.pngimage.png2、数据初始化

首先是数据的初始化,这里为了使 Servlet 容器能在一开始就加载数据,我选择在注解中进行了如下配置:

代码语言:javascript复制@WebServlet(name = "ShoppingCartServlet", urlPatterns = { "/shop/products", "/shop/details", "/shop/addCart", "/shop/deleteItem", "/shop/clearCart"}, loadOnStartup = 1)

其中 urlPatterns 为匹配的路径。 这样在一开始就可以加载在 init 方法中的数据了。

代码语言:javascript复制/** * 数据的初始化 * * @param config 配置参数,可以获取应用作用域 * @throws ServletException 抛出异常 */ @Override public void init(ServletConfig config) throws ServletException { super.init(config); // 装载数据 Product p1 = new Product (1, "单反相机", "最没有性价比的单反相机", 3306f); Product p2 = new Product (2, "双反相机", "最不值的双反相机", 3307f); Product p3 = new Product (3, "三反相机", "最难看的三反相机", 3308f); Product p4 = new Product (4, "四反相机", "最花里胡哨的四反相机", 3309f); List list = new ArrayList(); list.add(p1); list.add(p2); list.add(p3); list.add(p4); // 保存到应用作用域中 config .getServletContext() .setAttribute("products", list); }

因为这些数据是所有的应用都会用到的,所以把它放在 context上下文域中,代替了从数据库查询数据。

3、主页

然后我们访问页面,会自动跳转到 productList页面,来看一下 index页面的代码:

代码语言:javascript复制

就只有一行代码,是一个重定向。

访问之后的页面如图:

image.pngimage.png

我们可以选择喜欢的商品,也可以查看购物车。

4、商品详情

这里我们先点进去商品详情:

image.pngimage.png

请求地址为:

代码语言:javascript复制http://localhost:8080/WsShoppingCart/shop/details?id=1

这里拼接了一个 id ,我们可以在 Servlet中取出来,里看代码:

首先是根据请求路径,我们把不同的请求交给不同的方法来处理:

代码语言:javascript复制/** * 根据请求参数后缀来分别处理请求 * * @param request 请求 * @param response 响应 * @throws ServletException Servlet异常 * @throws IOException IO异常 */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uri = request.getRequestURI(); if (uri.endsWith("products")) displayProducts(request, response); else if (uri.endsWith("details")) displayGoods(request, response); else if (uri.endsWith("addCart")) addCart(request, response); else if (uri.endsWith("deleteItem")) deleteCard(request, response); else if (uri.endsWith("clearCart")) clearCart(request, response); }

比如我们这次请求就会转发到 displayGoods方法中去处理,下面来看一下该方法:

代码语言:javascript复制/** * 根据 ID 查询用户点击的是哪一个商品,然后跳转到商品详情页面 * 响应请求: /shop/details * * 注意: 只接受同级目录下的页面请求,所以 ./ 或者不写都可以 * * @param request 请求 * @param response 响应 * @throws ServletException Servlet 异常 * @throws IOException IO 异常 */ private void displayGoods(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Integer id = Integer.valueOf(request.getParameter("id")); List products = (List) getServletContext() .getAttribute("products"); Product product = findById(id, products); if (product != null) request.setAttribute("product", product); request.getRequestDispatcher("./productDetails.jsp") .forward(request, response); }

我们首先从请求路径中获取到了请求参数 id,然后从 context中获取到了之前存进去的商品,这里调用了一个 findById 方法,来看一下这个方法:

代码语言:javascript复制/** * 根据 id 查询相关内容是否在作用域中 * */ private Product findById(Integer id, List products) { for (Product product : products) { if (id.equals(product.getId())) { return product; } } return null; }

它的作用就是根据 id 查询商品,如果查到了就返回,否则返回为空。

这样我们获取这个对象之后就再把它存放到请求作用域中,然后将请求转发到 productDetails 页面。也就是之前我们看到的页面。

5、添加商品到购物车

然后我们可以在文本框中输入加入购物车的商品的数量:

image.pngimage.png

如果我们点击按钮,他会发送一个请求,我们使用这个方法来处理这个请求:

代码语言:javascript复制/** * 添加到购物车 * 响应请求: /shop/addCart * * @param request 请求 * @param response 响应 * @throws IOException 异常 */ private void addCart(HttpServletRequest request, HttpServletResponse response) throws IOException { ServletContext context = getServletContext(); HttpSession session = request.getSession(); Integer id = Integer.parseInt(request.getParameter("id")); Integer quality = Integer.parseInt(request.getParameter("quality")); List products = (List) context .getAttribute("products"); // 初始化购物车 Map cart = (Map) session .getAttribute("cart"); if (cart == null) { cart = new HashMap(); } Product product = findById(id, products); if (product != null) { cart.put(product, quality); session.setAttribute("cart", cart); } displayProducts(request, response); }

那他会发送什么请求呢?

代码语言:javascript复制

我们可以查看 form 表单,而且我们加了一个隐藏域,这样在 Servlet 中才可以获取商品的 id 然后放入 session 域中。并且重定向到 productList 页面中。

image.pngimage.png

我们可以点击查看购物车:

image.pngimage.png

那么 cart 页面是怎么获取数据的呢?

这里用到了 jstl 的标签库以及 el 表达式:

代码语言:javascript复制 ?${cart.value} ${cart.key.name} ${cart.key.price}? ${cart.key.price * cart.value}?

这样就可以输出到页面上了,而且我们还可以删除商品。

6、从购物车中删除商品

从购物车中删除商品需要 cart 页面发送一个请求,然后在 Servlet 页面中处理请求。

代码语言:javascript复制/** * 删除商品 * /shop/deleteItem * * @param request 请求 * @param response 响应 */ private void deleteCard(HttpServletRequest request, HttpServletResponse response) throws IOException { Integer id = Integer.parseInt(request.getParameter("id")); ServletContext context = getServletContext(); HttpSession session = request.getSession(); List products = (List) context .getAttribute("products"); Map cart = (HashMap) session .getAttribute("cart"); Product product = findById(id, products); if (product != null) { cart.remove(product); session.setAttribute("cart", cart); } response.sendRedirect("./cart.jsp"); }

我们从 session 域中获取对象之后再删除该对象,因为它本身是一个 Map 集合,最后重新存到 session 域中,然后重定向到他自己实现刷新效果。

删除之后:

image.pngimage.png7、总体的流程演示

下面通过 GIF 演示一下:

2020_04_20.gif2020_04_20.gif二、扩展功能

下面实现拓展功能:

1、清空购物车

在 cart 页面:

代码语言:javascript复制清空购物车❗

Servlet 中的代码:

代码语言:javascript复制/** * 清空购物车 * 响应请求: /shop/clearCart * * @param request * @param response */ private void clearCart(HttpServletRequest request, HttpServletResponse response) throws IOException { request.getSession().removeAttribute("cart"); response.sendRedirect("./cart.jsp"); }

就是从会话作用域中移除掉所有数据。

2、显示购物车中的商品种类数量和商品总数量

我们先在 forEach 循环中设置一个值 sum 和 total,用于记录商品数量与总数量。

代码语言:javascript复制 ✍总计 ${total}? 总数量 ${sum} 清空购物车❗ image.pngimage.png3、购物车为空的提示

使用 jstl 实现,使用相关标签:

代码语言:javascript复制 购物车中没有商品 ?


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有