企业级电商平台提供商,为企业级商家提供电商平台搭建及解决方案服务

全国热线:4008-868-127

分布式电商系统项目总结

2018-10-23 0
分类: 技术干货

城是采用分布式架构部署的一个大型网上商城系统,类似于京东商城。本系统分前台系统和后台系统。前台系统主要负责商城的页面的显示功能,这里采用的面向服务的方式,pc端手机端只负责显示页面,业务逻辑都在服务层实现,客户端调用服务端接口来实现显示功能。

商城是采用分布式架构部署的一个大型网上商城系统,类似于京东商城。本系统分前台系统和后台系统。前台系统主要负责商城的页面的显示功能,这里独立商城网站建设采用的面向服务的方式,pc端手机端只负责显示页面,业务逻辑都在服务层实现,客户端调用服务端接口来实现显示功能。

在前台网上商城系统中主要分为:客户端:系统前台页面显示系统(portal,8082)。

服务端系统:

(1)rest系统(8081):负责调用CMS系统的内容,将CMS系统的内容显示到页面,(这里的CMS内容管理系统,在后台实现)。

(2)商品的搜索系统(8083),当在页面输入商品信息时,可以搜索商品。这里用到了solr技术,利用solr索引库来实现。

(3)SSO(单点登陆系统,8084),因为商城采用分布式的系统部署,将整个系统划分为几个子系统,所以对于用户的访问权限是一个问题,如何实现一次登陆即其他系统都可以免登陆,sso可以解决。

(4)订单系统(8085):商城购物少不了订单系统,所以将此作为一个独立工程编写。

后台系统功能:商城的后台系统主要是负责商品的分类,添加、规格参数。CMS系统(这里主要是广告的分类、添加)。

本系统前台界面设计采用的easyUI的设计,后台采用springMVC、spring、mybatis框架,擦用java语言编程。

步骤分析:

1、项目需求分析:模仿京东商城系统。

2、项目数据库设计:商品信息表、商品信息分类表、商品信息描述表、商品规格参数表。

3、CMS系统内容表、CMS系统内容分类表。

4、用户表、订单表、订单的具体明细表。

具体实现:

1、框架的搭建:

这里采用maven来管理整个项目。

优势两点:

1、maven可以以管理整个项目工程,方便热部署项目,项目发布方便。

2、maven管理你jar包具有很大的优势,可以自动下载所需的jar包,只需定义好版本即可,其他maven自动下载。

因为这个项目比较大,子工程比较多,所以我们建立一个pom类型(聚合工程)parent来管理里所有jar包的版本,这样其他 子工程都依赖此工程。版本得到了统一,不会出现因版本问题导致的错误。其次建立一个专门的(jar类型)common工具类,可以将系统中使用到的工具类都加入此类,其他类也依赖此类,就可以使用这里面的工具了。此工具类也依赖parent类。

下面就是利用SSM框架来搭建工程了:利用框架搭建工程主要分两步:框架所依赖的jar包,框架的配置文件。弄清了这两点就好办了。

框架主要分三层:

dao层(mybatis)(主要是与数据库打交道)、service层(spring)(主要是负责调用dao层,实现业务逻辑的编写)、controller层(springMVC)(这里主要调用service层,根据jsp页面的内容,将jsp的内容传递到service层,然后讲数据显示到jsp页面)。

所以这里的配置文件也就:mybatis的SqlMapConfig.xml (主要是它的插件配置,数据库配置放在dao)。spring将mybatis和springMVC整合起来的application_context_dao.xml(配置数据源,与数据库的连接),application_context_service.xml(将service的文件包引入工程)。application_context_transation.xml(这里将事务独立出来,主要是事务的配置)

SpringMVC.xml(主要是前端控制器,试图解析器的配置)

框架搭建完成后,利用mybatis的逆向工程生成各个表的mapper.xml和mapper.java文件、pojo文件。

2、具体的功能的实现逻辑

(1)后台系统功能实现

(这里主要讲商品的查询、添加、规格参数、CMS系统的分类、添加)

其实对于功能模块的分析主要有三点:

从哪个数据表获取(主要mapper实现);页面传递是否有参数,页面的url是什么(controller实现);返回值是什么(即页面展示的格式是什么样子的,这个根据jsp使用的框架来决定,比如这里的easyUI,可以查询它的api文档,找到其返回值类型);

A、商品的查询逻辑分析:其实对于商品的查询主要就是从数据库中将所有商品查询出来。这简单的查询很简单,可是在页面分页显示出来这就是一个问题了。这里到了mybatis的分页插件pageHelper来实现。

1、传入参数:Easyui页面默认有page、rows参数传递。

2、返回值:easyui的格式即datagrid的格式,专门编写一个对应的pojo类放入专门工具类中使用,返回格式即这个pojo。

3、逻辑:Dao层:Dao层用mybatis的逆向工程

4、Service调用mapper的查询和分页实现逻辑。

5、Controller即将参数传递过去,url写好

B、商品添加:商品添加即将商品信息写入数据库,页面传递的内容当点击提交按钮时直接写入数据库,只需补全没有的字段即可。

这里涉及到商品的类目选择、上面的图片上传、商品的描述信息。

类目选择首先得将类目展示出来,这里使用的异步树的格式。查询api发现异步树的返回值的格式。主要思路是:根据parentId来查询类目表,默认从0开始,异步树有个特点,就是每次获取到的id,如果有子节点,会发送url再次请求,如果没有子节点则不发送请求,所以可以都遍历到所有节点。(这个是tree的特点,自动请求)

1、异步树的特点:从最顶层开始读取,先读顶层节点,如果是闭合状态,发送请求给服务器读取子节点,子节点的状态依赖于父节点,当展开一个封闭的节点时,如果节点没有加载子节点,它将会把节点的id的值作为http请求参数并命名为id,通过url发送到服务器上检索子节点。所以遍历一次后,如果父节点还是父节点(即存在子节点)则检索下面的子节点的内容,将子节点的id作为parentId来检索下面的节点。如果不是父节点了,则打开下面列表。也就是说这些实现都是 异步树自动实现的,我们只需要判断父节点的状态即可,下面的检索根据这个状态进行。

2、图片上传功能:因为商城的图片非常多,所以我们将这么多的图片保存在图片服务器中,然后将图片在服务器中的具体url写入数据库,供前台调用。前台获取到这个url既可获取到这个图片。这里图片上传到服务器的功能:先生存图片的名称,然后生成图片保存的格式,然后利用ftpUtil将图片上传到服务器,返回一个url链接。

3、商品规格参数,这里采用的规格参数模板的形式:

(1)这里有两个表:

一个模板表(根据商品的分类建立的模板,根据分类id),一个展示模板表(根据商品的信息写入模板表,根据商品id查询商品信息,然后写入对应订单模板中,然后生成HTML)。

1、商品的描述:这里采用文本的形式存储的,写入即可。富文本编辑器。

2、CMS分类:这里的格式也是用了异步树的格式,所以显示方法是一样的。

3、分类添加:像表中插入数据库即可。

(2)前台功能实现

首页大广告位的实现:这里是从CMS系统中获取广告位的图片,然后展示在页面。但是前台跟后台是不一样的端口,如何从前台访问后台呢,可以使用jsonp的形式。但是我们这里系统是采用面向服务的编程,所以采用rest接口的方式然后功能前台调用,这里用的httpcliet来调用接口。

(3)商品搜索功能的实现:

首先在linux下部署好solr服务器,然后将数据库的表字段导入到solr索引库。然后编写search服务接口,然后供前台调用这个服务接口。

1、Rest功能:

商品详情页面展示:写三个服务:根据id查询商品的具体信息显示到页面,根据id查询商品的内容表,根据id查询商品的规格参数,即将三个信息展示到页面。然后前台分别调用。

2、SSO系统:这里涉及到拦截器:

这里是利用了sso的接口文档,即校验接口、注册、登录接口、根据token查询用户接口、安全退出接口。这个的调用服务层是利用jsonp的形式访问的服务接口,实现跨域访问。客户端全部在jsp页面实现的。

3、具体流程:

当用户点击注册的时候,跳转到注册页面,即用户信息的保存功能。检验用户名是否存在、手机号和邮箱不能为空。

当用户点击登录按钮的时候,用户输入用户名和密码,检验用户名是否在数据库中存在,然后用户名密码是否正确。这里的密码是用了spring的MD5加密技术。当全部成功后,给用户颁发一个token令牌(利用uuid实现),然后将token存入到redis中(token的key是它生成的号,值是用户的名字),然后设置在redis的过期时间。这相当于用户的session。

然后将token写入cookie中,前台页面利用jsonp调用,根据cookie中的token的值,调用sso的根据token查询用户的服务,查看用户是否有效,如果有效则将用户返回前台页面,前台页面获取用户的用户名显示在首页,表示***已登陆。

这里的cookie是设置了共享域,即全部子系统都可以访问到cookie。

当用户登录其他子系统时,先从从cookie中获取token信息,根据token信息获取用户信息,判断用户信息是否有效,如果有效则放行,如果无效,则利用拦截器拦截跳转到登录页面。用户再次登录的时候刷新redis的时间,重新设置有效期。拦截器的拦截,在springMVC.xml中设置拦截的名称。

购物车功能:

购物车功能注意到这里商品加入购物车,是将购物车保存在cookie中。这里用到cookieUtil工具来实现这些保存删除功能。在商品详情页面点击“加入购物车”按钮提交一个请求吧商品id传递给Controller,Controller接收id,Controller调用Service根据商品id查询商品基本信息,购物车的商品专门写一个pojo对象,因为商品的很多信息购物车里面用不到。将购物车的商品的pojo,把商品写入cookie中,加入cookie之前先从cookie中把购物车的商品取出来判断当前购物车商品列表中是否有此商品,如果有数量加一,如果没有添加一个商品,数量为1。展示给用户购物车列表。

订单系统:订单系统主要是订单的创建、查询、修改、删除功能。

订单系统因为pc端和移动端都需要调用此功能模块,所以将订单系统也单独作为一个服务接口供客户端调用。

订单服务接口也有接口文档,根据文档进行订单的创建。

订单的创建需要用户登录,这里用到了拦截器在springMVC中配置下拦截方式即可。

当用户拦截成功后,用户登录该商城,这时候注意将用户保存在request中,目的是因为查询订单的时候需要根据用户的id来查询,不同的用户具有不同的订单啊。

然后用request的get和setAttribute来获取值、设定值。为什么可以从request中取,因为我们整个商城都是http协议访问的。

(1)订单创建逻辑:

当点击去去购物车结算时,显示购物车的列表,当选中购物车的商品点击去结算的时候,显示商品的提交订单之前的一系列信息(也就是结算页):针对数据库三张表:订单基本信息表、订单明细表(购买的商品信息)、订单配送(收货人的地址电话信息)

传入参数:因为创建订单也就是向数据库中插入一系列的信息,而对应的是数据库中的三个表,所以根据页面的内容,传入的参数也就是三个pojo类,然后页面填写的+补全页面上在数据库中没有的字段。所以主要是对数据库中的三个表进行插入操作。服务接口是负责接收这三个pojo类,所以客户端要想办法将这三个pojo类传递过来。

根据接口文档,返回的是一个json格式的数据,即这三张表的数据是在一个json串中,所以这里要想办法将这三个表单独建立一个pojo来保存这个返回值。

分布式电商系统项目总结

接收的pojo类:

这里采用了这种方式巧妙的将三个表合并起来了。

接下来就是数据的插入操作了,这个在service层实现:逐个表的插入数据库即可,然后返回一个订单号即订单的id。

controller层传递的就是这个pojo类,然后返回给客户端。

客户端也是将这个pojo类传递给服务接口,返回一个订单号给客户端。提交订单的时候显示订单提交成功页面时候,看下jsp页面显示哪些字段,然后用model传递给页面。

(2)订单的分页查询:

前面我们将用户保存在了request中,然后获取到用户的id,根据用户的id来查询订单,前台页面默认传递page和rows,利用mybatis的分页查询来查询订单即可。

分布式电商系统项目总结

传入参数:page和rows

执行操作:根据用户id查询订单,根据page和rows分页

返回值:订单的列表信息,即用户的多个订单信息。根据接口文档,我们发现这个返回的信息就是数据中订单表的部分信息,所以用几个字段组成一个新的pojo来接收返回值。

分布式电商系统项目总结

(3)根据订单id查询订单:

根据订单id查询订单这个显示的信息就比较全面了,这个返回值跟之前的三个数据库的表对应,所以根据id,分别查询这三个表,来获取对应的信息。

1、传入参数:订单id;

2、操作:三个表分别查询;

3、返回值:之前新定义的三个表的Order的pojo类;

来源:博客园

<数商云(www.shushangyun.com)是国内知名企业级电商平台提供商,为企业级商家提供最佳的系统开发(多种模式电商平台搭建:B2B/B2B2C/B2C/O2O/新零售等)、供应链系统搭建及电商行业解决方案服务>

网站声明:以上内容为数商云电子商务系统网站的原创文章,如需转载,请注明出处,谢谢合作!
上一篇: 电商系统架构
评论
剩余-200
发表

填写以下信息, 免费获取方案报价

姓名
手机号码
你的职位
企业名称
需求描述

请您填写以下信息,马上预约演示

姓名
手机号码
你的职位
企业名称

恭喜您的需求提交成功

尊敬的用户,您好!

您的需求我们已经收到,我们会为您安排专属电商商务顾问在24小时内(工作日时间)内与您取得联系,请您在此期间保持电话畅通,并且注意接听来自广州区域的来电。
感谢您的支持!

console.log();