微服务实战——注册功能

注册

1.1. 配置

@Configuration
public class GulimallConfig implements WebMvcConfigurer {/*** 视图映射* @param registry*/@Overridepublic void addViewControllers(ViewControllerRegistry registry) {/***     @GetMapping("/login.html")*     public String loginPage(){*         return "login";*     }*/registry.addViewController("/login.html").setViewName("login");registry.addViewController("/reg.html").setViewName("reg");}
}

1.2. 整合短信服务

compoent

package com.cwh.gulimall.thirdparty.component;import com.aliyun.teaopenapi.models.Config;
import com.aliyun.dysmsapi20170525.Client;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Slf4j
@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms")
@Data //为这些方法生成getter,setter
@Component
public class SmsClient {
//    private static String accessKeyId;
//    private static String accessKeySecret;public static Client createClient() throws Exception {String accessKeyId = "LTAI5tGW4xdUd5pnea6WHFZw";String accessKeySecret = "itwGI52mYtcveb6nA5ltU2ZUvTHLGy";Config config = new Config()// 配置 AccessKey ID,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。.setAccessKeyId(accessKeyId)// 配置 AccessKey Secret,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。.setAccessKeySecret(accessKeySecret);// 配置 Endpointconfig.endpoint = "dysmsapi.aliyuncs.com";return new Client(config);}
}

controller

package com.cwh.gulimall.thirdparty.controller;import com.cwh.gulimall.thirdparty.utils.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.cwh.gulimall.thirdparty.component.SmsClient;
import com.aliyun.dysmsapi20170525.Client;import static com.aliyun.teautil.Common.toJSONString;@RestController
@RequestMapping("/sms")
public class SmsSendController {Client client = SmsClient.createClient();public SmsSendController() throws Exception {}/*** 提供给其他服务调用* @param phone* @param code* @return*/@GetMapping("/sendcode")public R sendCode(@RequestParam("phone") String phone, @RequestParam("code") String code) throws Exception {// 构造请求对象,请填入请求参数值SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers("15866638892").setSignName("ColinCode商城").setTemplateCode("SMS_474140261").setTemplateParam("{\"code\":\"" + code + "\"}");System.out.println("验证码: " + code);// 获取响应对象SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);System.out.println(toJSONString(sendSmsResponse));return R.ok();}
}

1.3. 业务接口实现

@ResponseBody@GetMapping("/sms/sendcode")public R sendCode(@RequestParam("phone") String phone) throws Exception {// 1.接口防刷String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);if (StringUtils.isNotEmpty(redisCode)) {// 60s内不能重发if ((System.currentTimeMillis() - Long.parseLong(redisCode.split("_")[1])) < 60000) {return R.error(10002, "验证码频率过高,稍后再试");}}// 2.验证码再次校验 redis:key:phone, value:codeString code = String.valueOf(RandomUtils.nextInt(10000, 100000));redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone, code, 10, TimeUnit.MINUTES);System.out.println("验证码:" + code);thirdPartFeignService.sendCode(phone, code);return R.ok();}/*** 重定向携带数据,利用Session原理,将数据放入session中,只要跳到下一个页面,取出数据后,session中的数据就会被删掉* // TODO 分布式下的session问题* RedirectAttributes redirectAttributes:模拟重定向携带数据** @param vo* @param bindingResult* @param redirectAttributes* @return*/@Transactional@PostMapping("/register")public String registry(@Valid UserRegistVo vo, BindingResult bindingResult, RedirectAttributes redirectAttributes) {if (bindingResult.hasErrors()) {Map<String, String> errors = bindingResult.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
//            model.addAttribute("errors", errors);// 校验出错,转发到注册页redirectAttributes.addFlashAttribute("errors", errors);// Request method 'POST' not supported:只是Get请求能映射return "redirect:http://auth.gulimall.com/reg.html";}// 调用远程服务// 1.校验验证码String code = vo.getCode();String redisKey = AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone();String s = redisTemplate.opsForValue().get(redisKey);if (StringUtils.isNotEmpty(s) && code.equals(s.split("_")[0])) {// 删除验证码;令牌机制redisTemplate.delete(redisKey);// 验证码校验通过R r = memberFeignService.registry(vo);if (r.getCode() == 0) {// 注册成功回到登录页(重定向)return "redirect:http://auth.gulimall.com/login.html";} else {Map<String, String> errors = new HashMap<>();errors.put("msg", r.getData("msg", new TypeReference<String>() {}));redirectAttributes.addFlashAttribute("errors", errors);return "redirect:http://auth.gulimall.com/reg.html";}} else {Map<String, String> errors = new HashMap<>();errors.put("code", "验证码错误");// 校验出错,转发到注册页redirectAttributes.addFlashAttribute("errors", errors);// Request method 'POST' not supported:只是Get请求能映射return "redirect:http://auth.gulimall.com/reg.html";}}@PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r = memberFeignService.login(vo);if(r.getCode() == 0){MemberRespVo data = r.getData("data", new TypeReference<MemberRespVo>() {});session.setAttribute("loginUser", data);return "redirect:http://gulimall.com";}else {Map<String, String> errors = new HashMap<>();errors.put("msg", r.getData("msg", new TypeReference<String>(){}));redirectAttributes.addFlashAttribute("errors", errors);return "redirect:http://auth.gulimall.com/login.html";}}
@Overridepublic void registry(MemberRegistVo vo){MemberEntity memberEntity = new MemberEntity();// 检查用户名与手机号是否唯一,为了让controller感知异常,异常机制checkPhoneUnique(vo.getPhone());checkUserNameUnique(vo.getUserName());memberEntity.setUsername(vo.getUserName());memberEntity.setMobile(vo.getPhone());memberEntity.setNickname(vo.getUserName());// 设置默认等级MemberLevelEntity levelEntity = memberLevelService.getDefaultLevel();memberEntity.setLevelId(levelEntity.getId());// 密码加密BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();String encode = passwordEncoder.encode(vo.getPassword());memberEntity.setPassword(encode);this.save(memberEntity);}@Overridepublic void checkPhoneUnique(String phone) throws PhoneExistException {int count = this.count(new QueryWrapper<MemberEntity>().eq("mobile", phone));if(count == 1){throw new PhoneExistException();}}@Overridepublic void checkUserNameUnique(String name) throws UserNameExistExcept {int count = this.count(new QueryWrapper<MemberEntity>().eq("username", name));if(count == 1){throw new PhoneExistException();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55791.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ day04(友元 friend、运算符重载、String字符串)

目录 【1】友元 friend 1》概念 2》友元函数 3》友元类 4》友元成员函数 【2】运算符重载 1》概念 2》友元函数运算符重载 ​编辑 3》成员函数运算符重载 4》赋值运算符与类型转换运算符重载 5》注意事项 【3】String 字符串类 【1】友元 friend 1》概念 定义&#x…

YOLOv5改进——添加SimAM注意力机制

目录 一、SimAM注意力机制核心代码 二、修改common.py 三、修改yolo.py ​三、建立yaml文件 四、验证 一、SimAM注意力机制核心代码 在models文件夹下新建modules文件夹&#xff0c;在modules文件夹下新建一个py文件。这里为simam.py。复制以下代码到文件里面。 import…

吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)2.7-2.8

目录 第四门课 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;第二周 深度卷积网络&#xff1a;实例探究&#xff08;Deep convolutional models: case studies&#xff09;2.7 Inception 网络&#xff08;Inception network&#xff09;2.8 使 用 开 源 …

【Linux】 TCP短服务编写和守护进程

文章目录 TCP 短服务编写流程进程组和会话和守护进程 TCP 短服务编写流程 TCP服务器是面向连接的&#xff0c;客户端在发送数据之前需要先与服务器建立连接。 因此&#xff0c;TCP服务器需要能够监听客户端的连接请求。为了实现这一功能&#xff0c;需要将TCP服务器创建的套接字…

75. 颜色分类

思路 先排最小的数&#xff0c;将最小的数都放至列表前面 则0~r-1都是最小值 从r到len(nums)-1继续进行排序&#xff0c;从尾部开始&#xff0c;将最大值放置尾部 class Solution(object):def sortColors(self, nums):""":type nums: List[int]:rtype: None …

Python | Leetcode Python题解之第468题验证IP地址

题目&#xff1a; 题解&#xff1a; class Solution:def validIPAddress(self, queryIP: str) -> str:if queryIP.find(".") ! -1:# IPv4last -1for i in range(4):cur (len(queryIP) if i 3 else queryIP.find(".", last 1))if cur -1:return &q…

Window系统编程 - 文件操作

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天主要介绍使用windows系统编程操作读写文件 文件 CreateFile()函数讲解 介绍:该函数用于打开文件或者I/O流设备&#xff0c;文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和…

Jenkins Pipline流水线

提到 CI 工具&#xff0c;首先想到的就是“CI 界”的大佬--]enkjns,虽然在云原生爆发的年代,蹦出来了很多云原生的 CI 工具,但是都不足以撼动 Jenkins 的地位。在企业中对于持续集成、持续部署的需求非常多,并且也会经常有-些比较复杂的需求,此时新生的 CI 工具不足以支撑这些很…

看门狗电路设计

看门狗电路设计 看门狗是什么应用架构图TPV6823芯片功能硬件时序图为什么要一般是要保持200个毫秒左右的这种低电平的时间看门狗电路实际应用与条件 看门狗是什么 硬件看门狗芯片&#xff0c;Watch DogTimer&#xff0c;可用于受到电气噪音、电源故障、静电放电等影响(造成软件…

LSTM(长短时记忆网络)

一、引言 在处理序列数据时&#xff0c;循环神经网络&#xff08;RNN&#xff09;虽然能够处理序列数据并保留历史信息&#xff0c;但在实践中发现它对于捕捉长时间依赖关系的能力有限&#xff0c;尤其是在训练过程中容易遇到梯度消失或梯度爆炸的问题。为了解决这些问题&…

力扣1031. 两个非重叠子数组的最大和

力扣1031. 两个非重叠子数组的最大和 题目解析及思路 题目要求找到两段长分别为firstLen 和 secondLen的子数组&#xff0c;使两段元素和最大 图解见灵神 枚举第二段区间的右端点&#xff0c;在左边剩余部分中找出元素和最大的第一段区间&#xff0c;并用前缀和优化求子数组…

Nginx基础详解5(nginx集群、四七层的负载均衡、Jmeter工具的使用、实验验证集群的性能与单节点的性能)

续Nginx基础详解4&#xff08;location模块、nginx跨域问题的解决、nginx防盗链的设计原理及应用、nginx模块化解剖&#xff09;-CSDN博客 目录 14.nginx集群&#xff08;前传&#xff09; 14.1如何理解单节点和集群的概念 14.2单节点和集群的比较 14.3Nginx中的负载均衡…

对象的概念

对象是编程中一个重要的概念&#xff0c;尤其在面向对象编程&#xff08;OOP&#xff09;中更为核心。简单来说&#xff0c;对象是一种数据结构&#xff0c;它可以存储相关的数据和功能。以下是关于对象的详细描述&#xff1a; 1. 对象的定义 对象是属性&#xff08;数据&…

QT入门教程攻略 QT入门游戏设计:贪吃蛇实现 QT全攻略心得总结

Qt游戏设计&#xff1a;贪吃蛇 游戏简介 贪吃蛇是一款经典的休闲益智类游戏&#xff0c;玩家通过控制蛇的移动来吃掉地图上的食物&#xff0c;使蛇的身体变长。随着游戏的进行&#xff0c;蛇的移动速度会逐渐加快&#xff0c;难度也随之增加。当蛇撞到墙壁或自己的身体时&…

深入探讨JavaScript中的精度问题:原理与解决方案

深入探讨JavaScript中的精度问题&#xff1a;原理与解决方案 在日常的JavaScript开发中&#xff0c;我们经常会遇到一些令人困惑的数值计算问题&#xff0c;特别是涉及到小数点运算时。例如&#xff0c;为什么0.1 0.2的结果不是预期的0.3&#xff0c;而是0.30000000000000004…

Laravel Filament 如何配置多语言支持

演示 一、安装拓展包outerweb/filament-translatable-fields composer require outerweb/filament-translatable-fields配置模型 该套件包含一个名为 HasTranslations 的特性&#xff0c;用于使 Eloquent 模型具备多语言功能。翻译值以 JSON 格式存储&#xff0c;并不需要额外…

Run the FPGA VI 选项的作用

Run the FPGA VI 选项的作用是决定当主机 VI 运行时&#xff0c;FPGA VI 是否会自动运行。 具体作用&#xff1a; 勾选 “Run the FPGA VI”&#xff1a; 当主机 VI 执行时&#xff0c;如果 FPGA VI 没有正在运行&#xff0c;系统将自动启动并运行该 FPGA VI。 这可以确保 FPG…

夜间数据库IO负载飙升?MySQL批量删除操作引发的问题排查

目录 问题现象 问题分析 修改建议 总结 问题现象 近日&#xff0c;某用户反馈他们的MySQL数据库实例在凌晨时段会频繁出现IO负载急剧上升的情况&#xff0c;这种状态会持续一段时间&#xff0c;随后自行恢复正常。为了查明原因&#xff0c;该用户通过DBdoctor工具收集了相…

js进阶——深入解析JavaScript中的URLSearchParams

深入解析 JavaScript 中的 URLSearchParams 在现代Web开发中&#xff0c;我们经常需要处理URL中的查询参数&#xff0c;尤其是在构建动态Web应用时。这些查询参数&#xff08;query parameters&#xff09;通常以 ?keyvalue&key2value2 的形式存在。JavaScript 提供了一个…

javascript:void(0)

javascript:void(0)是一种常用于HTML中的Javascript语句&#xff0c;通常用作链接的href属性。它的主要作用是防止链接的默认行为(例如跳转到一个新页面或刷新当前页面)&#xff0c;同时又可以执行一些Javascript代码 详细解释 javascript&#xff1a;这是一个协议&#xff0c…