ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Servlet+Session实现购物车:JavaWeb入门项目实战解析

Servlet+Session实现购物车:JavaWeb入门项目实战解析 简介一套基于JavaWeb和Servlet实现的简单购物车系统项目面向正在学习JavaWeb开发的学生或需要完成课程设计的人员。项目采用Eclipse动态Web项目结构入口为商品展示HTML页面每个商品配有“添加到购物车”超链接点击该超链接后由Servlet接收请求记录所选购商品的信息和选购数量随后再跳转到另一个Servlet以表格形式输出购物车中的已选商品完整演示了Servlet接收请求、请求转发、页面跳转和简单业务处理的协作流程。压缩包共25个文件包含3个Java源文件及对应class文件、8张JPG商品图片、1个HTML页面以及Eclipse工程配置.classpath、.project、.settings等整体约491KBsrc与WebContent目录划分清晰便于导入Eclipse对照源码学习。目前已有638人学习浏览。借助该资源可掌握Servlet处理表单参数、暂存购物车记录、表格动态展示等核心写法也可以将其作为JavaWeb课程设计或Servlet入门练习的改造模板。1. servlet购物车是什么一个不用框架的javaWeb入门闭环刚把servlet和Session学完最缺的不是再跑一个hello world而是有一条能把请求参数、会话保存、页面跳转、动态输出串起来的完整业务链。javaWebservlet实现的这个简单购物车系统正好卡在这个点上一个商品展示页、两个servlet、一个存购物车的Session加一张表格输出凑成了javaWeb入门最常见的闭环。它解决两类具体问题一是让你在完全不依赖框架的前提下看明白一次点击从静态页面跳到Servlet、再跳到另一个Servlet的完整轨迹二是给你一份结构完整的工程目录src下的源码、编译输出、WebContent里的静态资源都是齐的省掉搭环境的功夫。适合正在学javaWeb准备交课程设计的人也适合想验证自己是不是真搞懂了Session作用域的从业者。2. 从商品页到Servlet请求流转、Session作用域与重定向为什么是关键购物车系统听起来简单但它天生跨请求、跨页面天然涉及HTTP无状态协议最核心的补偿机制。这一章先把请求从哪里来、到哪里去的链路拆清楚后面写代码才有据可依。2.1 商品展示页一个纯静态HTML能承接多少事项目里WebContent下有一个shop.html这就是整个购物车的入口。它用表格列出商品每一行放一个添加到购物车的链接链接后面带着商品id、名称和单价三个查询参数。关键代码如下!DOCTYPE html html langzh-CN head meta charsetUTF-8 title商品列表/title style table { border-collapse: collapse; } td, th { padding: 6px 12px; border: 1px solid #ccc; } /style /head body h2商品列表/h2 table trth编号/thth商品名称/thth单价/thth操作/th/tr tr td001/tdtdJava核心技术/tdtd89.00/td tda hrefAddCartServlet?id001nameJava核心技术price89.00添加到购物车/a/td /tr tr td002/tdtdServlet与JSP实战/tdtd69.00/td tda hrefAddCartServlet?id002nameServlet与JSP实战price69.00添加到购物车/a/td /tr tr td003/tdtdSpring Boot入门/tdtd109.00/td tda hrefAddCartServlet?id003nameSpring Boot入门price109.00添加到购物车/a/td /tr /table /body /html这里的写法有两个值得注意的选择。第一链接用的是相对路径AddCartServlet而不是/shop010/AddCartServlet这样项目换个context路径部署也不会404这是我在所有servlet小项目里都会坚持的写法。第二所有商品数据都是写死在HTML里的这对练习足够但你要清楚一个边界价格放在URL参数里等于把定价权交给了浏览器用户手动改一下链接里的price就能以0.01元下单。真实商城的价格必须由服务端从数据库查URL里只能出现商品id。练习阶段这样带参数是为了快速看到请求参数的传递效果不算错误只是要知道它撑不起真实业务。2.2 两个Servlet的分工一个写Session一个读Session整个购物车逻辑只用了两个Servlet分工很干净AddCartServlet负责接收商品参数、把商品写进SessionShowCartServlet负责从Session里读出购物车、拼成HTML表格输出。用户每次点击实际发生四次交互步骤用户操作请求URL处理的Servlet核心动作1打开商品页/shop010/shop.html无静态页展示商品列表2点添加到购物车/shop010/AddCartServlet?id001...AddCartServlet取参数写Session3浏览器跟随重定向/shop010/ShowCartServletShowCartServlet读Session拼表格4刷新页面/shop010/ShowCartServletShowCartServlet图表不变不重复添加第3步特别关键AddCartServlet处理完并没有直接输出页面而是用sendRedirect把浏览器指到ShowCartServlet。很多初学者在这里用请求转发request.getRequestDispatcher(ShowCartServlet).forward(request, response)也能看到购物车表格但副作用很阴险——转发是服务端内部跳转浏览器地址栏还停在AddCartServlet用户一按F5浏览器就把添加商品这个请求又发了一遍购物车数量翻倍。重定向让浏览器发起一次全新的GET请求地址栏变成了ShowCartServlet刷新多少次都只是重新展示购物车不会重复写入。这一个细节就是接口幂等性最早的启蒙。2.3 购物车为什么放Session而不是request或application这是整个项目最关键的设计判断。购物车是每个用户各自拥有一份的数据它必须跨多个请求存活但又不能和其他用户共享。Servlet规范里恰好提供了一个符合这个特性的作用域Session。要理解为什么先对比Servlet三个作用域的生命周期作用域存活时间可见范围放购物车的后果request一次请求-响应结束即销毁仅当前请求内的Servlet加完商品立刻丢失session一个浏览器会话期间存活同一个浏览器的所有请求购物车按用户隔离正确application应用启动到关闭所有用户共享所有人共用一个购物车互相能看到对方加的商品把购物车放request是初学者最常犯的错因为req和resp在同一段代码里看起来总是顺手能用。但它活不过一次请求AddCartServlet里刚put进去的数据跳到ShowCartServlet时request对象已经是新的了读出来必然是null。放application更隐蔽单机测试只有一个浏览器开着看不出来问题一旦换台电脑打开同一个应用发现购物车里躺着别人的商品那时才意识到是作用域选错了。Session的实现机制也值得在这里说透浏览器第一次访问时Tomcat在服务端创建一个HttpSession对象同时生成一个唯一的JSESSIONID通过Set-Cookie响应头发给浏览器。之后的每一次请求浏览器自动在Cookie里带上JSESSIONIDTomcat拿着这个ID在内存里找到对应的Session对象。也就是说Session能连续工作依赖两个前提服务端不重启、浏览器不关Cookie。这两个前提恰恰也是后面第4章排查购物车丢失两条踩坑记录的源头。3. 把购物车写出来添加、计数、展示的完整servlet实现原理理清楚之后代码落地就顺了。这一章从工程目录开始把两个Servlet和一个购物项类的完整代码给出来你可以直接照着搭。3.1 先看懂工程目录src、build与WebContent的分工先把项目结构讲清楚因为这份压缩包不是Maven标准布局而是Eclipse Dynamic Web Project的经典结构shop010/ ├── .classpath ├── .settings/ ├── src/ │ └── com/shop/ # Java源码所在 ├── build/ │ └── classes/ # Eclipse编译输出目录 │ └── com/shop/ └── WebContent/ ├── META-INF/ ├── WEB-INF/ │ └── web.xml ├── shop.html └── img/build/classes是Eclipse里把默认输出文件夹改成build\classes后的编译产物位置部署到Tomcat时IDE会把这个目录下的class文件复制到WEB-INF\classes。如果你在项目里看到build目录和WebContent目录并存基本可以判定这份代码是用Eclipse导出的源码在src页面在WebContent没有pom.xml。导入IDEA时不需要按Maven工程处理直接当普通JavaWeb项目导入即可后面第4章会单独说IDEA里的配置坑。WEB-INF下最值得看的是web.xmlServlet的注册信息一般都在这里。如果你用的是Servlet 3.0以上容器也可以直接用WebServlet注解替代web.xml两种方式效果相同。下面的代码为了减少文件跳转统一用注解。3.2 购物项类把商品信息和数量打包成一个对象购物车里的每一行本质是商品基础信息选购数量。把这两类数据封装成一个CartItem后面MapString, CartItem才有值可存。代码很简单package com.shop; public class CartItem { private String id; private String name; private double price; private int count; public CartItem(String id, String name, double price, int count) { this.id id; this.name name; this.price price; this.count count; } public double getSubtotal() { return price * count; } // 省略部分getter/setter实际项目中需要补全 public String getId() { return id; } public String getName() { return name; } public double getPrice() { return price; } public int getCount() { return count; } public void setCount(int count) { this.count count; } }getSubtotal()返回的是这一行商品的小计金额由单价乘数量得出放在对象内部而不是在展示Servlet里临时计算是为了让计算金额这个动作只有一处实现不要在每个用得到的地方各写一遍。如果你后续要加优惠折扣、满减活动只改这一个方法就行。3.3 AddCartServlet从取参数到写Session的完整链路添加购物车的Servlet是整个项目的核心它完成了三件事取参数、找Session里的购物车、把商品写进去。完整代码如下package com.shop; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; WebServlet(/AddCartServlet) public class AddCartServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置请求与响应的字符编码统一为UTF-8 request.setCharacterEncoding(UTF-8); response.setContentType(text/html;charsetUTF-8); // 从请求URL上取出商品id、名称、单价 String id request.getParameter(id); String name request.getParameter(name); String priceStr request.getParameter(price); double price Double.parseDouble(priceStr); // 获取当前会话的购物车Map不存在则新建并放进Session HttpSession session request.getSession(); MapString, CartItem cart (MapString, CartItem) session.getAttribute(cart); if (cart null) { cart new HashMapString, CartItem(); session.setAttribute(cart, cart); } // 按商品id判断购物车里是否有同一商品有则数量1没有则新增一项 CartItem item cart.get(id); if (item null) { cart.put(id, new CartItem(id, name, price, 1)); } else { item.setCount(item.getCount() 1); } // 回到购物车展示页用重定向而不是转发避免刷新重复添加 response.sendRedirect(request.getContextPath() /ShowCartServlet); } }这段代码有几个参数和逻辑细节值得逐一说清楚。request.setCharacterEncoding(UTF-8)只对POST请求的请求体生效对GET请求URL里的中文参数不起作用。商品名称是从链接的queryString传过来的属于GET参数所以这一行在这里实际救不了乱码真正解决GET中文乱码的手段后面第4.1节会讲。我保留这行是因为它对POST请求仍是必要防线写servlet时统一带上没有坏处。Double.parseDouble(priceStr)把价格字符串转成double如果URL里的price不是合法数字这行会直接抛NumberFormatException。练习阶段你可以假装它不存在真实项目里必须在parse之前做一次数字格式校验否则用户改坏一个参数页面就白屏了。cart.get(id)是HashMap按key取值的典型用法时间复杂度O(1)。用商品id做key而不是用name做key是因为id在业务上唯一商品名可能会有同名不同规格的情况。cart.put(id, new CartItem(...))之后购物车Map必须通过session.setAttribute(cart, cart)写回Session否则这个Map只是局部变量这个方法一结束就没了下一次请求又得新建。这是新手最容易漏的一行漏掉的表现就是购物车永远只有最后加的一件商品。最后response.sendRedirect(request.getContextPath() /ShowCartServlet)getContextPath()返回当前应用的context路径例如/shop010这样拼接出来的地址在应用改名部署时依然正确。重定向会造成一次额外的浏览器往返性能上多一次HTTP请求但换来了地址栏正确和防止重复提交这个取舍在课程设计和小型项目中是划算的。3.4 ShowCartServlet手拼HTML表格的写法与边界展示购物车的Servlet逻辑更简单从Session拿购物车Map遍历拼表格输出总金额。完整代码如下package com.shop; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; WebServlet(/ShowCartServlet) public class ShowCartServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 从Session中取出购物车没有购物车则按空处理避免空指针 HttpSession session request.getSession(); MapString, CartItem cart (MapString, CartItem) session.getAttribute(cart); out.println(html); out.println(headmeta charsetUTF-8title我的购物车/title/head); out.println(body); out.println(h2我的购物车/h2); out.println(table border1); out.println(trth商品名称/thth单价/thth数量/thth小计/th/tr); double total 0; if (cart ! null) { for (CartItem item : cart.values()) { double subtotal item.getSubtotal(); total subtotal; out.println(trtd item.getName() /tdtd item.getPrice() /tdtd item.getCount() /tdtd subtotal /td/tr); } } out.println(/table); out.println(p购物车总金额 total 元/p); out.println(pa hrefshop.html继续购物/a/p); out.println(/body); out.println(/html); } }手拼HTML是这个时代看着很土但依然有效的servlet基本功它逼着你把字符串拼接和HTML结构在脑子里同时过一遍。写这段时有三个边界点要守住。第一cart null的判断必须放在遍历之前。用户第一次进入购物车页面时Session里根本没有cart这个属性不判空直接for (CartItem item : cart.values())会抛NullPointerException页面直接500。我见过太多servlet入门代码栽在这一行。第二商品名称如果是用户输入的数据直接拼进HTML有脚本注入风险。比如商品名叫scriptalert(1)/script浏览器会把这段内容当脚本执行。练习阶段商品名是写死的风险为零但你要知道边界在哪。常见的做法是写一个escapeHtml小方法把、、、替换成对应的HTML实体再拼进页面。第三response.setContentType(text/html;charsetUTF-8)要在getWriter()之前调用并且要放在方法最前面。顺序反了输出流已经按默认编码写出一部分数据再设置charset就不会生效页面会出现乱码。这个坑在后面第4章还会碰到一次。3.5 web.xml注册与WebServlet注解怎么选上面两个Servlet都用了WebServlet注解这是Servlet 3.0规范引入的方式Tomcat 7及以上支持。如果你把代码放进Tomcat 6或更老的环境注解不生效就必须回退到web.xml注册。两种方式等价写法如下?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee version3.1 servlet servlet-nameAddCartServlet/servlet-name servlet-classcom.shop.AddCartServlet/servlet-class /servlet servlet-mapping servlet-nameAddCartServlet/servlet-name url-pattern/AddCartServlet/url-pattern /servlet-mapping servlet servlet-nameShowCartServlet/servlet-name servlet-classcom.shop.ShowCartServlet/servlet-class /servlet servlet-mapping servlet-nameShowCartServlet/servlet-name url-pattern/ShowCartServlet/url-pattern /servlet-mapping /web-app用web.xml时要注意servlet-name在两处必须完全一致包括大小写否则启动时Tomcat会报Servlet [名字] does not contain class definition实际表现是访问URL时404。注解方式虽然省事但要是你手上的Tomcat版本升级到10以上Servlet包名从javax.servlet改成了jakarta.servlet代码里所有import javax.servlet.*都会编译失败这一步换包名的操作是Tomcat 10迁移最常见的翻车点。这个项目源码里用的是javax包建议直接用Tomcat 8或9跑省心。4. 避坑与排查中文乱码、Session丢失、IDEA配置这三关servlet购物车这个体量的项目能踩的坑翻来覆去就那么几个。这一章把我实际排过的五类问题按现象-原因-解决写清楚你在自己的环境里遇到同类问题可以照方抓药。4.1 商品名显示成涓績鎶€鏈一类的乱码现象商品展示页正常点添加到购物车之后购物车表格里的商品名称完全不可读价格和数量正常。第一种情况是整个项目从商品名到页面全是乱码第二种情况是只有从URL传过来的中文乱码英文和数字正常。原因乱码只发生在GET请求的URL参数上。HTML页面用UTF-8编码浏览器打开shop.html时点击链接里的中文字符会按页面编码处理发出的URL参数是UTF-8字节而Tomcat在解析URL参数时使用的解码字符集不匹配。Tomcat 7及以下版本默认用ISO-8859-1解码URL参数UTF-8的中文字节被按ISO-8859-1读出来就成了涓績鎶€鏈这类乱码。Tomcat 8.0开始默认URIEncoding改为UTF-8所以同样是这段代码在Tomcat 8上可能不出现这个问题在Tomcat 7上必现。解决两个方向都行。改Tomcat配置在conf/server.xml的Connector节点上加URIEncodingUTF-8一劳永逸但只对当前这个Tomcat生效换个Tomcat又得改一次改代码在AddCartServlet里手动按ISO-8859-1取回原始字节再转回UTF-8String name new String(request.getParameter(name).getBytes(ISO-8859-1), UTF-8);注意这段代码只在Tomcat默认解码确实为ISO-8859-1时有效。如果你用的是Tomcat 8参数已经是UTF-8解码的再用这个写法反而会把中文转成乱码。我的习惯是先确认容器版本Tomcat 7及以下用回解方案Tomcat 8以上保持原样。更彻底的做法是从链接里去掉中文参数商品名由Servlet根据id去商品数据源里查URL只传id这样从根本上绕开URL参数中文编码问题。这个设计也顺带消除了价格被篡改的风险是一举两得的改造。4.2 购物车加完东西关掉浏览器重开就什么都没了现象点添加到购物车后一切正常购物车表格显示完整但换个浏览器标签、或者把浏览器完全关闭再打开购物车空了。还有一种情况购物车在开发时好好的第二天重新启动Tomcat继续开发购物车里的旧数据全没了。原因第一条链路的断点在JSESSIONID。Session能识别同一个用户依赖浏览器每次请求带上服务端下发的JSESSIONID Cookie。如果浏览器设置了清除浏览数据或禁用了CookieSession就找不回来购物车自然消失。第二条链路更隐蔽Session对象默认是存在Tomcat内存里的Tomcat进程一重启所有Session对象被清空购物车当然跟着没了。这是Session方案的天然局限——它不是持久化存储只是内存里的临时数据。解决先判断是哪种情况。如果只是关闭浏览器后消失这是正常的Session生命周期购物车本身就不该跨会话存活除非你把它存进数据库。让Session存活更久的做法是在web.xml里配置超时时间session-configsession-timeout30/session-timeout/session-config单位是分钟但刷新链接、重新部署都救不了重启后丢失。要跨重启保留购物车只能把购物车数据同步写进数据库服务重启后从数据库恢复。课程设计阶段一般不做这步但要清楚这个边界。排查的时候可以顺便验证一下Session是按用户隔离的这件事同一台电脑开两个不同浏览器比如Chrome和Edge各自访问shop010各自添加商品两个购物车互不干扰。反过来如果开两个浏览器看到同一个购物车那Session机制就有问题了第一个要怀疑的是Cookie被禁用后服务端是否还在用URL重写。4.3 IDEA运行javaweb项目配置Tomcat页面404与Servlet 500现象把项目导入IDEA后点击运行Tomcat浏览器访问http://localhost:8080/shop010/shop.html返回404。或者页面能打开但一点添加到购物车就报404或500。这是idea运行javaweb项目配置里被问得最多的一类问题我自己也在这上面翻过车。原因404分两种。第一种是应用本身没部署对IDEA里配置Tomcat时Application context应该设为/shop010Artifact选择shop010:war exploded如果context留成/那你得访问http://localhost:8080/shop.html才对访问/shop010/shop.html自然404。第二种是部署了但路径不对用相对路径AddCartServlet从shop.html发起请求是最稳的一旦你写死/AddCartServletcontext又是/shop010实际请求会被拼成/AddCartServlet而不是/shop010/AddCartServlet也会404。500通常是Servlet类本身加载失败导致的后面4.5节单独说。解决在IDEA的Run Configuration里按下面三点检查Deployment标签下确认Artifact选择了当前项目的war explodedApplication context填/shop010Server标签下选好本地Tomcat的安装目录JDK版本要和项目编译级别匹配启动后去IDEA的Output窗口看Tomcat日志搜Deployment of web application确认应用成功启动看到Completed deployment再开浏览器。页面能打开但servlet 500时去Tomcat日志里看Exception堆栈最常见是ClassNotFoundException: javax.servlet.http.HttpServlet说明Tomcat版本和代码包名对不上把Tomcat换成8或9即可。提示浏览器缓存也会造成改了代码没生效的假象。servlet输出的是动态HTML但有些浏览器会缓存带queryString的动态请求排查时先开无痕窗口或者强制刷新CtrlShiftR。4.4 同一个商品点了十次购物车表格里出现十行现象第一次点击商品001购物车一行再点商品001购物车变成两行商品名称和价格相同数量都是1。预期是同一行商品数量变成2但实际是重复条目。原因最可能的问题是购物车没按商品id聚合存的是List而不是Map。用ListCartItem时每次点击都list.add(new CartItem(...))不做任何查重十个请求就有十条记录。第二种可能是用了Map但判断条件写反了if (item ! null)才put新条目结果是第一个商品永远放不进去或者每次put都覆盖旧值。第三种可能是Session存取没有配对AddCartServlet每次从Session取mapput之后忘了setAttribute写回导致本次点击只对当次请求的局部变量生效下次请求又拿到旧的空map。解决改用MapString, CartItem商品id做key核心判断就三行CartItem item cart.get(id); if (item null) { cart.put(id, new CartItem(id, name, price, 1)); } else { item.setCount(item.getCount() 1); }这几行的逻辑要口算一遍第一次点001Session里没有购物车新建Mapmap里没有001put一个数量为1的条目第二次点001map里已经有001了取出这个CartItem把它的count由1改成2不新增条目。只要Map和count加一两条写对这个场景就不会翻车。检查时重点看两处cart.get(id)用的key是不是和URL传来的id一致类型不一致比如一个String一个Integer会导致永远get不到已存在的商品以及session.setAttribute(cart, cart)是否每次都执行。4.5 改完代码重新部署页面还是旧输出现象改了ShowCartServlet里表格标题重启Tomcat打开页面看到的还是改之前的旧标题。有人会怀疑Tomcat缓存于是清浏览器缓存、重启IDEA问题依旧。原因这是Eclipse或IDEA下最常见的编译产物与部署目录不同步。项目源码编译后的class输出到了build/classes而Tomcat实际加载的是部署目录下WEB-INF/classes里的class。IDE的自动编译有时没有把最新的class同步过去或者部署选项里勾选了仅当代码变化时更新但Tomcat对已加载的Servlet类不会自动替换。还有一种情况是Tomcat的webapps下还残留一份旧的shop010目录新部署被跳过或覆盖失败。解决操作顺序按三步走。第一步在IDE里执行一次Project Clean让所有class重新编译第二步确认编译输出目录正确Eclipse项目右键Properties - Java Build Path - Output folder改成shop010/build/classes保证src下的源码确实编译到这个目录第三步部署前手动删除Tomcat的webapps目录下对应的旧应用文件夹再重新Deployment。这几步做完还不行就直接把Tomcat完全停掉再启动而不是点Reload。以后我拿到任何servlet老项目第一件事就是把编译输出和部署目录对应关系核一遍这个习惯能省掉至少一小时的瞎排查时间。5. 从能跑到好用一张验证清单和一个MySQL升级方向项目能跑起来只是第一步你得有一套方法确认它真的对了再决定要不要继续往上加功能。先给一份手工验证清单我每次拿到servlet购物车项目都会按这个流程过一遍等于给你一张现成的测试用例表序号操作步骤预期结果1打开shop.html商品表格显示无乱码2点击商品001添加到购物车跳转到购物车页出现一行记录数量13点击继续购物返回再点商品001购物车页同一行商品数量变成24点击商品002购物车新增加一行两行共存5在购物车页按F5刷新页面重新展示数量不增加6换一个浏览器打开应用添加商品另一个浏览器的购物车看不到前一个浏览器的商品7查看Tomcat日志无堆栈异常无HTTP状态码报错第3条和第5条是重点分别验证了Map聚合和重定向防重复提交这两条过了这个项目的核心逻辑就稳了。第6条是Session按用户隔离的实证也是你向别人讲解这个项目时的硬证据。如果还想往上走一步最值得做的升级是把商品数据从HTML写死改成MySQL存储。这也是javaweb项目完整案例mysql这条热词指向的进阶路径建一张product表在AddCartServlet里根据id从数据库查出商品名和价格URL里只传id彻底解决中文乱码和价格篡改两个隐患。核心代码就一段JDBC查询String sql SELECT name, price FROM product WHERE id ?; try (Connection conn DriverManager.getConnection(url, user, password); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, id); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { name rs.getString(name); price rs.getDouble(price); } } }注意PreparedStatement的setString是按类型传参和字符串拼接相比既避免了SQL注入也免去了手动给中文加引号的麻烦。数据库连接串里的user、password建议抽到配置里不要直接写死在Servlet里这是从练习项目往工程化项目过渡时要养成的第一个习惯。至于购物车本身要不要同步存MySQL我的看法是课程设计阶段不需要Session内存方案足够说明问题如果指导老师要求跨登录保留购物车再上购物车表把Session里的Map在每次添加后同步写库展示时优先读库。这个改造做完你的项目就从能演示变成了能下结论说清楚为什么这样设计。从那以后我每次拿到这类servlet小项目都会强制自己先跑一遍上面七条验证清单再决定改哪里而不是打开页面看到能出表格就觉得完工。希望帮到你。本文还有配套的精品资源点击获取
返回列表