热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MMall项目完整分析总结

Linux服务器线上环境:1.jdk2.vsftpd3.nginx4.mysql5.tomcat6.git7.maven8.Redis项目采用Tomcat集群方式:在

Linux服务器

线上环境:

  1.jdk    2.vsftpd   3.nginx

  4.mysql       5.tomcat

  6.git   7.maven    8.Redis

项目采用Tomcat集群方式:

在此架构图中,nginx使用的是轮询的负载均衡策略。session不交给tomcat自己管理,已经交由左侧的redis分布式集群来管理。

服务器的文件独立存放于文件服务器上。用户在请求的时候会经过nginx的分配访问到各个Tomcat服务器上。


 

项目的模块划分目录:

  1.用户管理模块    2.分类管理模块    3.商品模块

  4.购物车模块       5.收货地址模块    6.支付模块    7.订单模块


 

项目各模块详细解析

-----------------1.用户管理模块-----------------

  功能模块:

    登录        login(String username, String password);

    用户名/邮箱验证    checkValid(String str,String type);

    注册        register(User user);

    忘记密码      forgetResetPassword(String username,String passwordNew,String forgetToken); 

    提交问题答案    checkAnswer(String username,String question,String answer);

    重置密码      resetPassword(String passwordOld,String passwordNew,User user);

    获取用户信息(无密码) getInformation(Integer userId);

    更新用户信息    updateInformation(User user);

    退出登录      logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse)

  技术学习:

    横向越权、纵向越权安全漏洞

    MD5明文加密及增加salt值

    Guava缓存的使用

    高复用服务响应对象的设计思想及抽象封装

    Mybatis-plugin

    Session的使用

   用户模块注意:      

      1.在密码存入数据库前使用MD5进行编码,取出时再使用MD5解码(普通MD5加密形式网上已有解码方式,为提高安全性,需另外在md5上添加逻辑)      2.注册用户时需要在数据库中查询是否有相同的用户名和邮箱(可单独写一个方法查询用户名与邮件是否已存在)      3.忘记修改密码时当验证问题正确时会附带有一个记号返回。(记号用于传递给修改密码的时候,可以提高用户的安全性,防止他人传值修改密码。当修改密码的时候会验证记号是否在存在与有效期内,若是存在且在有效期内方可修改)      4.客户修改信息时,在将User传回数据库修改时username是不可修改的。且email在修改时需要验证新的email是否已存在。如果存在相同email的话,不能是我们当前的这个用户的      5.在登录后台页面时需验证是否为管理员

-----------------2.分类管理模块-----------------

  功能模块:

    获取节点      getChildrenParallelCategory(Integer categoryId);

    增加节点      addCategory(String categoryName, Integer parentId);

    修改节点      updateCategoryName(Integer categoryId,String categoryName);

    获取分类ID     getChildrenParallelCategory(Integer categoryId);

    递归子节点ID    selectCategoryAndChildrenById(Integer categoryId);

  技术学习:

    如何设计及封装无限层级的树状数据结构

    递归算法的设计思想

    如何处理复杂对象排重

    重写hashcode和equal的注意事项

   产品模块注意:

      1.在上传文件时需验证是否为管理员,在上传文件的大小上限制最大为4m      2.上传文件流程为,先将文件保存到tomcat服务器上的update文件夹中,随后连接FTP服务器,配置好上传FTP工具类后将tomcat服务器上存放的文件通过工具类转移到FTP服务器指定文件夹下,然后删除掉tomcat服务器中的原先文件。      3.富文本上传与SpringMVC上传最明显的区别在于返回值上,其次富文本上传成功后在返回时需设置响应头response.addHeader("Access-Control-Allow-Headers","X-File-Name");

 

-----------------3.商品模块-----------------------

  功能模块:

    前台

      商品搜索    searchProduct(String productName,Integer productId,int pageNum,int pageSize);   

      商品列表    list(String keyword,Integer categoryId,int pageNum,int pageSize,String orderBy)

      商品详情    getProductDetail(Integer productId);

    后台

         商品列表    getList(HttpServletRequest httpServletRequest, int pageNum,int pageSize)

      商品搜索    productSearch(String productName,Integer productId,int pageNum,int pageSize);

      图片上传    upload(HttpServletRequest httpServletRequest,MultipartFile file,HttpServletRequest request)

      富文本图片上传 richtextImgUpload(HttpServletRequest httpServletRequest, MultipartFile file, HttpServletRequest request, HttpServletResponse response)

      商品详情    getDetail(HttpServletRequest httpServletRequest, Integer productId)

      商品上下架   setSaleStatus(HttpServletRequest httpServletRequest, Integer productId, Integer status)

      增加商品    productSave(HttpServletRequest httpServletRequest, Product product)

  技术学习:

    FTP服务的对接

    SpringMVC文件上传

    流读取Properties配置文件

    抽象POJO、BO、VO对象之间的转换关系及解决思路

    joda-time快速入门

    静态块

    Mybatis-PageHelper高效准确地分页及动态排序

    Mybatis对List遍历的实现方法

    Mybatis对where语句动态拼装的几个版本演变

   产品模块注意:

      1.在上传文件时需验证是否为管理员,在上传文件的大小上限制最大为4m      2.上传文件流程为,先将文件保存到tomcat服务器上的update文件夹中,随后连接FTP服务器,配置好上传FTP工具类后将tomcat服务器上存放的文件通过工具类转移到FTP服务器指定文件夹下,然后删除掉tomcat服务器中的原先文件。      3.富文本上传与SpringMVC上传最明显的区别在于返回值上,其次富文本上传成功后在返回时需设置响应头response.addHeader("Access-Control-Allow-Headers","X-File-Name");

-----------------4.购物车模块--------------------

  功能模块:

      加入商品      add(HttpServletRequest httpServletRequest, Integer count, Integer productId)

      更新商品数     update(HttpServletRequest httpServletRequest, Integer count, Integer productId)

      查询商品数     getCartProductCount(HttpServletRequest httpServletRequest)

      移除商品      deleteProduct(HttpServletRequest httpServletRequest,String productIds)

      单选/取消       select(HttpServletRequest httpServletRequest,Integer productId),unSelect(HttpServletRequest httpServletRequest,Integer productId)

      全选/取消       selectAll(HttpServletRequest httpServletRequest),unSelectAll(HttpServletRequest httpServletRequest)

      购物车列表       list(HttpServletRequest httpServletRequest, Integer count, Integer productId)

  技术学习:

       购物车模块的设计思想

      如何封装一个高复用购物车核心方法

      Bigdecimal解决浮点型商业运算中丢失精度的问题

   购物车模块注意:

      1.在购物车内产品数量修改时验证是否超过数据库中产品库存,若超出则改为产品库存最大量(如修改为200台手机,此时发现数据库只有100台,则将购物车中购买数改为100)      2.在购物车开发时肯定会接触到价格数字上的运算,这时候若是用普通的数据类型进行运算则容易产生丢失精度。此时可以用到java中的BigDecimal类进行运算,该类中的字符串构造方法可保证运算时精度的准确度。      3.在购物车的价格数字上的运算上偶尔会有除不尽的情况,此时应该尽可能保持精度然后选择保留几位小数且四舍五入

-----------------5.收货地址模块-----------------

  功能模块:

      添加地址    add(Shipping shipping)

      删除地址    del(HttpServletRequest httpServletRequest, Integer shippingId)

      修改地址    update(HttpServletRequest httpServletRequest, Shipping shipping)

      地址列表分页  select(HttpServletRequest httpServletRequest, @RequestParam(value = "pageNum",defaultValue = "1") int pageNum,@RequestParam(value = "pageSize",defaultValue = "10") int pageSize)

      地址详情    select(HttpServletRequest httpServletRequest, Integer shippingId)

  技术学习:

         SpringMVC数据绑定中对象绑定

      mybatis自动生成主键、配置和使用

      如何避免横向越权漏洞的巩固

   地址模块注意:

      1.避免横向越权(用户登录后,在接口处传递shippingID时使用他人的shippingid)(在sql语句上处理shipping时加上userId判断即可)

-----------------6.支付模块-----------------------

  功能模块:

      支付宝对接    pay(HttpServletRequest httpServletRequest, Long orderNo, HttpServletRequest request)

      支付回调     alipayCallback(HttpServletRequest request)

      查询支付状态     queryOrderPayStatus(HttpServletRequest httpServletRequest, Long orderNo)

  技术学习:

       支付宝调试技巧

      熟悉支付宝对接核心文档,调通支付宝支付功能官方Demo

      解析支付宝SDK对接源码

      RSA1和RSA2验证签名及加解密

      避免支付宝重复通知和数据校验

      生成二维码,并持久化到图片服务器

   支付模块注意:

      1.在订单的回调时会访问地址,由于我们的外网穿透使用的是免费的所以域名不稳定,每次都需要重新配置,可购买域名以及稳定的通道进行绑定。      2.在支付宝的回调验签时,会判断是否为支付宝发出的签并且还要避免重复的通知      3.支付宝的回调验签默认为utf-8编码,若想指定编码则需在构造ClientBuilder类时指定好编码

-----------------7.订单模块-----------------------

  功能模块:

      前台

        创建订单    create(HttpServletRequest httpServletRequest, Integer shippingId)

        选中商品信息  getOrderCartProduct(HttpServletRequest httpServletRequest)

        订单列表    list(int pageNum, int pageSize)

        订单详情    detail(HttpServletRequest httpServletRequest,Long orderNo)

        取消订单    cancel(HttpServletRequest httpServletRequest, Long orderNo)

      后台 

        订单列表    orderList(HttpServletRequest httpServletRequest, int pageNum, int pageSize)

        订单搜索    orderSearch(HttpServletRequest httpServletRequest, Long orderNo,int pageNum,int pageSize)

        订单详情    orderDetail(HttpServletRequest httpServletRequest, Long orderNo)

        订单发货    orderSendGoods(HttpServletRequest httpServletRequest, Long orderNo)

  技术学习:

         避免业务逻辑中横向越权和纵向越权等安全漏洞

        设计实用、安全、扩展性强大的常量、枚举类

        订单号生成规则、订单严谨性判断

        POJO和VO之间的实际操练

        mybatis批量插入

    订单模块注意:

     1.订单模块涉及到很多商品,订单条目,地址,订单详细等内容,在该模块我们会创建很多相对应的装配对象(VO),将对象装配好再返回。  


项目后端开发分析

1.在Git托管服务上选择使用国内的Gitee,之所以选择Gitee而不是选择GitHub是因为GitHub为国外的平台,国内的用户在使用上经常遇到的问题就是访问的速度太慢,有时候还会出现无法连接的情况。和GitHub相比Gitee也提供免费的Git仓库。此外,还集成了代码质量检测、项目演示等功能。对于团队协作开发,Gitee的还提供了项目管理、代码托管、文档管理的服务,5人以下小团队免费。

2.项目统一字符集UTF-8

3.为了方便前期的项目接口测试 没有限制访问方式(Get/Post/Put....)

4.为避免横向越权(当前用户去操作其他用户的所有),在大部分的sql查询上添加上了userId这一条件,这样就不会去查询到不属于该用户的所有了

5.在访问数据库之前尽可能做好条件判断,如果不成立,则直接手动返回错误,尽量减少对数据库的访问。  例如(查询当前用户订单时,提前判断好接口传递过来的参数是否有值,若无值则直接返回参数有误)  (参数有误在接口开发上需大量使用到,则直接声明在常量类上)

6.在做订单支付时需处理好状态码且等待第三方的回调,等回调成功后方可改为支付成功(避免单方帐) (单方帐:买方提交订单后未支付成功订单,然后后台显示支付成功。或是相反)

7.为方便项目后期的更新改进,在接口处要使前后端分离

8.项目中大量使用到分页功能,于是我们可以将分页独立出一个对象

9.在项目的搭建时对代码做好校验,在可能出现错误的地方做好try-catch,避免项目放在运行的时候报错,这样会很麻烦。

10.项目中的pojo类大量使用到Getter和Setter方法,这里我们引入Lombok工具,它可以通过简单注解来精简代码达到消除冗长代码的目的。

11.在项目的开发会面临到各个阶段的开发时期,有本地开发环境(Local)、开发环境(Dev)、测试环境(Beta)、线上环境(Prod)   在各个时期使用到的环境,数据库FTPServer等等都是不一样的,所以这里我们引入Maven环境隔离

12.在项目开发时,为提高服务端效率,项目采用了tomcat集群。既然采用了集群,那就要考虑到session的存放,这里我们选用了Redis进行集体存放   在存放的时候呢我们采用JSessionID当键存入Redis,但是nginx负载均衡会将服务分发给各个tomcat,每个tomcat的JSessionID都不相同,在Redis取值的时候   也面临取不到值的状况。此时我们改用COOKIE来存放对应的键,当用户在进行单点登录的时候,被负载均衡到另一个服务器的时候,COOKIE也会跟随着浏览器去             到另一个服务器。

13.在我们用户登录后将session存放(User)到Redis的时候(存储时间30分钟)。此时我们在网站中浏览30分钟后,发现Redis中存储的对应数据到指定时间被清除了。   这个时候我们设置了一个过滤器(Filter),当我们在项目中进行操作(*.do)的时候触发过滤器,将我们存放在Redis的数据的消除时间重计

14.在用户模块中有个忘记密码功能,为了避免横向越权,我们加入了TokenCache做了记号,在忘记密码修改密码的时候需带记号进行修改

   初期没做tomcat项目集群的时候,TokenCache是存放在tomcat上的。在做了集群后呢,我们应当将其迁移到Redis上。

15.后期若是还要提升,可以将用户模块单独拿出做成服务中心,这样也可以对项目有个解耦的效果

16.在项目的开发中会面临很多的传参,在传参的时候我们要考虑到是使用基本类型还是包装类型,拿int和Integer举例,当我   们在面临age的传参时,如果是基本类型int,那这个key是必须传参数的,不能为Null。如果是包装类型Integer,那这个   key是可以为null的。在项目的开发中应当尽量避免报错,所以在参数类型的选择上应该选择好

17.考虑到项目的管理员模块涉及到许多的登录/权限的校验,我们采用SpringMVC拦截器进行权限拦截。



推荐阅读
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 如何在php文件中添加图片?
    本文详细解答了如何在php文件中添加图片的问题,包括插入图片的代码、使用PHPword在载入模板中插入图片的方法,以及使用gd库生成不同类型的图像文件的示例。同时还介绍了如何生成一个正方形文件的步骤。希望对大家有所帮助。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • PG12新增的VACUUM命令的SKIP_LOCKED选项
    PG12版本的VACUUM命令新增了SKIP_LOCKED选项,该选项使得vacuum命令在遇到被lock住的table时可以跳过并被视为成功执行。之前的版本中,vacuum命令会一直处于等待状态。本文还提到了PostgreSQL 12.1版本的相关信息。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 负载均衡_Nginx反向代理动静分离负载均衡及rewrite隐藏路径详解(Nginx Apache MySQL Redis)–第二部分
    nginx反向代理、动静分离、负载均衡及rewrite隐藏路径详解 ... [详细]
  • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
  • 像跟踪分布式服务调用那样跟踪Go函数调用链 | Gopher Daily (2020.12.07) ʕ◔ϖ◔ʔ
    每日一谚:“Acacheisjustamemoryleakyouhaven’tmetyet.”—Mr.RogersGo技术专栏“改善Go语⾔编程质量的50个有效实践” ... [详细]
author-avatar
浩哥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有