码神之路电商笔记

所用技术:

springboot,dubbo,nacos,mysql,elasticsearch(商品需放在里面),spark,redis,rocketmq,sharding-jdbc等。

项目开始:

内部模块对外提供接口是buyer-api,调用内部的dubbo
service服务(注意api是可调用多个service服务)。

dubbo:

在这里插入图片描述
注册中心用的nacos,注册内容为ip:port/接口名称/方法名称。

本机多环境的配置:

在这里插入图片描述
前端跨域地址可写在properties中,使用注解
@Value("${buyer.url}")获取
private String buyerUrl;

api接口模块配置:

在这里插入图片描述
api在这里 属于服务消费方需要去nacos寻找服务。

provider提供者配置:

在这里插入图片描述
只有在这个配置下的才会被扫描到(需加dubbo的服务注解@DubboService),并提供相应服务通常写在service模块中。

nacos:

在bin目录下cmd中输入:单机启动startup.cmd -m standalone

地址为:http://localhost:8848/nacos/index.html#/login

WebMVCConfig跨域配置:

@Configurationpublic class WebMVCConfig implements WebMvcConfigurer {   
@Value("${buyer.url}")    
private String buyerUrl;   
@Override 
public void addCorsMappings(CorsRegistry registry) { 
registry.addMapping("/**").allowedOrigins(buyerUrl);    
   }
}

需实现WebMvcConfigurer接口,写上允许跨域的url请求地址。

nacos中服务列表-服务名和组名:

在这里插入图片描述
1.服务名 要唯一,如果服务名一样 会组成集群
2.组名是 服务在不在一个分组内
3.如果不在 不能进行互通

分组名的的名字在application中编写为dubbo.registry.group=dubbo_buyer_service所设置。
服务名由@DubboService所备注的接口名字提供。
额外
spring.application.name=mall-service-provider
服务启动名称如有一样多的服务 那么nacos的实例数就会增加
也就是说服务消费方调用的时候,nacos可以根据负载均衡策略 来进行提供服务提供者的地址
系统的承载能力就强

Knife4j:

为Swagger增强版本,配置如下

@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
    Docket docket=new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(new ApiInfoBuilder()
                    .title("码神商城API列表")
                    .description("码神商城 rest API列表")
                    .termsOfServiceUrl("https://mall.mszlu.com/")
                    .contact(new Contact("码神之路","","mall@mszlu.com"))
                    .version("1.0")
                    .build())
            //分组名称
            .groupName("3.X版本")
            .select()
            //这里指定Controller扫描包路径   .apis(RequestHandlerSelectors.basePackage("com.mszlu.shop.buyer.controller"))
            .paths(PathSelectors.any())
            .build();
    return docket;
  }
}

统一异常处理:

@ControllerAdvice
@Slf4j
public class BusinessExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result doException(Exception e){
    e.printStackTrace();
    log.error("出异常了:{}",e.getMessage());
    return Result.fail();
 }
}

@ControllerAdvice注解 ,增强Controller。
可以实现三个方面的功能:
全局异常处理
全局数据绑定
全局数据预处理
SpringMVC 提供的功能,可在Spring Boot 中可以直接使用。

全部商品分类查询后并保存到前端:

一.
在这里插入图片描述
二.
在这里插入图片描述
这种分类数据一般都是固定的,一般不用每次都请求后端。
第一次请求后,就把子节点的数据加在父节点里面list并获取所有的树形父子结构数据并保存到浏览器中。

热搜词与redis的zset:

在这里插入图片描述
按照分数存入,进行有序的排列数据。

opsForZSet().reverseRangeWithScores(HOT_WORDS_REDIS_KEY, 0, 2);

逆序获取数据,相当于先拿热度(分数)最高的数据放在前面,并控制获取元素数量大小。

Page分页:

使用mybatisplus的分页插件,以page类型返回数据,Result<Page<ArticleVO>>

实战也没做过,得new一个page对象泛型为实体类,在设置当前页和页面大小

public Page(long current, long size) {
        this(current, size, 0L);
    }
private static final long serialVersionUID = 8545996863226528798L;
    protected List<T> records;
    protected long total;
    protected long size;
    protected long current;
    protected List<OrderItem> orders;
    protected boolean optimizeCountSql;
    protected boolean searchCount;
    protected String countId;
    protected Long maxLimit;

并将所取的实体类数据存在records中。

登录前进行图片滑动验证获取:

代码思路,前端传来一个uuid(来证明未登录用户的一个唯一标识的sessionId),并再传一个正登录标识之类的。
数据库存两种资源,一个是RESOURCE原图资源,另一个SLIDER滑块的原图资源。
随机操作两种资源的其中一个,使用工具类SliderImageUtil.pictureTemplatesCut(放入其中一个SLIDER的url,再放入RESOURCE的url),两种url都可访问。

切割好的对象数据如下图
在这里插入图片描述
滑块base64和原图背景的模块base64等等,什么是base64?
图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址。
优点:减少请求数量(减轻服务器压力)
缺点:图片体积会更大(文件请求速度更慢)
所以一般8-12kb以下的图片适合用base64。
eg:生成的两个base64可用转码工具转成原图片。
业务逻辑实现继续,再存入uuid为键,再将切割出来的数据x坐标(抠图坐标)放入值中,形成键值对。
一个用户对应一个x坐标,并存过期时间。
再将切割好的图片的x坐标设置为0,再放回给前端,让滑动的图片一开始就最左边开始滑动。

SliderImageCut sliderImageCut = SliderImageUtil.pictureTemplatesCut(
getInputStream(sliderUrl), getInputStream(resourceUrl));
//如果不设置为0  滑块直接就匹配
//生成验证参数 120可以验证 无需手动清除,120秒有效时间自动清除
redisTemplate.opsForValue().set(verificationRedisKey(uuid, verificationEnums), String.valueOf(sliderImageCut.getRandomX()), 120, TimeUnit.SECONDS);
sliderImageCut.setRandomX(0);

登录前进行图片滑动验证:

代码思路传三个参数,登录标识,该登录的uuid和滑动的坐标,去redis寻找该登录用户的uuid所对应的x坐标值,
和传来的滑动的坐标x作比较。

//允许有误差
boolean result = Math.abs(Integer.parseInt(x) - xPos) < 3;
//滑块验证成功之后 随后的一段时间 如果有操作,认为是验证通过的 不需要重复进行滑块验证          redisTemplate.opsForValue().set("VERIFICATION_IMAGE_RESULT_"+verificationEnums.name()+uuid, "true", 120,TimeUnit.SECONDS);

登录:

使用了token令牌的登录认证方式。
单点登录一般使用jwt技术实现,jwt是一个加密技术,用于生成token。
在进行登录认证的时候,buyer-api使用security进行认证,调用sso服务,进行登录认证。

JWT:

JWT一般由三部分组成,分别是头信息、有效载荷、签名。

AuthUser authUser = new AuthUser(member.getUsername(),String.valueOf(member.getId()),member.getNickName(), UserEnums.MEMBER);
String accessToken = TokenUtils.createToken(member.getUsername(), authUser, 7 * 24 * 60L);

jwt有好多种加密算法,一般默认为hash256
项目中用了Base64.decodeBase64。
该电商项目中使用的工具类,放了四种
//jwt私有声明
//JWT的主体
//失效时间 当前时间+过期分钟
//签名算法和密钥
在这一步设置token的过期时间是为了后面解析的时候,如果过期直接就拒绝,不让它在访问Redis耗费时间。

在这里插入图片描述

实现HandlerInterceptor拦截器:

过滤器与拦截器的区别:拦截器是AOP思想的具体应用。

过滤器:

servlet规范中的一部分,任何java web工程都可以使用。

在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截。

拦截器:

拦截器是SpringMVC框架自己的,只要使用了SpringMVC框架的工程

才能使用,拦截器只会拦截访问的控制器方法,如果访问的是jsp/html/css/image/js是不会进行拦截的。

最常用的是登录拦截、或是权限校验、或是防重复提交

想要自定义拦截器,就必须实现HandlerInterceptor接口。

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception;
		
void postHandle(
		HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
		throws Exception;

void afterCompletion(
		HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
		throws Exception;

公钥与私钥:

项目中的token加密那部分,使用的是对称加密,加密和解密为同一个。
并对公钥与私钥的概念做一个笔记。
1.密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥。

2.密钥分为两种:对称密钥与非对称密钥。

3.对称密钥加密,又称私钥加密或会话密钥加密算法,即信息的发送方和接收方用同一个密钥去加密和解密数据。它的最大优势是加/解密速度快,适合于对大数据量进行加密,但密钥管理困难。

4.非对称密钥加密系统,又称公钥密钥加密。它需要使用不同的密钥来分别完成加密和解密操作,一个公开发布,即公开密钥,另一个由用户自己秘密保存,即私用密钥。

5.对于普通的对称密码学,加密运算与解密运算使用同样的密钥。通常,使用的对称加密算法比较简便高效,密钥简短,破译极其困难,由于系统的保密性主要取决于密钥的安全性,所以,在公开的计算机网络上安全地传送和保管密钥是一个严峻的问题。

SpringSecurity 与单点登录的token:

项目的Security安全认证貌似都是以继承WebSecurityConfigurerAdapter适配器为基础, 在配置的时候,需要我们自己写个配置类去继承他,然后编写自己所特殊需要的配置
比如无需进行登录就可以访问的连接,和允许跨域等。
并添加我们需要的业务,JWT认证过滤器。
至此在前端发起登录时(需要过滤操作的)我们重写BasicAuthenticationFilter结果过滤器FilterInternal方法,使用(HttpServletRequest)request.getHeader方法获取请求头token(JWT),如果存在的话并对该token解析,利用的同一个密钥看是否"正常",并将解析出来的json转换成用户对象,并用这个传来的token往redis查一遍里面有没有这个token(是上一步返回后并保存到redis里)防止伪造。如果有则认定该token具有权限,并进行业务操作将用户对象返回,存到当前SecurityContextHolder.getContext().setAuthentication(authentication)中。
该步骤是为了后面业务层获取当前用户。

Spring Security使用一个Authentication对象来描述当前用户的相关信息。SecurityContextHolder中持有的是当前用户的SecurityContext,而SecurityContext持有的是代表当前用户相关信息的Authentication的引用。这个Authentication对象不需要我们自己去创建,在与系统交互的过程中,Spring Security会自动为我们创建相应的Authentication对象,然后赋值给当前的SecurityContext。

后续需在业务实现层使用AuthUser currentUser = UserContext.getCurrentUser()(封装了SecurityContextHolder.getContext().getAuthentication())来获取用户的一些字段值等,去数据库配对,返回用户具体信息给前端。

登录基本过程概念

1、检查参数是否合法

2、根据用户名或者密码去user准备去表中查询(参考了博客项目)

这里两种方式:

传来的明文密码md5下并加盐(默认该用户注册的时候就这样做的,并已经存到数据库里了),加完后带用户名和密码去数据库查如果没查到就是账户or密码输入可能有误。

另一种用的security的提供的bcrypt的加密方式

//底层会随机的给密码加盐
BCryptPasswordEncoder encoder =new BCryptPasswordEncoder();
String encode = new BCryptPasswordEncoder().encode("123456");

boolean matches = new BCryptPasswordEncoder().matches("123456", encode);
System.out.println(matches);

true

先用户名去查数据库,查到该用户的数据中的密码(相当于encode),
然后用security的提供的技术BCryptPasswordEncoder().matches方法和传来的明文123456作比较它两是否正确。

3、如果不存在,登录失败

4、如果存在,使用jwt生成token返回给前端

5、token放入redis当中,redis token:user信息 设置过期时间 * (登录认证的时候,先认证token字符串是否合法,去redis认证是否存在)

退出登录的话就是把token传来,删除在redis里面的token。

SPU和SKU的概念:

SPU : 标准化产品单元。 是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。通俗点讲,属性值、特性相同的商品就可以称为一个SPU。
SKU : 库存量单位。 是库存进出计量的基本单元,可以是以件,盒,托盘等为单位。SKU是物理上不可分割的最小存货单元。在服装、鞋类商品中使用最多最普遍。
简单来说苹果6是一个spu,苹果6加上要选的颜色和内存大小就是一个具体的sku。

购物车添加前:

目前电商项目中添加商品的接口采用pc端方式,没有登录是无法添加购物车的。与霍哥沟通是目前市场上趋势pc端将不再未登录的情况下添加购物车,而app端也就是手机端可以未登录就添加购物车,app端可以用手机的mac地址,序列号,手机型号等生成唯一用户Id。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值