基于JSP技术的网上购物系统设计与实现.doc
基于JSP技术的网上购物系统设计与实现摘要:本课题主要阐述采用JSP实现网上购物系统的过程。采用Dreamweaver开发工具和JDBC技术操作数据库,以及采用Mircrosoft SQL Server 2000作为后台数据库实现该系统,并详细介绍该系统的开发过程以及与该系统技术实现有关的知识。关键词:jsp、jdbc、javabean、JavaScript、SQL Server一 前言随着Internet的不断普及,人们对于互联网技术的要求已不单单是浏览一下网页,收发电子邮件,日益忙碌的人们开始追求足不出户的利用互联网这一强大的平台来实现的网上购物。对于企业来讲,无论是企业之间(B to B),还是企业和客户之间(B to C)的交易,如果能够实现网上交易将大大提高交易速度、节约交易成本。我作为一名中南民族大学2005届计算机科学与技术专业的学生,对从事计算机操作和编程工作有着特殊的爱好,在学习之余,我时常钻研专业课基础理论,经常用JSP编写网页。为了在毕业之际向学校交一份满意的答卷,开发这样一网上购物系统很有必要,在下面我将以开发网上购物系统为主,论述在开发过程和所涉及到的问题及解决方法。(一) 选题背景电子商务常缩写为EC(Electronic-Commerce),有人也称为电子贸易,它是指采用网络技术实现数据的交换,从而完成整个的商业交易过程。电子商务是于九十年代初,在欧美兴起的一种全新的商业交易模式,它实现了交易的无纸化,效率化,自动化表现了网络最具魅力的地方,快速的交换信息,地理界限的模糊,这所有的一切也必将推动传统商业行为在网路时代的变革。网上购物是电子商务的具体表现,开发一个网上购物系统是十分必要。 传统的购物要到商场去买商品,经常要在收银台前面排队,很浪费时间、精力、物力、财力。网上购物是24小时开放的,不用去排队。在网上,用户还可以快速的找到自己的商品。人们生活节奏的加快,购物的效率和质量也要跟上去,开发一个网上购物系统成为解决问题的首选方案 (二) 方案论证在本次课题研究的过程中,将论述网上购物系统的JSP实现。他分为前台管理和后台管理,前台是用户购物,后台是数据管理. 管理员登录后拥有管理员权限,即有增加、删除、查询、修改记录权限。可以进行商品分类管理、商品管理、定单管理、用户管理、投诉管理。删除商品分类的时候要注意数据的完整性,当这个商品分类下有商品的时候,就不可以删除这个商品分类。增加商品的时候要选择商品所属分类。一般用户登录后拥有一般用户权限,用户输入商品名称和商品分类进行商品的查询,系统分页显示查询结果,然后用户添加商品到购物车,用户可以查看购物车情况,也可以修改购物车购物情况,当用户结帐的时候,系统在后台生成定单及该定单的名细记录,并显示要付款的金额,同时注销用户登录信息,清空购物车,释放系统资源.当用户没有登录的时候,用户只可以查看商品,不能购买商品。二 系统分析 网上购物系统采用模块化的设计方法,分为前台管理和后台管理两个模块. (一) 系统结构图 图1 系统结构图 (二) 系统模块图网上购物系统前台管理浏览商品查询商品购买商品用户注册用户投诉后台管理分类管理商品管理订单管理投诉管理用户管理图2 系统两大模块 (三) 系统流程图 在网上购物系统中,共有两个主要的流程,即前台客户购物流程和后台订单处理流程. 前台客户购物流程图:浏览商品选择商品订购商品未注册用户已登录注册用户未登录注册用户注册登录结帐生成定单购物入购物车确认个人信息图3前台管理流程图 后台订单处理流程图用户订单订单处理订单发货订单结帐订单删除图4后台管理流程图 由于在前台已经生成了定单及该定单的明细,所以可以用定单来结帐,同时订单明细是发货的重要依据,它记录了商品ID、商品单价,以及订购该商品的数量。(四) E-R图设计SortsSor_nameSor_describerSor_idProducesPro_idSor_nameSor_idPro_productoctorPro_pricePro_describerDetailsDet_idDet_priceNumberPro_id1mOrd_idOrd_totalOrd_dateUse_idOrd_checked11mTousuTou_idTouDateOrd_idUse_idTou_checked属于Use_idUse_idUse_nameUse_pwZip属于属于属于属于属于mm1m1SystemsSys_idOrd_id11AddressEmailSys_pwSys_namePhoneOrdersTou_contendTou_rs图5系统数据库E-R图(五) 数据库设计一般用户信息(用户ID、用户名、密码、用户地址、电子邮箱、邮政编码、 号码)商品分类信息(商品分类ID、商品分类名称、商品分类描述)商品信息(商品ID、商品名称、提供商、单价、商品分类ID、商品描述)定单信息(定单ID、用户ID、金额、定单日期、定单情况)定单明细信息(定单明细ID、定单ID、商品ID、单价、数量)投诉信息(投诉ID、用户ID、定单ID、投诉时间、投诉情况、投诉内容、投诉回复)系统用户信息(用户ID、用户名字、用户密码) 用户表Users列名类型是否为空描述Use_idVarchar(50)no用户IDUse_nameVarchar(50)no用户名字Use_pw_Varhcar(50)no用户密码Zipintno邮政编码PhoneVarchar(50)no 号码EmailVarchar(50)no电子邮箱AddressVarchar(50)no用户地址商品分类表Sorts列名类型是否为空描述Sor_idintno商品分类IDSor_nameVarchar(50)no商品分类名称Sor_describeVarchar(50)no商品分类描述商品表Produecs列名类型是否为空描述Pro_idintno商品IDPro_nameVarchar(50)no商品名称PriceFloatNo商品单价Pro_productorVarchar(50)no提供商Pro_describeVarchar(50)no商品描述Sor_idintno所属分类定单表Orders列名类型是否为空描述Ord_idintno定单IDOrd_totalFloatno预付金额Ord_datedatetimeno定单日期Ord_checkedbitno定单情况Use_idintno用户ID定单明细表Details列名类型是否为空描述Det_idintno定单明细IDPricefloat)no商品单价Numberintno商品数量Pro_idintNo商品IDOrd_idintno定单ID,外键投诉表Tousus列名类型是否为空描述Tou_idintno投诉IDTou_dateDatetimeNo投诉时间Tou_contendVarchar(50)no投诉内容Tou_rsVarchar(50)no投诉回复Tou_checkedbitno投诉情况Use_idVarchar(50)no用户IDOdr_idintno定单ID系统用户Systems列名类型是否为空描述Sys_idVarchar(50)no系统用户IDSys_nameVarchar(50)no用户名字Sys_pwVarchar(50)no密码数据表的具体实现:一般用户表create table Users( Use_id varchar(50) primary key, Use_name varchar(50), Use_pw varchar(50), Use_Phone varchar(50), Email varchar(50), Address varchar(50), Zip int)商品分类表create table Sorts( Sor_id int IDENTITY(1,1) primary key, Sor_name varchar(50), Sor_describe varchar(50)商品表create table Produces( Pro_id int IDENTITY(1,1) primary key, Pro_name varchar(50), Pro_productor varchar(50), Pro_price float, Pro_describe varchar(50),Sor_id int not null references Sorts(Sor_id)定单表create table Orders( Ord_id int IDENTITY(1,1) primary key, Ord_total float, Ord_date datetime, Ord_checked bit, Use_id varchar(50) not null references Users(Use_id)定单明细表create table Details( Del_id int IDENTITY(1,1) primary key, price float, Number int, Pro_id int not null references Produces(Pro_id) Sor_id int not null references Sorts(Sor_id)投诉表create table Tousu( Tou_id int IDENTITY(1,1) primary key, Tou_date datetime, Tou_contend varchar(50), Tou_rs varchar(50), Tou_checked bit, Ord_id int not null references Orders(Ord_id), Use_id varchar(50) not null references Users(Use_id)系统用户表create table Systems( Sys_id varchar(50) primary key, Sys_name varchar(50), Sys_pw varchar(50)三 系统实现网上购物系统分为前台管理和后台管理两个模块.通过前台用户可以查询商品,添加商品到购物车,浏览购物车,结帐,投诉,修改个人信息等操作,通过后台系统用户统一管理数据,有商品分类管理,商品管理, 定单管理,投诉管理,用户管理等。网上购物系统建立两个文件来分别管理前台文件和后台文件。(一)预备知识1. JSP技术介绍 JSP简介:JSP(JavaServer Pages)是由Sun Microsystem公司倡导、许多公司参与一起建立的一种动态网页技术标准。 在传统的网页HTML文件(*.htm,*.html)中加入Java程序片段(Scriptlet)和JSP标记(tag),就构成了JSP网页(*.jsp)。Web服务器在遇到访问JSP网页的请求时,首先执行其中的程序片段,然后将执行结果以HTML格式返回给客户。程序片段可以操作数据库、重新定向网页以及发送 email 等等,这就是建立动态网站所需要的功能。所有程序操作都在服务器端执行,网络上传送给客户端的仅是得到的结果,对客户浏览器的要求最低,可以实现无Plugin,无ActiveX,无Java Applet,甚至无Frame jsp九种内置对象:request, response, out, session, application, config, pagecontext, page, exception. JSP优点:简便性和有效性, 程序的平台无关性, 程序的兼容性, 程序的可重用性。 JSP工作原理:JSP 页面使用 XML 标签和 scriptlets(一种使用 Java 语言编写的脚本代码),封装了生成页面内容的逻辑。它将各种格式的标签(HTML 或者 XML)直接传递回响应页面。通过这种方式,JSP 页面实现了页面逻辑与其设计和显示的分离。JSP 技术是 Java 系列技术的一部分。JSP 页面被编译成 servlets,并可能调用 JavaBeans 组件(beans) 或 Enterprise JavaBeans 组件(企业 beans),以便在服务器端处理。因此,JSP 技术在构建可升级的基于 web 的应用程序时扮演了重要角色。JSP 页面并不局限于任何特定的平台或 web 服务器上。JSP 规范在业界有着广泛的适应性。尽管JSP本质上是Servlet,但是,这两者还是有很大不同,Servlet完全由java程序代码构成,比较适合流程控制和事务处理,但是由Servlet生成的动态网页不直观,JSP由HTML和JSP标签构成,可以方便的编写动态网页,因此在是实际的应用中,采用Servlet来控制业务流程,用JSP生成动态的网页,这在MVC设计模式中讲解。浏览器JSP容器JSP文件生成Servlet源代码经编译的Servlet类响应请求图6 JSP容器初次实行JSP的过程 MVC3设计模式: MVC是Model-View-Controller的简称,是一种软件设计模式,是被Sun公司推荐为J2EE平台的设计模式,Struts是非常流行的基于MVC的Java Web框架,在Struts框架中,JSP位于MVC设计模式中的视图.采用MVC设计模式,可以保证系统的可扩展性,可维护性. javaBean:是一种基于Java的软件组件。JSP对于在Web 应用中集成JavaBean组件提供了完善的支持。这种支持不仅能缩短开发时间(可以直接利用经测试和可信任的已有组件,避免了重复开发),也为JSP应用带来了更多的可伸缩性,2. JDBC技术介绍 Java的开发者Sun的Javasoft公司指定的java数据库连接(java DataBase Connectivity)技术的简称,是为各种常用数据库提供无缝联接的技术。JDBC为Java程序提供了一个统一无缝地操作各种数据库的接口,程序员编程时,可以不关心它所要操作的数据库是哪个厂家的产品,从而提高了软件的通用性,而且在Internet上确实无法预料你的用户想访问什么类型的数据库。只要系统上安装了正确的驱动器程序,JDBC应用程序就可以访问其相关的数据库JDBC对象的功能:Connection对象。代表与数据库的连接。连接过程包括所执行的 SQL 语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。DriverManager类。是 JDBC 的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。另外,DriverManager 类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务Statement 对象。用于将 SQL 语句发送到数据库中。实际上有三种 Statement 对象,它们都作为在给定连接上执行 SQL 语句的包容器:Statement、PreparedStatement和 CallableStatementResultSet对象。包含符合 SQL 语句中条件的所有行,并且它通过一套 get 方法(这些 get 方法可以访问当前行中的不同列)提供了对这些行中数据的访问。PreparedStatement接口。PreparedStatement 实例包含已编译的 SQL 语句。这就是使语句“准备好”。包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。CallableStatement 对象。为所有的 DBMS 提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是 CallableStatement对象所含的内容。JDBC的核心是Connection、DriverManager、Statement、ResultSet对象。首先用Connection与服务器建立连接,然后用Statement对象执行命令,如查询、更新等。用ResultSet对象来操作查看查询结果。(二) 程序实现1. 可重用模块的设计. 连接及操作数据库1 MyConn.java,由于许多页面都要进行数据库连接,对数据库进行插入、查询、更新、修改等操作.把这些操作封装在一个组件模型javabean中.该类提供了对外的接口,用户只要调用这个接口,不用考虑它内部的具体实现. 由于许多页面要判断用户是否登录及用户的权限.可以把它单独做为一个文件,其他页面只要包含他就可以了. 它的作用是方便用户在整个网站进行漫游. 导航条有购物查询、查看购物车、我要投宿、查看投宿、个人信息、后台管理、添加到文件夹、退出等功能。这些功能又可以分成更小的功能。比如后台管理包括:管理员登录,商品分类管理,商品管理,定单管理,投诉管理,用户管理,注销等。2管理主界面与登录程序设计 管理员登录的实现系统用户在此登录.并把登录信息保存让其他页面使用.登录成功就进入后台管理的主页面,不成功就返回,让用户重新登录,界面如下: 图7 管理员登录具体代码如下:<jsp:useBean id="mdb" scope="page" class="myconn.MyConn"/><%ResultSet rs=null;String denglu=null,sql=null,sys_id=null,sys_pw=null;denglu=request.getParameter("denglu");if(denglu!=null) denglu=new String(denglu.getBytes("ISO8859_1"); if(denglu.equals("登录") sys_id=request.getParameter("sys_id"); sys_pw=request.getParameter("sys_pw"); sql="select * from Systems where sys_id='"+sys_id+"' and sys_pw='"+sys_pw+"'" rs = mdb.executeQuery(sql); if(rs.next()session.putValue("ifadmin","yes");response.sendRedirect("index.jsp"); else session.putValue("err","err"); response.sendRedirect("reg.jsp"); else String err=(String)session.getValue("err"); if(err!=null) err=".error." session.removeAttribute("err"); else err="" %> 管理主界面的设计permit.jsp 用户进入后台管理模块,必须要严格的审核用户权限和登录情况,进入后台管理模块的任何一个子模块也要严格的审核用户权限和登录情况,这是为了防止用户不登录就进入子模块。例如当用户没有登录,就想打开定单处理模块,他是进不去的,系统自动的把页面转到系统管理员登录页面,这个页面主要是防止用户的非法访问。left.jsp 是一个可以重用的页面.包括了多个超级链接,每个链接对应一个模块.有商品分类管理、商品管理、用户定单管理、用户投诉管理、一般用户管理、系统用户管理、注销系统等.每个模块又分为更小的模块。 这是管理主界面,主界面由left.jsp和右边显示部分组成,同时也包含了permit.jsp文件,右边默认显示的是商品分类管理页面。管理主界面如下: 图8 管理主界面3. 商品查询及购买商品查询find.jsp 提供了查询商品的功能.用户输入商品名称和选择商品所属分类进行高效的查询.如果用户只是输入了商品名称,系统从所有商品中查找该商品,如果用户只是选择了商品分类,系统就查询该分类的所有商品,如果什么也不输入就表示查找全部.最后一种情况的查询效率要低一些。这里的查询是模糊查询。商品查询界面如下图9 商品查询窗口根据用户输入的商品名称和商品分类,把查询的结果按分页显示的方式显示出来,用户可以在文本框中直接输入页码来定位。每一条记录对应一个超级链接,点击它就会链接到显示该商品详细信息的页面detail.jsp。查询结果界面如下:图10 查询结果显示result.jsp文件的部分代码如下:<%page contentType="text/html; charset=gb2312"language="java" import="java.sql.*,java.util.Date,java.text.SimpleDateFormat" errorPage="" %><!DOCTYPE HTML PUBLIC "-/W3C/DTD HTML 4.01 Transitional/EN" " :/ w3.org/TR/html4/loose.dtd"><%page import="mypage.MyPage"%><%page import="java.util.*"%><jsp:useBean id="mdb" scope="page" class="myconn.MyConn"/><script language="javascript">function isInt(iCheck) return ('0'<=iCheck)&&(iCheck<='9');function checkForm(frm) var s=frm.pageId.value; flag=true; for(i=0;i<s.length;i+) iCheck=s.charAt(i);if(!isInt(iCheck) alert("非法的字符!"); frm.pageId.focus(); return false; if(s="") alert("不能为空"); frm.pageId.focus(); return false; if(!flag) return true; function tetail(i)?Pro_id="+i,"ok","width=850 height=600,left=150,top=20,toolbar=no,systemMenu=no,menubar=no"); </script><%String getPage=request.getParameter("pageId");if(getPage.equals("-1")/保存分页显示String pro_name=request.getParameter("pro_name");String sor_id=request.getParameter("sor_id");if(pro_name=null|pro_name.equals("")else pro_name=new String(pro_name.getBytes("ISO8859_1");if(pro_name=null|pro_name.equals("") pro_name=""else pro_name=" where Pro_name like '%"+pro_name+"%'"if(sor_id=null|sor_id.equals("")|sor_id.equals("0") sor_id="" else if(pro_name=null|pro_name.equals("") sor_id=" where Sor_id="+Integer.parseInt(sor_id)+"" else sor_id=" and Sor_id="+Integer.parseInt(sor_id)+""String sql="select * from Produces" +pro_name+sor_id+" order by Pro_id desc"ResultSet rs=mdb.executeQuery(sql);MyPage mypage=new MyPage();mypage.recordCount=0;mypage.pageSize=2;mypage.pageCount=0;mypage.pageId=1;Vector idList=new Vector();getPage="1"while(rs.next() mypage.recordCount+; if(mypage.recordCount=mypage.pageSize) mypage.pageCount+; idList.addElement(rs.getString("Pro_id"); mypage.recordCount=0; if(mypage.recordCount!=0) mypage.pageCount+;if(mypage.recordCount=0) mypage.recordCount+=mypage.pageCount*mypage.pageSize; else mypage.recordCount+=(mypage.pageCount-1)*mypage.pageSize; if(mypage.recordCount<0) mypage.recordCount=0;rs.close();session.putValue("idList",idList);session.putValue("mypage",mypage);session.putValue("pro_name",pro_name);session.putValue("sor_id",sor_id);%><html><head><meta -equiv="Content-Type" content="text/html; charset=gb2312"><title>查询分页显示结果</title><jsp:include page="head.jsp" flush="true" /><%MyPage mypage=(MyPage)session.getValue("mypage");if(mypage.recordCount=0) out.println("<center>对不起,没有你找的物品!</center>");else out.println("<br><center>当前页面商品如下</center><br>");int pageId=mypage.pageId;Vector idList=(Vector)session.getValue("idList");String pro_name=(String)session.getValue("pro_name");String sor_id=(String)session.getValue("sor_id");String getList=""if(getPage!=null|pro_name!="") pageId=Integer.parseInt(getPage.trim();if(pageId<1|pageId>mypage.pageCount) pageId=mypage.pageId; mypage.pageId=pageId;session.putValue("pageId",Integer.toString(mypage.pageId);if(pageId>1) getList=(String)idList.elementAt(pageId-2); if(pro_name.equals("")&&sor_id.equals("") getList=" where Pro_id<"+Integer.parseInt(getList)+"" else getList=" and Pro_id<"+Integer.parseInt(getList)+""Stringsql="selecttop"+mypage.pageSize+"*fromProduces "+pro_name+sor_id+getList+" order by pro_id desc"ResultSet rs=mdb.executeQuery(sql); while(rs.next()%><center><a href="javascript:tetail(<%=rs.getString("Pro_id")%>)"><%=rs.getString("Pro_name")%></a></center><br> <%> <center><% if(pageId!=1)%> <a href="result.jsp?pageId=1">第一页</a>|<a href="result.jsp?pageId=<%=pageId-1%>">上一页</a><% else out.println("第一页|上一页"); %> <% if(pageId!=mypage.pageCount) %> <a href="result.jsp?pageId=<%=pageId+1%>">下一页</a>|<a href="result.jsp?pageId=<%=mypage.pageCount%>">最后一页</a> <% else out.println("下一页|最后一页"); %> <%=mypage.pageId%>/<%=mypage.pageCount%> <form name="form1" action="result.jsp" method="post" onSubmit="return checkForm(this)"> <input type="text" name=pageId width=100> <input type="submit" name="submit" width=100 value="确定"> <input type="reset" width=100 value="取消"> </form> </center><%> </html>detail.jsp,显示对应商品的详细信息,包括商品单价、生产商等信息,同时有一个购物超级链接。 图11 添加商品到购物车 商品购买用户点击商品详细信息页面中购物链接.就可以把商品添加到购物车.然后页面自动跳转到viewcar.jsp,把购物的结果快速的返回给用户浏览.如果用户没有登录,他只可以查看商品,但是不能购物,页面自动跳转到登录页面以便让用户登录.显示了购物车购物情况.包括商品的名称,商品单价,数量.用户可以修改购物的数量.只要在文本框中输入数字,点刷新按钮就可以了,当商品数目输入为零的时候,就表示不购买这这个商品了,更新的时候要进行表单的验证,必须是合法的数据,否则不能更新.页面也提供了清空购物车的功能。浏览购物车界面如下: 图12 浏览购物车用户结帐的时候,系统根据购物车的购物情况来结帐.并在后台生成定单和定单明细.同时显示用户以前的注册信息,用户在这里可以修改信息,如电子邮箱、 ,地址等,以确保双方通信的畅通,确保交易的成功。结帐界面如下:图13 结帐显示结帐的结果,包括定单号,用户的ID,预付金额,同时也要注销用户的登录信息、防止别人用这些信息进行非法的操作,清空购物车,释放系统的资源。4. 商品分类管理.smanage.jsp 显示了所有商品分类.每一个商品分类后有删除,修改链接.还有一个增加商品分类按扭。smanagers.jsp 这是商品分类的具体处理过程.包括删除,修改,增加.删除商品分类的时候要注意数据的完整性,当这个商品分类下有商品的时候,就不可以删除该商品分类.5. 商品管理.pmanage.jsp 显示了所有的商品.每一个商品后有删除,