版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1绪论1.1系统目的近几年人们的消费观念在逐渐的发生改变,越来越多的人选择在网路上购买自己所需要的产品,网购就需要快递这个行业支撑。不知不觉中快递已经成为大多数人生活中一个必不可少的东西。为了能更好的服务大家,就需要一个良好的物流系统来实现。1.2需求描述在开始实现系统之前,首先得先做需求分析,有了良好的需求分析才能使得系统更好的进行下去。该系统分为了两大功能模块:用户模块,管理员模块。1.2.1用户模块a.注册,将用户的姓名,密码,手机号等信息记录起来。b.登录,用户通过输入用户名和密码登录自己的账号,从而进行更多的操作,不仅保护了用户自己的个人数据不被他人操作,也告诉了系统是哪个用户在进行操作。c.修改密码,提高用户体验d.评论,记录用户的评论能更好的了解用户的需求,这样有利于后期对系统的完善。e.下单,新增订单,记录用户的快递信息。f.订单查询,将订单的详细信息展示给用户,提高用户体验。1.2.2管理员模块a.用户的增删改查,作为该系统的操作与维护者,需要有更多的权限。不仅可以新增普通用户,而且也能新增配送员,还能增加管理员。b.订单进行增删改查,能更好的展示数据的时效性。c.对用户评论进行回复。1.3系统的可行性分析技术可行性是决定整个物流管理系统成效的最直接的因素,没有坚实可靠的技术作为支持,物流管理系统就无法正常稳定的运行。研究人员首先需要分析物流管理系统的技术特点,然后结合系统的应用特点进行全面分析这样才能够搭建一个良好的系统。因为java是一门强大的而且简单易用的面向对象语言编程语言,Java具有简单性、面向对象、分布式、健壮性、安全性等特点,能更好的满足需求。Mysql也是一非常强大的数据库,而且还是开源(免费)的。1.4开发环境该系统是一个基于jsp+Mysql实现的web系统。采用的是前后端分离技术,前台主要是html,css,js,jQuery,jsp,Ajax来实现的,后端采用的编程预言是java,java代码来处理操作数据的逻辑,持久层是利用Mysql数据库来记录数据。前端主要用的是WebStorm这款软件编写的,java代码是用eclipse编写的,持久层使用Navicat来编写sql语句。虽然eclipse这一个应用软件能满足以上代码的编写,但其对于前端的编程和sql的编写太过于繁琐,所以为了提高代码的质量,采用了三款软件对代码进行编写。该系统是在Windows操作系统,jdk1,8,Tomcat下设计实现的。2系统相关技术2.1JspServlet是sun公司制定的一种扩展web服务器功能的组件规范。web服务器只能够处理静态资源的请求(即需要事先将静态页面写好),不能够处理动态资源的请求(即需要进行计算,生成动态页面),所以,需要扩展其功能。可以使用Servlet来扩展web服务器功能,web服务器收到请求之后,如果需要计算,则调用Servlet来处理。图2-1Servlet工作原理图Servlet的工作主要分成6步:a.浏览器依据ip和port建立连接。b.浏览器将相关数据放到请求数据包,然后将请求数据包发送给服务器。c.服务器解析请求数据包,将解析到的结果放到请求对象里面,同时,创建一个响应对象。d.服务器依据请求路径,创建Servlet对象,然后调用该对象的service方法。e.容器从响应对象中取出处理结果,然后创建响应数据包并发送给浏览器。f.浏览器解析响应数据包,生成结果页面。jsp是sun公司制订的一种服务器端动态页面技术规范。其本质就是一个Servlet。虽然可以使用Servlet来实现动态页面效果,但是过于繁琐,并且不利于页面的维护(比如,要修改页面就必须修改java代码),所以,sun制订了一个全新的技术规范,即jsp规范。jsp文件中主要包含了html和少量的java代码,容器在启动的时候会将jsp文件自动编译成一个对应的Servlet然后执行。2.2Ajax在传统开发模式中,浏览器向服务器提交请求的方式有:改变浏览器地址栏中的URL、FORM表单,这2种方式发出请求后,由浏览器直接处理服务器的响应,而浏览器的响应方式就是直接把响应正文显示在浏览器中!为了使得客户端可以自行发出请求,并自行处理结果,而不是由浏览器把响应的结果直接显示出来,则需要使用到异步请求!AJAX是在网页客户端通过Javascript发出异步请求的做法,传统的AJAX开发比较麻烦,通常,会结合jQuery框架来使用。其发送的是json类型的数据。其语法特征是:整个数据是使用大括号框住的;各组属性之间使用逗号分隔;使用冒号分隔属性名称与属性值;属性名称使用双引号框住;如果属性值是字符串,也需要使用双引号框住;属性值可以是基本型数据(数值型、字符串、布尔值),也可以是另一个对象(使用`{}`),或数组(使用`[]`)。2.3MysqlMysql是一个非常流行的关系型数据库,由于该系统是一个WEB应用,而Mysql在WEB应用方面是最好关系数据库管理系统应用软件,所以该系统采用的是Mysql数据库。2.4SSM框架SSM框架,即Spring、SpringMVC、MyBatis三个框架,SSM框架也是非常流行的2.4.1SpringSpring是一个轻量级的、用来简化企业级应用开发的开发框架。Spring的一个核心模块是Spring容器,用于管理对象(包括对象的创建及对象之间的依赖关系)。Spring的核心技术为IOC和AOP。IOC(InversionOfControll控制反转)对象之间的依赖关系应该由容器来建立,,对象之间的耦合度会大大降低,提供高了系统的维护性。AOP即面向切面编程,是面向对象编程的延续,AOP使得业务逻辑变得更加清晰,可以让业务逻辑只关注业务本身。2.4.2SpringMVCSpringMVC框架解决了V-C的交互问题,即视图与控制器的交互问题。SpringMVC组件:DispatcherServlet:前端控制器,主要职责是接收所有请求(根据配置文件来决定),并将请求转发给对应的控制器,接收控制器的处理结果,确定最终由哪个视图完成响应!HandlerMapping:处理请求路径与控制器的映射关系。Controller:实际处理请求的组件,例如接收请求参数,决定最终是转发或重定向的方式来响应。ModelAndView:控制器的处理结果,其中的Model表示转发的数据(如果是重定向,则Model没有意义),而View表示最终负责响应的视图组件的名称。ViewResolver:根据视图组件的名称,确定具体使用的是哪个视图组件。图2-2SpringMVC的原理图2.4.3MyBatisMyBatis是优秀的、简化持久层开发的框架,MyBatis简单易用,使用时只要定义数据操作接口的抽象方法,然后在编写与之关联的sql语句。MyBatis是一个独立的框架,能单独使用,但是比较麻烦,结合Spring框架和SpringMVC来使用会使得操作变得相对简单。3系统数据库的设计3.1用户信息表(user)用户信息表记录的是用户的详细信息。其结构如下:表3-1用户信息表字段名称类型含义idint主键,表示数据的唯一性usernamevarchar(15)用户姓名user_telvarchar(15)用户手机号码passwordchar(32)密码customer_idint用户类型(包含普通用户,管理员,配送员)saltchar(32)盐值is_deleteint是否删除,用来判断数据是否被删除created_timedatetime创建时间created_uservarchar(20)创建人modified_uservarchar(20)最后一次修改人modified_timedatetime最后一次修改时间其中varchar表示为可变长度的字符串,括号后面的数字表示字符串的最大长度;char表示固定长度的字符串,括号里面的数字表示的是字符串的长度;datetime是用来保存时间的类型,保存年月日时分秒,默认值为null,最大值9999-12-31。表中后四个字段是用来记日志的,方便追踪数据。3.2评论信息表(comment)评论信息表记录的是用户的评论信息和管理员回复信息,其结构如下:字段名称类型含义idint主键,表示数据的唯一性customer_idint客户id,用来记录评论的用户REMAKEvarchar(100)用户评论内容REPLYvarchar(100)管理员回复内容REPLY_idint管理员id,用来记录回复管理员信息is_deleteint是否删除,用来判断数据是否被删除created_timedatetime创建时间created_uservarchar(20)创建人modified_timevarchar(20)最后一次修改人modified_userdatetime最后一次修改时间表3-2评论信息表(comment)3.3地址管理表(t_area)物流是离不开地址管理的,所以应当创建一个地址管理表来将全国的地址信息记录下来,由于全国的省市县数据量较大,所以不可能去一条条的新增,而且关于地址的管理网上有很多现成的sql,可拿过来直接使用,其表结构如下:表3-3地址管理表(t_area)字段名称类型含义areaIdint地区IdareaCodevarchar(50)地区编码areaNamevarchar(20)地区名levelint地区级别(1:省份,2:市3:区县cityCodevarchar(50)城市编码centervarchar(50)城市中心点(即:经纬度坐标)parentIdint地区父节点地址表里面的数据是固定的,所以没有添加日志四项和is_delete字段。3.4枚举值表(fix_code)枚举值表用来记录不同的枚举值,比如用户的类型,订单的状态等,相较于直接使用值类型去做判断,枚举类型更易读,能够提升代码的可读性和易维护性。该表结构如下:表3-4枚举值表(fix_code)字段名称类型含义CODE_TYPEvarchar(20)枚举值类型CODEint枚举值CODE_NAMEvarchar(20)枚举名称TYPE_NAMEvarchar(20)枚举类型名称created_timedatetime创建时间created_uservarchar(20)创建人modified_timedatetime最后一次修改时间modified_uservarchar(20)最后一次修改人3.5订单信息表(t_order)订单信息表记录的是订单的详细信息。其结构如下:表3-5订单信息表(t_order)字段名称类型含义idint主键,表示数据的唯一性mail_namevarchar(20)寄件人姓名mail_telint寄件人手机号码mail_pidint寄件省idmail_cidint寄件市idmail_aidint寄件区/县idmail_addressvarchar(50)寄件详细地址receipt_namevarchar(20)收件人姓名receipt_telvarchar(20)收件人手机号码receipt_pidint收件省idreceipt_cidint收件市idreceipt_aidint收件区/县idreceipt_addressvarchar(50)收件详细地址statusint订单状态(枚举值)is_deleteint是否删除created_timedatetime创建时间created_uservarchar(20)创建人modified_timedatetime最后一次修改时间modified_uservarchar(20)最后一次修改人4系统设计4.1系统结构图4-1系统结构图系统的名称为SF-logistics,是一个Mavenwar系统。在src/main/java目录下创建包com.cbb.logistics来存放java代码,其内部结构如下:图4-2java代码结构图其中controller包存放的都是控制器类;entity包下存放的都是实体类,filter下存放的是过滤器;interceptor目录下存放的是拦截器;mapper类下面存放的是持久层接口;service包下存放的是业务层接口,其子包ex下存放的是异常类,子包impl下存放的是业务层实现类。util包下存放的是帮助类;VO类存放的是多表查询的实体类。每个包下存放的类都应当属于同一类型,这样使得结构清晰,方便阅读和维护。所有的前台代码都存放在src/main/webapp目录下,其内部结构如下:图4-3前端代码结构图其中web文件夹下面存放的是.html文件;css文件夹下面存放的是.css文件,js目录下存放的是.js文件;img目录下存放的是图片;WEB-INF目录下有.jsp文件,还有配置文件web.xml,该目录下的.jsp文件是不能直接通过浏览器输入地址访问的,必须是服务器内部通过转发或重定向才能访问。持久层的代码写在src/main/resources下的mapper文件夹下面,一个xml映射文件,都会对应一个持久层接口,对应关系为xml文件的namespace值与持久层接口的全限名相同;而xml文件中的每一个Statement的id属性值与的接口的方法名相等而形成对于关系;接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为主键值,可唯一对应一个MapperStatement对象。在Mybatis中,每一个增删改查标签,都会被解析为一个MapperStatement对象。4.2用户模块4.2.1注册由于大部分的表都含有日志的四项,所以在设计实体类前,先设计实体类的基类。在entity包下面按照javaBean的设计模式创建实体类基类BaseEntity,将日志四项createdUser(创建人)、createdTime(创建时间)、moidifiedUser(修改人)、modifiedTime(修改时间)申明成私有属性,并生成对应的get、set方法和toString方法。并实现序列化接口Serializable,并生成序列化版本号。在entity中创建用户实体类User,继承BaseEntity,申明私有化属性id(用户自增长id)、username(用户姓名)、userTel(用户手机号)、password(密码)、customerId(用户类型)、salt(盐值)、isDelete(是否删除),同样生成get、set方法和toString方法。为了保护用户的信息,需要对用户的密码进行加密处理,而不是直接将用户的密码记录在数据库中。加密算法有:对称加密、非对称加密。无论是哪种,在已知加密过程的各项数据参数后,都可以根据密文运算得到原文。通常,密码的存储并不使用这些加密算法,而是使用消息摘要(MessageDigest)算法。消息摘要的特征有:使用特定的摘要算法,得到的摘要数据的长度是固定的;使用相同的原文,必然得到相同的摘要;使用不同的原文,可能得到相同的摘要,但是,机率非常非常低;消息摘要是不可被逆运算的!常见的消息摘要算法有SHA家族(SecureHashAlgorithm)算法,MD系列。在Java原生API中,有`java.security.MessageDigest`类,用于处理消息摘要运算,但是,使用相对繁琐,通常,会使用其它API来实现,例如,在Spring和Apache中都有`DigestUtils`工具类,可以用于摘要运算,前者需要添加Spring的依赖,后者需要添加`commons-codec`的依赖:<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>为进一步增加密码的安全性,采取了加盐操作和多次加密操作,其方法如下: privateStringgetEncrpytedPassword(Stringpassword,Stringsalt){ Stringpwd=password+salt;//将密码与盐值拼接 for(inti=0;i<5;i++){//循环5次加密 pwd=DigestUtils.md5Hex(pwd); } returnpwd;//返回 }首先在com.cbb.logistics.mapper包下创建接口UserMapper,创建抽象方法Integerinsert(Useruser)和UserfindByName(Stringn);在src/main/resources下创建一个mapper文件夹,该文件夹下面存放放的是持久层接口对应的xml文件。在该目录下创建UserMapper.xml文件。在该xml文件中创建两个方法的映射。业务层在com.cbb.logistics.service包下创建建IUserService接口,声明抽象方法User(Useruser),com.cbb.logistics.service.impl包下创建其实现类UserServiceImpl,并重写抽象方法如下:publicUseruserReg(Useruser){ //验证输入格式 if(!TextValidator.checkUsername(user.getUsername())){ thrownewUsernameFormatException("用户名格式不正确!"); } if(!TextValidator.checkPassword(user.getPassword())){ thrownewPasswordFormatException("密码的格式不正确!"); } if(!TextValidator.checkPhone(user.getUserTel())){ thrownewPhoneFormatException("手机号码的格式不正确!"); } Stringusername=user.getUsername(); //根据用户名查询用户信息 Userdata=findByName(username); if(data!=null){//如果用户已存在,则抛出用户冲突异常 thrownewUsernameConflictException("您尝试注册的用户名"+username+"以被占用!"); } //反之说明用户是不存在的,则执行插入数据操作 try{ Userr=insertUserInfo(user); returnr; }catch(InsertDataExceptione){ throwe; } } privateUserinsertUserInfo(Useruser){ //在参数user中封装那些不由外部提供的数据: //1.生成随机盐,并封装到user中 Stringsalt=UUID.randomUUID().toString(); user.setSalt(salt); //2.取出user中原密码执行加密,并封装回user中 Stringpassword=getEncrpytedPassword(user.getPassword(),salt); user.setPassword(password); //3.设置customerId为普通用户(10001001) user.setCustomerId(FixCode.USER_TYPE_CUSTOMER); //4.设置isDelete为0 user.setIsDelete(FixCode.IS_DELETE_NO); //5.日志的4项 user.setCreatedUser(FixCode.SYSTEM);//"System" user.setCreatedTime(newDate()); user.setModifiedUser(FixCode.SYSTEM); user.setModifiedTime(newDate()); //调用持久层对象的方法实现功能,并获取返回值 Integerrows=userMapper.insert(user); if(rows!=1){//抛出InsertDataException异常 thrownewInsertDataException("增加用户数据时发生未知错误!请联系系统的管理员进行处理!"); } returnuser; }注册前台页面如下:图4-1用户注册图首先在com.cbb.logistics.controller创建控制器层基类BaseController,可以在基类处理控制器层抛出的异常,和控制器层共有的方法。创建UserController继承BaseController,添加类注解@Controller和@RequestMapping("/user"),通过添加@RequestMapping("/user")注解表示该控制器都在/user目录下。创建注册方法,在方法上添加注解@ResponseBody和@RequestMapping(value="/handle_reg.do",method=RequestMethod.POST),@ResponseBody表示返回值为json字符串,@RequestMapping注解的value表示请求路径,method属性的值表示前端发送的请求为POST请求。用户填选数据进行注册,通过注册按钮的点击事件发送Ajax请求给后台,判断返回值,如果是200表示注册成功,则跳转到登录页面;如果不是200,根据不同的返回值判断注册失败原因,提示用户按照要求注册。4.2.2登录登录在持久层里利用注册持久层的方法findByName。业务层在IUserService创建抽象方法Userlogin(Strringusername,Stringpassword);并在UserServiceImpl实现该方法如下:publicUseruserLogin(Stringusername,Stringpassword){ //验证格式 if(!TextValidator.checkUsername(username)){//用户名格式不正确 thrownewUsernameFormatException("用户名格式不正确!"); } if(!TextValidator.checkPassword(password)){//密码格式不正确 thrownewPasswordFormatException("密码格式不正确"); } Userdata=findByName(username);//根据用户名查找用户数据 if(data==null){//用户名不存在 thrownewUserNotFoundException("用户名不存在!"); } Stringsalt=data.getSalt(); //获取盐值//将颜值和用户输入的密码进行加密 Stringpwd=getEncrpytedPassword(password,salt); if(!pwd.equals(data.getPassword())){//加密后的密码和数据库中用户密码不一致 thrownewPasswordNotMatchException("密码错误"); } data.setSalt(null);//登录成功将密码和颜值设置为null data.setPassword(null); returndata; }控制器层在UserController类中创建注册方法:@ResponseBody @RequestMapping(value="/login.do",method=RequestMethod.POST) publicResponseResult<Void>userLogin(Stringusername,Stringpassword,HttpSessionsession){ //验证格式 if(!TextValidator.checkUsername(username)){//用户名格式不正确 thrownewUsernameFormatException("用户名格式不正确!"); } if(!TextValidator.checkPassword(password)){//密码格式不正确 thrownewPasswordFormatException("密码格式不正确"); } Useruser=userService.userLogin(username,password); //登录 //将登录成功的user的id和username和customerId绑定到session中 session.setAttribute("uid",user.getId()); session.setAttribute("uname",user.getUsername()); session.setAttribute("cid",user.getCustomerId()); returnnewResponseResult<Void>(); }并返回json给前端。前台用户通过输入用户名和密码进行登录,当用户名密码全部输入正确后才能登录,并将用户的id和name和用户类型绑定在session中。否则提示用户错误信息。后期的很多功能是建立在登录上的,,而且不同的用户的操作权限也是不相同的,这些都是通过获取session中绑定的数据来进行判断的。4.2.3修改密码登录成功后,点击用户身份进入用户信息界面,将用户的用户名和手机号显示出来,而一些敏感的数据如密码就不显示。用户可以点击修改密码按钮来修改密码,只有当原密码输入正确的时候才能修改密码,一旦修改密码操作成功,用户就需要重新登录。其页面如下:图4-2修改密码4.2.4评论用户可以进行评论,该功能同样是需要用户进行登录操作。用户进入评论界面,首先展示10条最新的评论以及管理员的回复,用户可以在文本域中输入内容进行评论,系统会将用户输入的信息和用户的用户id记录下来,每当用户评论成功后会再次刷新评论区的内容。4.2.5寄件用户寄件也是需要用户登录才能进行操作的。进入寄件页面,首先向服务器发送请求,将所有的省全部查询出来,显示到下拉选中供用户选择。当用户选择对应的省份后,会向服务器发送请求获取当前省对应的市,同理当市发送改变的时候会将对应的区县查询出来。用户通过填选寄件的详细信息来下单,并会生成对应的订单号,默认提交的订单状态为已生成,当订单保存成功后,会跳转到我的订单页面。订单页面会展示当前登录人创建的所有订单详细信息。图4-3寄件人信息图4-4收件人信息4.2.6订单查询用户不仅能通过订单页面查询自己创建的订单,也可以通过输入订单号来查询对应的订单。通过输入号码
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 煤炭供需合同范例
- 民间理财合同范例
- 快闪销售合同范例
- 法院合同工合同范例
- 快递货运合同模板
- 灯光秀合同范例
- 火锅采购加盟合同范例
- 挖机台班劳务合同范例
- 猪场修建合同范例
- 物权法4454合同范例
- 呼吸消化科科室现状调研总结与三年发展规划汇报
- 与复旦大学合作协议书
- 第五单元(知识清单)【 新教材精讲精研精思 】 七年级语文上册 (部编版)
- 缓冲托辊说明书
- 煤矿机电运输安全培训课件
- 2023年人教版新目标八年级英语下册全册教案
- 安抚(氟比洛芬酯注射液)-泌尿外科术后疼痛管理的基础药物
- 学前教育职业规划书
- GB/T 42249-2022矿产资源综合利用技术指标及其计算方法
- 《意识形态工作管理制度》
- GB/T 21010-2007土地利用现状分类
评论
0/150
提交评论