尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

JSP购物车项目实战:SQL Server环境搭建与避坑指南

JSP购物车项目实战:SQL Server环境搭建与避坑指南 简介一份基于JavaJSP与SQL Server的购物车Web应用源码包适合正在学习Java Web开发、需要完成课程设计或入门电商项目的开发者。资源包共35个文件包含10个JSP页面、1个Java类及对应class文件以及SQL Server数据库文件MDF/LDF、图片和Flash素材等既覆盖注册、登录、商品展示、购物车与结算等核心页面也提供可直接附加的数据库文件便于还原运行环境。包体仅约381KB典型的小型教学项目结构简洁适合对照学习JSP/Servlet与JDBC连接数据库的完整流程。已有205人学习下载。通过学习可以理解购物车会话管理、SQL Server表设计与数据操作、PreparedStatement防注入等关键知识点同时参考界面设计与前后端交互方式对完成同类实训作业或快速搭建原型有直接帮助。1. 一个能跑的 JSP 购物车为什么值得花时间拆它做课程设计或刚接触 Java Web 的人最怕的不是不会写代码而是拿到一个号称“完整项目”的压缩包解压后一堆.jsp和.class连数据库都连不上。这个 JSP 购物车SQL Server 版是典型的单体 Java Web 项目前端用 JSP 输出页面业务逻辑放在 Java Bean 里数据落在 SQL Server 的 MDF 文件中。压缩包里能看到index.jsp、login.jsp、purchase.jsp这些核心页面以及Web_Data.MDF和Web_Log.LDF两个数据库文件也就是说它是带库的完整实例不是那种只有页面没有数据库的花架子。如果你正在找 Java SQL Server 的购物车实现这篇笔记能帮你把它跑起来顺便把数据库附加、JDBC 连接、session 存购物车这些绕不开的坑点讲透。2. 环境搭建与数据库还原从附加 MDF 到 JDBC 连通拿到压缩包第一步不是急着看代码而是把运行环境理清楚。这个项目是 JSP SQL Server 的老组合环境版本不一定要新关键要让驱动、数据库服务和 JDK 三者对得上。2.1 环境选型JDK、Tomcat、SQL Server 怎么搭配我拆这类老项目时习惯先把版本定死在“够用”的档位JDK 1.8Tomcat 8.5SQL Server 用 2008 R2 或 2012 都可以JDBC 驱动用sqljdbc4.jar或更高版本。这个组合的好处是兼容性好Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver)这种老写法照样能跑。如果你手头只有 SQL Server 2016/2017/2019也不是不行但注意两点一是安装时如果报“无法找到数据库引擎启动句柄”先去检查服务的登录身份把 SQL Server 服务改成“本地系统”或“网络服务”再重启服务这个报错多半是服务权限问题二是高版本 SQL Server 默认禁用了 sa 登录和 TCP/IP 协议后面连接时会踩坑。所以我自己宁愿用低版本虚拟机来跑这种项目省时间。Tomcat 方面不要用 10.x 以上的版本因为 JSP 和 Servlet 的包名从javax变成了jakarta老项目里的 import 会直接报错。老老实实用 Tomcat 8.5它就是为这类项目准备的。2.2 附加 Web_Data.MDF两种方式都要会解压后数据库文件是Web_Data.MDF和Web_Log.LDF。这是 SQL Server 的主数据文件和日志文件不能直接拷贝到 Data 目录下就算完事必须“附加”到实例中。最常见做法是打开 SQL Server Management Studio连接到实例后右键“数据库”节点选择“附加”然后添加Web_Data.MDF文件。但如果你的机器权限有问题或者文件是从压缩包直接拖出来的界面附加很容易报“拒绝访问”。所以我更喜欢用 SQL 命令来处理在 SSMS 新建查询窗口执行USE [master] GO CREATE DATABASE [Web_Data] ON (FILENAME NC:\path\to\Web_Data.MDF), (FILENAME NC:\path\to\Web_Log.LDF) FOR ATTACH GO命令里C:\path\to\Web_Data.MDF要换成你解压后的实际绝对路径建议路径里不要带中文也不要有空格SQL Server 对路径的处理有时候很敏感。执行成功后刷新数据库列表能看到Web_Data库里面应该包含商品表、用户表、订单表之类的业务表。如果附加时报错最常见的两个原因一是 LDF 和 MDF 不匹配二是文件只读或权限不足。解决办法是把这两个文件的属性改成可读写并且给 SQL Server 服务账户添加“完全控制”权限然后再执行附加命令。这个动作看起来不起眼但没做对的话后面的连接全都会卡在“数据库不可用”上。2.3 配置 JDBC 连接驱动、连接串、账户三件事数据库附加好之后再看代码里怎么连库。这个项目的连接信息一般写在 Java Bean 或 JSP 页面的初始化代码里也有可能是独立的配置文件。我拆包时习惯先搜SQLServerDriver和jdbc:sqlserver这两个关键字把连接串找出来。如果是自己重建连接配置最典型的写法是这样的Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver); String url jdbc:sqlserver://localhost:1433;DatabaseNameWeb_Data; String user sa; String password 123456; Connection conn DriverManager.getConnection(url, user, password);这里几个参数要特别注意localhost是数据库服务器地址如果连的是本机可以这么写连远程就换 IP1433是 SQL Server 默认端口如果你的实例改了端口这里要跟着改DatabaseNameWeb_Data必须和附加的数据库名完全一致user和password是 SQL Server 的登录账户常见做法是用 sa 加你自己设的密码。连接之前还要确保两件事把sqljdbc4.jar放到WEB-INF/lib下以及在 SQL Server 里启用了“SQL Server 身份验证模式”。如果这两步没做代码再对也连不上。尤其是驱动 jar很多人只把它放到 Tomcat 的 lib 目录但项目在 IDE 里运行时会优先使用WEB-INF/lib下的包加载不到就会报ClassNotFoundException。驱动加载成功、连接建立之后可以用一行测试代码验证System.out.println(conn.isClosed() ? 连接失败 : 连接成功);输出“连接成功”说明环境已经没问题可以往下看业务代码了。3. 核心流程拆解注册、登录、加购与结算的实现逻辑环境通了之后再看这个购物车项目是怎么把页面和数据库串起来的。压缩包里的文件不算多但 JSP 页面之间的跳转、session 的用法、SQL 的写法都很典型。3.1 从 index.jsp 开始页面资源与入口关系index.jsp通常是首页也是整个项目的入口。打开这个文件你会看到商品图片、商品列表、加入购物车的链接。压缩包里有bb1.jpg、bb2.jpg、bb3_1.jpg这一批图片看命名像商品图还有logo.jpg、lucky.swf、denglu.gif这些是页头、登录入口和 Flash 装饰。我拆这种包的时候会先把 JSP 页面里所有的a href和form action列出来理清页面之间的跳转关系。以这个项目为例index.jsp列表页点击商品会跳到purchase.jsp登录入口指到login.jsp注册入口指到register.jsp。而do_register.jsp是处理注册请求的后台逻辑页register_confirm.jsp则是注册成功后的反馈页面。这种“展示页 处理页 确认页”的命名方式是老 JSP 项目最常见的套路。这里有个识别小技巧看文件名有没有do_前缀有的话基本就是接收表单数据的处理页不会直接展示给用户。do_register.jsp就是典型它从 request 里拿参数写完数据库后再forward或redirect到register_confirm.jsp。3.2 注册与登录do_register.jsp 的表单处理注册功能的逻辑是用户在register.jsp填写用户名、密码、邮箱等信息表单提交到do_register.jsp这个页面负责把数据写入 SQL Server 的 user 表然后跳转到register_confirm.jsp显示成功信息。典型的表单代码通常长这样form actiondo_register.jsp methodpost 用户名input typetext nameusername / 密码input typepassword namepassword / 确认密码input typepassword nameconfirmPassword / input typesubmit value注册 / /formmethodpost是为了避免用户名和密码出现在地址栏这个在购物车类项目里是标配。接收端用 request.getParameter 取值但要注意编码问题如果页面是 UTF-8Tomcat 默认按 ISO-8859-1 解析 post 参数中文就会乱码。常见做法是在页面顶部加% page contentTypetext/html;charsetUTF-8 pageEncodingUTF-8 % % request.setCharacterEncoding(UTF-8); %第一行设置响应编码第二行是告诉 Tomcat 用 UTF-8 来解析请求体。这两行最好每个 JSP 都加上否则注册的用户名是中文时写入数据库就会变成乱码。这也是为什么很多人照着教程做用户名却变成??的原因。登录逻辑一般写在login.jsp里有的是表单和处理逻辑写在一起。判断用户是否存在用一条 SQL 就能完成SELECT COUNT(*) FROM users WHERE username ? AND password ?查出来大于 0就说明账号密码正确可以把用户名放到 session 里否则返回错误提示。这里建议用 PreparedStatement 而不是直接拼字符串原因后面第五章会说。3.3 购物车核心purchase.jsp 的 session 操作purchase.jsp是这个项目最核心的页面。压缩包里同时有purchase.jsp、刚改purchase.jsp和原来purchase.jsp说明作者在改 bug 或加功能时保留了多个版本。这点很常见也从侧面说明购物车逻辑容易改出问题。购物车的经典实现是把商品 id 和数量存在 session 的一个 Map 里每次用户点“加入购物车”就往 Map 里放一条记录。示意代码如下// purchase.jsp 中的核心逻辑示意 HttpSession session request.getSession(); String goodsId request.getParameter(goodsId); int quantity 1; if (request.getParameter(quantity) ! null) { quantity Integer.parseInt(request.getParameter(quantity)); } MapString, Integer cart (MapString, Integer) session.getAttribute(cart); if (cart null) { cart new HashMapString, Integer(); } cart.put(goodsId, quantity); session.setAttribute(cart, cart);这里有个非常容易翻车的点Integer.parseInt在参数不是数字时会抛NumberFormatException。很多初学者直接从商品列表页面传quantity1没问题但如果你在“修改数量”功能里没做非数字校验用户在输入框里乱填一个abc整个页面就会报 500。所以正规写法是先判断参数能不能转成数字用try-catch包住或者先正则校验一下。购物车信息存 session 之后接下来是结算逻辑。老项目里常见做法是遍历 session 里的 Map去数据库查询每个商品的最新价格再计算总价。这里注意不要把商品价格直接存在 session 里因为用户下单前商品价格可能调整过要以数据库价格为准。操作顺序是先查价格再算总金额最后把订单写入数据库。这个项目没有下单页面结算逻辑很可能写在purchase.jsp后半段或者以index.jsp里的“购买”链接直接调用。如果你想把它改成完整的商城需要补一个订单表把 session 中的数据逐条插入订单详情表这一步扩展会在第六章再讲。4. 避坑实录SQL Server 连接、乱码与路径问题的五个排查案例这个项目我完整跑过一遍遇到了不少问题。下面这几条是典型的、网上问得最多、也最容易让新人卡住的问题每一条我都按“现象 → 原因 → 解决”的格式列出来。4.1 驱动加载失败ClassNotFoundException现象Tomcat 启动后访问首页控制台报java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver。原因驱动 jar 没有放到WEB-INF/lib目录下。很多人把sqljdbc4.jar放到了 Tomcat 的lib目录或者只是引入了 IDE 的 classpath但没有进入最终部署的 webapp 目录。解决把sqljdbc4.jar拷贝到项目WebContent/WEB-INF/lib如果你用的是 Eclipse或者src/main/webapp/WEB-INF/libMaven 结构。如果是 IDEA还要确认它被添加到 Artifact 里。做完之后重新部署、重启 Tomcat而不是只点刷新。4.2 数据库附加不上显示“拒绝访问”现象在 SSMS 里附加Web_Data.MDF时提示无法打开物理文件拒绝访问。原因压缩包里的文件被 Windows 标记为只读或者文件目录对 SQL Server 服务账户没有读取权限。前者是文件属性后者是目录安全策略。解决先把文件从解压目录复制到一个新文件夹比如D:\sql_data\右键属性把“只读”去掉然后给该文件夹添加“Authenticated Users”完全控制权限。再重新执行附加命令。这个方法对 LDF 和 MDF 都适用。另外不要直接在压缩软件里双击打开 MDF一定要先解压出来。4.3 登录后中文乱码现象注册的用户名是中文但数据库里存的是???或者页面上显示乱码。原因Tomcat 8 之前默认使用 ISO-8859-1 解析请求参数而 JSP 页面是 UTF-8两边不一致导致中文乱码。高版本 Tomcat 在 get 请求上默认 UTF-8但 post 请求仍然可能有问题。解决在每个 JSP 页面顶部加request.setCharacterEncoding(UTF-8);并且在 web.xml 里配置一个字符编码过滤器CharacterEncodingFilter来统一处理。如果是 get 请求又要保证 Tomcat 的useBodyEncodingForURItrue。最省事的做法是所有页面统一 UTF-8数据库表字段用nvarchar连接串加characterEncodingUTF-8。4.4 商品图片不显示现象首页能打开但商品图片全部是破图标浏览器控制台显示 404。原因图片路径写成了/images/bb1.jpg这是相对于服务器根目录的绝对路径。如果部署上下文根是/JspShoppingCart那么/images/bb1.jpg会被解释成http://localhost:8080/images/bb1.jpg而不是http://localhost:8080/JspShoppingCart/images/bb1.jpg。解决在 JSP 页面里用${pageContext.request.contextPath}拼接图片路径或者在img标签中写相对路径。示意img src${pageContext.request.contextPath}/images/bb1.jpg /另外还要确认images目录在WEB-INF外面放在WebContent下的images文件夹中。放在WEB-INF里的话浏览器是访问不到的。4.5 SQL Server 登录失败sa 无法登录现象代码里用sa和密码连接数据库报Login failed for user sa或者连接超时。原因第一SQL Server 只启用了 Windows 身份验证没有启用 SQL Server 身份验证第二sa 的密码跟代码里写的不一致第三TCP/IP 协议没有启用或者端口不是 1433。解决在 SSMS 实例上右键选择“属性”找到“安全性”把服务器身份验证改为“SQL Server 和 Windows 身份验证模式”然后在安全-登录名中找到 sa设置密码并启用登录最后打开“SQL Server 配置管理器”查看 SQL Server 网络配置中的 TCP/IP 是否启用。注意改完这些都需要重启 SQL Server 服务很多人在这一步忘了重启导致怎么改都连不上。5. 安全与性能加固PreparedStatement、Session 与索引怎么改项目能跑起来只是第一步这章讲怎么把它改成一份能交给老师、或者能部署到生产环境的样子。重点说四个方向防注入、会话持久化、数据库索引、密码存储。5.1 用 PreparedStatement 替换 Statement防注入的第一道门老 JSP 项目里用拼接 SQL 的情况很常见比如String sql SELECT * FROM users WHERE username username AND password password ; Statement st conn.createStatement(); ResultSet rs st.executeQuery(sql);这段代码最大的问题是 SQL 注入。如果用户在用户名输入框填 OR 11拼出来的 SQL 就变成了SELECT * FROM users WHERE username OR 11 AND password这一下就把整个用户表的数据都查出来了。正确做法是用 PreparedStatementString sql SELECT * FROM users WHERE username ? AND password ?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery();?是占位符setString方法会把传入值当成纯字符串处理单引号会被转义从而破坏拼接结构。这个改动很小但对安全性的提升非常大。凡是涉及用户输入的 SQL都应该用 PreparedStatement没有例外。5.2 Session 购物车还是 Cookie 购物车单体场景怎么选这个项目用的是 session也就是把购物车数据放在服务器内存里。这样做的好处是数据在服务器端用户改不了逻辑也简单。坏处是服务器重启后购物车清空而且多台服务器之间无法共享 session。如果只是课程设计session 完全够用。但如果你想做“在过期后还能恢复”的效果可以把购物车序列化到数据库里的 cart 表或者在 Cookie 里存购物车 id再在数据库中查。我不建议在 Cookie 里存整个购物车因为商品数量和价格很容易被用户篡改。正确做法是session 里只存用户名购物车数据在访问时从数据库重新加载。这样一个改动能让你把“购物车存内存”升级成“购物车落表”后面下订单也顺理成章。5.3 数据库索引与表结构避免全表扫描购物车项目表通常不大但商品表可能会随着图片、描述字段变宽。如果商品表经常按分类查、按价格排序可以给分类字段和价格字段加索引。比如CREATE INDEX idx_goods_category ON goods(category_id); CREATE INDEX idx_goods_price ON goods(price);索引不是越多越好。写操作频繁的表索引过多会导致插入和更新变慢。对于这种小项目只需要给查询条件的字段加索引就行尤其是购物车结算时要根据商品 id 查价格商品表主键本来就带索引一般不用额外处理。这里要注意SQL Server 里对nvarchar字段加索引时如果字段长度很长可能超出索引键限制解决办法是只对前缀建索引但在这个项目里基本用不到。5.4 密码明文问题至少做一次哈希登录和注册页面的密码如果直接存明文数据库被拖库后用户密码就全暴露了。常见做法是用 SHA-256 做哈希虽然不算最安全但至少能挡住大多数问题MessageDigest md MessageDigest.getInstance(SHA-256); byte[] hash md.digest(password.getBytes(UTF-8)); StringBuilder sb new StringBuilder(); for (byte b : hash) { sb.append(String.format(%02x, b)); } String hashedPassword sb.toString();注册时把hashedPassword存入数据库登录时把用户输入的密码再做一次同样的哈希然后比对数据库里的值。注意这里忘了加盐只是最基础的改造。如果有余力可以用BCrypt这种专门的哈希算法盐值会自动嵌入到结果里。另外把哈希计算放在 JSP 页面里是很丑的写法建议把这段逻辑抽到一个UserUtil类里然后在 Servlet 或 bean 里调用。这个项目本身用 Java Bean把工具类放进classes目录下的 bean 包中页面里直接% UserUtil.hashPassword(password) %这样的方式当然能用但正规一点是封装成静态方法并保持 JSP 里尽量少出现 Java 代码。6. 最后再验一遍把项目跑通后我习惯做的三件事项目跑起来不等于交付。我每次拿到这种改造完的项目都会从头到尾走一遍“新用户完成一单”的流程并且把最容易出问题的地方列成一个检查清单。第一件事从index.jsp点开一个商品加入购物车然后立刻去看 session 里有没有数据。常用的验证方法是在浏览器开发者工具里查看 Cookie确认JSESSIONID存在。如果购物车在页面跳转后清空先检查purchase.jsp里有没有调用session.invalidate()或者在页面之间跳转时是不是用了response.sendRedirect导致 session 丢失。第二件事测试非正常输入。在修改数量的输入框里填abc看页面是否报错在用户名输入框里填admin OR 11看是否还能登录。这两条能快速判断代码有没有做好防注入和类型校验。很多项目看起来功能正常但一测就炸问题大多出在这。第三件事把数据库连接信息放到一个配置文件里不要散落在各个 JSP 页面中。我习惯建一个db.propertiesjdbc.drivercom.microsoft.sqlserver.jdbc.SQLServerDriver jdbc.urljdbc:sqlserver://localhost:1433;DatabaseNameWeb_Data jdbc.usernamesa jdbc.passwordyour_password然后在 Java Bean 里用java.util.Properties加载这个文件。这样部署到别的机器时只需要改一个文件不用在十几个 JSP 页面里翻找密码。这时候再导出 WAR 包放到 Tomcat 的 webapps 下才算是真正可交付的状态。有一次我就吃过亏项目在本地跑得很顺部署到服务器后一直报“数据库连接失败”最后发现是服务器上的 SQL Server 端口不是 1433而我硬编码在代码里的连接串没改排查了一个多小时。从那以后我每次部署前都强制走一遍上面的检查清单尤其是连接配置和端口确认无误再打 WAR 包。希望帮到你。本文还有配套的精品资源点击获取
返回列表