基于JAVA的购物网站(毕业论文).doc_第1页
基于JAVA的购物网站(毕业论文).doc_第2页
基于JAVA的购物网站(毕业论文).doc_第3页
基于JAVA的购物网站(毕业论文).doc_第4页
基于JAVA的购物网站(毕业论文).doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

南南昌航空大学科技学院2016届学士学位论文1引言 自从B2C购物出现在人们的视野中,电子商务就在全世界范围内受到了格外的关注,并且得到了快速的发展。从现实角度来看,目前购物网站的普遍用户是购买者难以自己想要购买的商品甚至用户在耗费很大的精力和时间后即使找到了自己想要的产品,最后却由于其他原因而放弃购买。很多报道指出,推销商们普遍对目前的网络行销感到失望,尽管如此,电子商务无疑是目前最好的在线商品展示的媒体和工具。然而,网上产品展示的目的不仅仅是展示产品,而更重要的是通过让客户更多地了解产品而提高产品的购买率。因此,购物网站目前所面临的最大挑战之一就是网站的设计,如何使得网页能够有效地展示自己的产品,同时方便用户的使用,使用户以愉悦的心情选购称心如意的商品。本系统的目的和意义就是应上述挑战而尝试为用户提供一个操作简单方便的网上交易系统。利用本系统,用户可以自由地浏览商品,注册成为网站会员,选择商品加入自己的购物车,而后生成订单,实现网上购物。2系统应用的关键技术2.1EXTJS MVC的介绍ExtJs 前台我分为了 model,store,view,controller层4层架构,对于model层 ,用于接收后台传入的Pojo封装成前台数据Model中,创建一个model需要define的一个继承于Ext.data.Model的一个类,其中关键不可少的配置项是fields,例如 fields: name:id,type:int,srotable:true, name:text,type:string,srotable:true其中name代表字段名称,type为字段类型,类型只有string、float、int、boolean、date、 auto(默认值, 意味着无convert方法)6种对应后台pojo,形成一条数据,而stroe层则是数据集合,也就是model的集合。开发时我们经常是用代理的方式从后台获取一条json数据,形成stroe,如proxy:type:ajax,url:./category/combo_category.do,reader:type:json,root:rows,writer:type:json是用ajax的代理方式从后台获取一个数据集,stroe还得指定你使用的model是那个,model配置项就可以指定你要指定的Model类,用字符串的形式写上类名即可配置好stroe.这时候搭建主面板视图,主面板是一个border布局,上方是login信息以及系统名称,左边属性图,中部是数据表格以及一些表单。完成的mvc架构还需要controller层,这时候我们要先建立一个app.js,内容如下:Ext.onReady(function()Ext.QuickTips.init();/开启提示功能Ext.Loader.setConfig(/动态加载js文件enabled : true);Ext.application(name : core,/名称appFolder : ./core,/所在的目录launch:function()Ext.create(Ext.container.Viewport,layout : fit,border : 0,items : xtype : mainviewlayout);,controllers : core.app.controller.MainController););我们用一个Viewport搭建系统主界面,其中items中放入的mainviewlayout就是系统主视图的别名,通过这种方式可以直接加载mianviewlayout类到页面,Cotrollers配置的则是我们的控制器层,控制器层的声明也相当的简单,创建一个继承与Ext.app.controller的类,写一个初始化方法中的this.controller方法中则是我们控制界面按钮效果的主要地方。我在搭建这套界面是写了一个公用的加载其他控制器和页面视图的方法:this.addFunItem=function(funInfo)if(funInfo)var mainView=funInfo.mainView;var funPanel=mainView.down(funInfo.funViewXtype);if(!funPanel)self.application.getController(funInfo.funController).init();funPanel=Ext.create(funInfo.funViewName);mainView.add(funPanel);mainView.setActiveTab(funPanel);elsemainView.setActiveTab(funPanel);,传入funInfo是一个js对象,用来加载不同views,models,stores,实现点击左侧树形图,加载不同的数据表格表单树形等不同的数据展示效果.2.2 数据表格的形成 ExtJS中的数据表格中的每一条数据对应的都是Model,所有记录则是一个数据集合,所以数据表格中我们肯定要配置的有stroe对象,为了形成数据表格中可以形成复选框多选的效果我们需要加入的配置项有selModel:selType:checkboxmodel,multiSelect:true,使用的是复选形式的选择模式,数据表格必不可少有colums,也就是列模式,规范我们接收store数据形成表格的展现形式如:columns:text:商品名称,dataIndex:name,width:100,text表示的每列展示的名字,dataIndex则是需要展示的字段,一般我们在生成一个数据表格的时候我们都会在表格头上加几个按钮,用来管理数据表格的增删改,这个功能实现只要用tbr里面放几个按钮,分别给上他们响应的rel属性,方便我们在控制器中查找,实现控制功能,常见的数据表格还会有分页展示,以及搜索框,bbar:xtype:pagingtoolbar,store:duct.store.ProductStore,dock:bottom,displayInfo:truebbar中放入的就是一个分页的组件,他也需要一个数据集合stroe,dock表示地定位的位置,而搜索框我们一般用一个触发器组件来形成,做一个前台的过滤效果即可。如-,按名称查询:,xtype: triggerfield, triggerCls: Ext.baseCSSPrefix + form-search-trigger,listeners: change:function(_this,_new,_old,_opt) var _store = _this.ownerCt.ownerCt.getStore(); _store.clearFilter(false); _store.filter(name,_new); , onTriggerClick: function() var _store = this.ownerCt.ownerCt.getStore(); _store.clearFilter(false); _store.filter(name,this.getValue(); ,这样简单的搜索功能我们就可以实现了。2.3 树的形成 定义一个类继承于Ext.tree.Panel.本系统的主界面的树形使用的是本地树,不同过后台生成,直接前台固定数据,生成的固定的树结构,树同样需要数据就有store的配置以及树的items配置主要配置的就是树的各个节点,本系统每一个小菜单就是一颗树,通过前面定义的加入新的视图和控制器的方法来加载不同的页面都需要传入树的节点信息。2.4 数据库的连接本系统数据库的连接使用的MyBatis框架的数据连接,用配置文件配置数据库连接属性,本次我没有使用外部属性文件,而是直接使用配置的固定参数,先配置一个数据源dataSource,让他直接指向类org.springframework.jdbc.datasource.DriverManagerDataSource,配置参数driverClassName的value为com.mysql.jdbc.Driver,url为jdbc:mysqlL.localhost:3306/lzl?characterEcoding=utf-8&useUnicode=true在配置数据库访问账号密码,这样我们就和数据库连接上了。2.5 系统的运行环境 本系统前端使用mvc模式的ExtJS4.1后台使用springmvc,spring,mybatis整合,使用的服务器是tomcat7.0,在eclipse编译器下运行即可,操做系统Windows7,在火狐浏览器下进行测试.2.6 springmvc工作流程 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获; 2.DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回; 3.DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(.)方法) 4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作: HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中 5. Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象; 6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet; 7.ViewResolver 结合Model和View,来渲染视图 8. 将渲染结果返回给客户端。 2.7 spring依赖注入,控制反转IoC,即控制反转。他使程序组件或类之间尽量形成一种松耦合结构,开发者在使用类的实例之前,需要先创建对象的实例。但是IoC将创建实例的任务交给IoC容器,这样开发应用代码时只需要直接使用类的实例,这就是IoC。通常用一个好莱坞原则(请不要打电话给我,我会打电话给你。)来比喻这种控制反转的关系。依赖注入有3种类型注入,spring支持2种,setter注入和构造器注入,在项目中我使用的是注解方式的注入,在配置文件中配置了com.lzl包下的类自动注入到容器中,在我们需要用到这些类的时候,我们只需声明该类,然后使用一个autowired注入想要使用的类,其中控制器我们使用的Controller注解标识为控制器,业务逻辑层我们使用的service注解。这样spring容器就能管理好我们的类。2.8 spring AOP 3 系统需求分析和总体设计3.1系统功能需求在本系统中用户管理、购物车管理、订单管理、产品展示,商品管理,广告管理六个模块。分为前台展示项目和后台管理项目。(1)购物车管理:实现添加商品、取消一个商品、数量修改、清空购物车功能。(2)订单管理:实现提交订单、删除订单、查询订单、订单审核功能。(3)前台展示:实现产品列表、产品明细功能。(4)用户管理:实现用户注册、用户信息修改、用户删除、用户查询功能。(5)商品管理: 实现对商品的添加,对商品信息的修改,对商品的删除。以及按类别查询商品,按名称查询商品功能。(6) 广告管理: 对主页面广告部分的管理,实现广告的动态化,页面广告信息的更新。3.2系统角色及其功能分析3.2.1系统中有3个角色:(1)注册用户(2)管理员 (3)游客3.2.2系统角色的功能(1)普通用户网站的普通浏览者(即游客),可以浏览商品和添加本地购物车。(2)注册用户普通浏览者只要注册为网站用户后,登录成功后有以下功能:登录,登出,向购物车中添加商品,查看个人信息,生成并提交订单。添加或修改个人明细资料。(3)管理员 登录成功后,进入后台项目,对前台展示的动态管理,以及用户商品等管理,对订单的审核。3.3总体设计思想概述本系统是基于B/S架构下的多层结构应用系统。B/S(Browser/Server)结构即浏览器和服务器结构。它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,形成所谓三层3-tier结构。这样就大大简化了客户端电脑载荷,减轻了系统维护与升级的成本和工作量,降低了用户的总体成本(TCO)。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。推荐的分层式结构一般分为三层,从下至上分别为:数据访问(dao)层、业务逻辑层、表示层总的来说,采用分层结构的设计思想,可以让每个层由一组相关的类或组件构成,共同完成特定的功能。层与层之间存在自上而下的依赖关系,上层组件会依赖下层组件的API,而下层组件则不依赖于上层组件。例如:表述层依赖于业务逻辑层,而业务逻辑层依赖于数据库层。并且每个层对对上层公开API,但具体的实现细节对外透明。当某一层发生变化,只要API不变,不会影响其他层的实现。在本系统中,使用开源的mysql数据库,持久层用到spring所集成的mybatis技术,业务逻辑层用普通javabean实现,表述层运用基于springmvc的MVC设计模式(springmvc用来做C层,spring实现V层与C层的解耦以及C层与M层的解耦)。3.4数据库设计 图3-1 数据库E-R3.4.2数据库表设计下面列出了设计过程中所用到的数据库表及其结构: 表3-1 lzl_quser 前台用户表 列名类型长度允许空值描述idint11不允许主键usernamevarchar255不允许用户名passwordvarchar255不允许密码emailvarchar255允许邮箱地址qqvarchar255允许qq号码phonevarchar255允许电话号码sexvarchar255允许性别xlvarchar255允许学历ahvarchar255允许 爱好jjvarchar255允许简介表3-2 lzl_user 管理用户表列名类型 长度允许空值描述id varchar11不允许主键usernamevarchar255不允许用户名passwordvarchar255不允许密码sexint 11允许性别phonevarchar155允许电话号码qqvarchar255允许qqaddrvarchar255允许地址emailvarchar255允许邮箱地址 表3-3 lzl_product 商品表列名类型长度允许空值描述idint11不允许主键namevarchar255允许商品名descvarchar255允许描述norma_Pricedouble11允许社会价格member_Pricedouble11允许本店价格pdatetimestamp0允许上货日期category_idint11允许所属类型photovarchar255不允许图片地址 表3-4 lzl_cartItem购物车表列名类型长度允许空值描述idint11不允许主键product_idint11不允许商品idproduct_namevarchar255允许商品名称countint11允许商品数量pricedouble11允许商品单价quser_idint11不允许用户idstateint11允许当前状态imagepathvarchar255允许商品图片3.5系统的类设计3.5.1DAO类设计通过这个mybatis获取对应的DAO,然后使用DAO进行数据库操作,每个dao对应一个Mapper配置文件,进行Sql的配置,在本系统中,dao的一般使用都使用了BaseProvice类,根据约定实体用param(“entity”)标识,分页参数用param(“pageNum”)和param(“pageSize”)标识,这样就能友好的被读取,按照约定还有实体中的其他对象属性要用ObjectAlt注解标志,集合用ArrayAlt标志,这样的标识都可以方便我们更好的识别其属性到底是个什么类型,其次做条件查询时,是用entity标识的实体中有不为空的属性且不为空字符串时就会被and连接,保存也是实体中不为空的属性都会进行保存,主键必须为空,数据库进行主键的自动增长3.5.2JacksonUtil类设计 本类中实现了一个mapToJson方法,参数为一个Object的对象。返回值为一个String类型的json对象,本类可以将对象或者集合传化为JSON格式的字符串,用的是JackSon Jar包。3.5.3 ObjectAlt注解类设计 用Target(ElementType.FIELD)标识表示可以使用在属性上,在使用Retention(RetentionPolicy.RUNTIME) 在运行时检测,最后方法中声明一个String value(),本类用来标识实体类中的对象属性。3.6系统的用例图Customerer浏览商品注册登录购物车管理订单操作修改信息添加修改删除 图3-2 总体用例分析1 Admin商品管理广告管理角色管理用户管理图3-3总体用例分析2如图3-3,用户管理、购物车管理、订单管理、产品展示,广告管理,商品管理6个模块构成了本b2c购物网站系统。User是指系统用户,包括注册用户和匿名用户两种,匿名用户只可以浏览商品,匿名用户通过用户管理模块注册后就可以使用购物车和下订单。展示用户Admin用户登录录信息修改添加新用户图3-4用户管理用例如图3-4,用户管理模块主要包括:用户登陆、用户注册、用户信息修改、用户删除、用户信息查询五个功能组成。取消一个商品购物车管理用户商品数量修改清空购物车图3-5购物车管理用例如图3-5,购物车管理模块主要包括:添加商品、取消一个商品、数量修改、清空购物车四个功能组成。订单查询订单审核订单管理管理员修改订单图3-6订单管理用例如图3-6,订单管理模块主要包括:订单提交、删除订单、订单明细三个功能组成。4.系统结构设计 图4-1 系统前台功能设计 图4-2 系统后台功能设计图4-3 系统总体功能设计 图4-4 个别功能设计5 系统的详细设计5.1 BaseProvice类 这个类重要是复用型的后台动态SQL语句的生成,在dao层使用selectkey注解指定type为BaseProvice.class,method为指定的方法,5.1.1 isString 方法 该方法返回值为一个String ,参数为Field field,Map map,String sql三个,通过field.getType().toString().contains(String),判断出这个属性为string属性,然后在判断这个属性不为空的字符,这时候我就进行了模糊查询and连接方式的拼接,用传入的sql参数的concat方法拼接“and”+StringUtil.StringtoCoulm(field.getName(),在拼接like Concat (%,#entity,加上field的getName方法拼接属性名称上去,StringUtil.StringtoCoulm方法是将属性格式化为字段的方法,如mebmerPrice就会格式化成mebmer_price,最后返回sql即可。5.1.2 isObject 方法 该方法返回值为一个String ,参数为Field field,Map map,String sql三个,通过field的getAnnotation(ObjectAlt.class)方法不为空的话我们就通过 field.get(map.get(entity),得到一个Object的对象,通过Object对象的getClss().getDeclaredFields(),得到属性的数组,循环遍历属性数组,循环中先设置私有属性可访问,然后通过fields1j.get(obj),得到这个属性,判断这个属性如果是id的话在进行拼接sql=sql.concat( AND+StringUtil.StringtoCoulm(fields1j.getName()+ = # entity.+field.getName()+.+fields1j.getName()+);就可以将外键属性的id进行拼接进入,最后返回sql即可。 5.1.3查找单个对象首先我们在BaseProvice类下建立一个名为findOne返回值为String值参数为一个map的方法,其次通过 map.get(entity).getClass()得到一个map中param(“entity”)注解标识为实体的Class对象,然后我们声明一个String类型的字符串,初始化为”select * from ”,通过concat方法用刚刚得到的Class对象的getSimpleName()方法得到类名,约定好lzl_+类名就为数据库表名,这时候就得到了Select * from 表名 ,最后我们在通过concat方法拼接where id=#entity.id,返回字符串sql。5.1.4 通过条件查找对象集合先声明一个名为findList返回值为String参数为Mapmap的方法,通过map.get(“entity”)得到param(“entity”)注解标识为实体的Class对象,声明一个String类型的字符串,初始化为select * from,通过concat方法拼接lzl_+clazz.getSimpleName()+ WHERE 1=1,得到的sql为 select * from表名where 1=1,这时候我们调用Class对象的getDeclaredFields()方法得到属性的数组fields,对属性数组进行遍历,在循环开头我们需要设置可以访问私有属性,这句代码就是设置访问私有属性,fieldsi.setAccessinble(true),然后进行判断这个属性在实体中是否为空fieldsi.get(map.get(entity)!=null,不为空的时候我们对属性的类型进行判断,这时候我们就要用得isString,isInteger ,isObject方法,最后返回sql。5.1.5通过条件查找对象集合带分页 这个方法中我们只需要调用上放的findList方法,最后我们将sqlConcat方法拼接 limit #pageNum,#pageSize,最后返回sql。5.1.6 带条件的查询数据总数 这个方法我们也是先调用findList方法得到所有的记录,然后通过sql的replace方法将*替换为count(*),返回sql即可。5.1.7 增加一条记录的方法 声明一个名为save返回值为String参数为map的方法,首先我们通过map.get(entity).getClass()得到对象的Class对象,声明二个String字符串,一个为sql初始化为insert into,sql1初始化为 values (;给sql字符串拼接上表名,通过sql.concat(lzl_+clazz.getSimpleName()+ ( ),用class对象的getDeclaredFields()得到所有的属性,遍历属性数组,设置可以访问私有属性,通过fieldsi.getAnnotation(ObjectAlt.class)!=null时,对sql进行sql=sql.concat(StringUtil.StringtoCoulm(fieldsi.getName()+_id ,);对sql1进行sql1=sql1.concat( #entity.+fieldsi.getName()+.id,);然后continue出去,在判断if(fieldsi.getAnnotation(ArrayAlt.class)!=null),在continue出去,在判断该属性是否是id属性,是的话sql=sql.concat(StringUtil.StringtoCoulm(fieldsi.getName()+,); sql1=sql1.concat( # entity.+fieldsi.getName()+,);最后将sql的最后一个,替换为 )sql.substring(0, sql.lastIndexOf(,).concat() );sql1的最后一个,替换为 )sql1=sql1.substring(0, sql1.lastIndexOf(,).concat();最后返回 sql.concat(sql1)就得到了增加语句5.1.8 根据id修改的方法5.1.9 根据对象修改的方法 声明一个名为update返回值为String参数为map的方法,声明2个字符串分别为sql和where 初始化为 “update” 和“where id=#entity.id”,通过map.get(entity).getClass()得到class对象声明为clazz,给sql拼接表名并加上set字符串,通过clazz.getDeclareFields()得到所有的属性,设置可以访问私有属性,判断是否为id属性是的话不拼接,在判断是否是对象,通过fieldsi.getAnnotation(ObjectAlt.class)!=null判断是对象,是对象的话 给sql拼接sql=sql.concat(StringUtil.StringtoCoulm(fieldsi.getName()+_id = #entity.+fieldsi.getName()+.id);在continue出去,在通过fieldsi.get( map.get(entity)!=null判断当前属性值不为空,在拼接以下语句sql=sql.concat(StringUtil.StringtoCoulm(fieldsi.getName()+= # entity.+fieldsi.getName()+,);最后去除掉字符串的最后一个字符sql=sql.substring(0,sql.length()-1);返回sql.concat(where)即可5.1.9 根据id删除的方法 声明一个名为remove 返回值为String参数为map ,先声明一个sql的字符串,初始化为delete from,通过map.get(entity).getClass()得到Class对象,然后拼接lzl_+clazz.getSimpleName() where id=#id,最后返回sql即可5.2主要模块的设计说明与界面5.2.1用户管理模块用户管理模块主要包括用户注册,登录,退出、删除、修改 图5-1 未记住密码以及未自动登录状态 图5-2 记住密码状态图5-3自动登录的状态图5-4用户管理页面图5-5 用户增加1图5-6 用户增加2图5-7用户增加3 图5-8用户信息修改 图5-9 搜索过滤5.2.2 前台系统展示模块图5-10 游客用户展示页面图5-11 登录页面图5-12 登录成功后 图5-13购物车5.3系统的测试测试是软件开发的重要组成部分,每一个开发人员都应该养成良好的生活习惯的测试,通过不断地测试和维护,完成提高系统它是。显着性检验如下:(1)测试并不仅仅是为了找到错误,通过分析发生的错误发生的原因和趋,可以帮助项目经理找到当前软件开发过程中的缺陷,以便及时改进;(2)分析可以帮助测试人员提高效率和测试的有效针对性;(3)错误被发现,也是有价值的,完整的测试是评估软件质量的方法。(4)测试可以使系统更加完善,减少不必要的时间来再看一遍同一个地方.测试一般有两种方法:如果你已经知道产品应该具有的功能,可以通过测试来验证每一个功能都可以正常使用;如果知道在工作过程内的产品,可以进行测试

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论