1. 注册功能分析 78
2. 验证手机号是否注册 79
2.1 验证手机号格式 79
操作micr-common
CommonUtil
/*手机号格式 true:格式正确;false不正确*/
public static boolean checkPhone(String phone){
boolean flag = false;
if( phone != null && phone.length() == 11 ){
//^1[1-9]\\d{9}$
flag = Pattern.matches("^1[1-9]\\d{9}$",phone);
}
return flag;
}
添加枚举类 79
2.2 业务接口 80
操作micr-api
UserService
package com.bjpowernode.api.service;
import com.bjpowernode.api.model.User;
//用户操作的业务接口 80
public interface UserService {
//根据手机号查询数据 80
User queryByPhone(String phone);
}
2.3 业务接口实现类
micr-dataservice
UserServiceImpl
package com.bjpowernode.dataservice.service;
import com.bjpowernode.api.model.User;
import com.bjpowernode.api.service.UserService;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.dataservice.mapper.UserMapper;
import org.apache.dubbo.config.annotation.DubboService;
import javax.annotation.Resource;
//用户操作的实现类 80
@DubboService(interfaceClass = UserService.class,version = "1.0")
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
//根据手机号查询数据 80
@Override
public User queryByPhone(String phone) {
User user = null;
if(CommonUtil.checkPhone(phone)){
user = userMapper.selectByPhone(phone);
}
return null;
}
}
2.4 在mapper中定义方法 80
micr-dataservice
UserMapper
//根据手机号查询数据 80
User selectByPhone(String phone);
2.5 编写sql
micr-dataservice
UserMapper.xml
<!--根据手机号查询数据 80-->
<select id="selectByPhone" resultType="com.bjpowernode.api.model.User">
select <include refid="Base_Column_List"></include>
from u_user
where phone = #{phone}
</select>
2.4 消费者 UserContorller 80
操作micr-web
BaseController
//用户操作 80
@DubboReference(interfaceClass = UserService.class,version = "1.0")
protected UserService userService;
UserController 80
package com.bjpowernode.front.controller;
import com.bjpowernode.api.model.User;
import com.bjpowernode.common.enums.RCode;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.front.view.RespResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
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;
//有关用户的操作 79
@Api(tags = "用户功能")
@RestController
@RequestMapping("/v1/user")
public class UserContorller extends BaseController{
//验证手机号是否注册 79
@ApiOperation(value = "手机号是否注册过",notes = "在注册功能中,判断手机号是否可以注册")
@ApiImplicitParam(name = "phone",value = "手机号")
@GetMapping("/phone/exists")
public RespResult phoneExists(@RequestParam("phone") String phone){
RespResult result = new RespResult();
result.setRCode(RCode.PHONE_EXISTS);
//检查请求参数手机号是否符合要求 79
if(CommonUtil.checkPhone(phone)){
//可以执行逻辑,查询数据库,调用数据服务
User user = userService.queryByPhone(phone);
if (user==null){
//可以注册
result = RespResult.ok();
}
}else {
result.setRCode(RCode.PHONE_FORMAT_ERR);
}
return result;
}
}
测试 81
使用postman
http://localhost:8000/api/v1/user/phone/exists
3. 发送短信 82-85
这里我们使用京东万象的短信服务
资料我放在了E:\java学习\盈利宝\资料\资料\07-短信验证码
3.1加入依赖 85
micr-common
pom.xml
<!-- 加入commons-lang3依赖 85-->
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--87-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--fastjson 87-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
3.2 配置文件 85
micr-web
application.yml
#短信配置 85
jdwx:
sms:
url: https://way.jd.com/chuangxin/dxjk
appkey: 3680fa919b771148da626bbcbd459475
content: 【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人
3.3 京东万象短信配置类 85
JdwxSmsConfig
package com.bjpowernode.front.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//京东万象短信配置类 85
@Component
@ConfigurationProperties(prefix = "jdwx.sms")
public class JdwxSmsConfig {
private String url;
private String appkey;
private String content;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppkey() {
return appkey;
}
public void setAppkey(String appkey) {
this.appkey = appkey;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
3.4 短信业务接口 86
micr-web
SmsService
package com.bjpowernode.front.service;
//短信服务的业务接口 86
public interface SmsService {
//发送短信 86
boolean sendSms(String phone);
}
3.5 短信业务接口的实现类 86-87
micr-common
micr-web
SmsCodeRegisterImpl 87
package com.bjpowernode.front.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.front.config.JdwxSmsConfig;
import com.bjpowernode.front.service.SmsService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* 短信服务的业务接口实现类 86
* 注册发送短信验证码
*/
@Service
public class SmsCodeRegisterImpl implements SmsService {
//注入StringRedisTemplate 89
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private JdwxSmsConfig smsConfig;
@Override
public boolean sendSms(String phone) {
boolean send = false;
// 设置短信内容,生成随机数
String random = RandomStringUtils.randomNumeric(4);
System.out.println("注册验证码的随机数 random="+random);
//更新content中的 %s 【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人
String content = String.format(smsConfig.getContent(), random);
//使用HttpClient发送 get 请求 给第三方。87
CloseableHttpClient client = HttpClients.createDefault();
//https://way.jd.com/chuangxin/dxjk?mobile=13568813957&content=
//【创信】你的验证码是:5873,3分钟内有效!&appkey=您申请的APPKEY
String url = smsConfig.getUrl()+"?mobile="+phone
+"&content=" + content
+"&appkey="+smsConfig.getAppkey();
//创建get方式发送 87
HttpGet get = new HttpGet(url);
try{
//发送
CloseableHttpResponse response = client.execute(get);
//发送成功
if( response.getStatusLine().getStatusCode() == HttpStatus.SC_OK ){
//得到返回的数据,json 87
// String text = EntityUtils.toString(response.getEntity());
//因为发送短信过期了,所以我们为了测试就改造一下
//模拟成功 返回的数据 88
String text="{\n" +
" \"code\": \"10000\",\n" +
" \"charge\": false,\n" +
" \"remain\": 1305,\n" +
" \"msg\": \"查询成功\",\n" +
" \"result\": {\n" +
" \"ReturnStatus\": \"Success\",\n" +
" \"Message\": \"ok\",\n" +
" \"RemainPoint\": 420842,\n" +
" \"TaskID\": 18424321,\n" +
" \"SuccessCounts\": 1\n" +
" }\n" +
"}";
//解析json 87
if(StringUtils.isNotBlank(text)){
// fastjson 87
//将得到的数据 转为json对象
JSONObject jsonObject = JSONObject.parseObject(text);
if("10000".equals(jsonObject.getString("code"))){ //第三方接口调用成功
//读取result中的key:ReturnStatus
if("Success".equalsIgnoreCase( //equalsIgnoreCase忽略大小写的比较字符串
//因为result是json,所以要得到他就用getJSONObject
jsonObject.getJSONObject("result").getString("ReturnStatus"))){
//短信发送成功
send = true;
//把短信验证码,存到redis 89
String key = RedisKey.KEY_SMS_CODE_REG + phone;
stringRedisTemplate.boundValueOps(key).set(random,3 , TimeUnit.MINUTES);
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return send;
}
}
3.6 controller 87-89
micr-common
micr-web
SmsController 89
package com.bjpowernode.front.controller;
import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.common.enums.RCode;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.front.service.SmsService;
import com.bjpowernode.front.view.RespResult;
import io.swagger.annotations.Api;
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 javax.annotation.Resource;
//短信服务 85
@Api(tags = "短信业务")
@RestController
@RequestMapping("/v1/sms")
public class SmsController extends BaseController{
@Resource
private SmsService smsService;
//发送短信验证码 85
@GetMapping("/code/register")
public RespResult sendCodeRegister(@RequestParam String phone){
RespResult result = RespResult.fail();
if(CommonUtil.checkPhone(phone)){//手机号格式正确,可以发送短信 89
//判断redis中是否有这个手机号的验证码 89
String key = RedisKey.KEY_SMS_CODE_REG + phone;
if(stringRedisTemplate.hasKey(key)){
result = RespResult.ok();
result.setRCode(RCode.SMS_CODE_CAN_USE);
} else {
boolean isSuccess = smsService.sendSms(phone);
if( isSuccess ){
result = RespResult.ok();
}
}
}else {
result.setRCode(RCode.PHONE_FORMAT_ERR);
}
return result;
}
}
4. 手机号的用户注册 90
4.1 业务接口 91
micr-api
UserService
//用户注册 91
int userRegister(String phone, String password);
4.2 业务接口实现类 91
4.2.1 密码的盐 91
micr-dataservice
4.2.2添加记录和获取主键值 91
在UserMapper中定义方法91
//添加记录和获取主键值 91
int insertReturnPrimaryKey(User user);
编写sql 91
LAST_INSERT_ID() 时获取你刚刚添加的自增列的值
并且把获取到的主键值赋值给keyProperty="id"也就是user的id
<!--添加记录和获取主键值 92-->
<insert id="insertReturnPrimaryKey">
insert into u_user(phone, login_password,add_time)
values(#{phone},#{loginPassword},#{addTime})
<selectKey keyColumn="newId" keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID() as newId
</selectKey>
</insert>
4.2.3 实现类UserServiceImpl 91
//用户注册 91
@Transactional(rollbackFor = Exception.class) //添加事务,发生异常就回滚 92
@Override //synchronized时同步方法的意思,考虑线程安全 92
public synchronized int userRegister(String phone, String password) {
int result = 0;//默认参数不正确 91
if(CommonUtil.checkPhone(phone)
&&(password!=null&&password.length()==32)){
//判断手机号在库中是否存在 92
User queryUser = userMapper.selectByPhone(phone);
if(queryUser==null){//数据库中不存在此手机号,即用户没注册过,可以注册 92
//注册密码MD5二次加密,给原始密码加盐 91
String newPassword = DigestUtils.md5Hex( password + passwordSalt);
//注册添加进u_user表
User user = new User();
user.setPhone(phone);
user.setLoginPassword(newPassword);
user.setAddTime(new Date());
userMapper.insertReturnPrimaryKey(user);
//解释,既然用户注册添加成功,我们就要给他开一个资金账户
// 即添加一条记录到u_finance_account 92
//获取主键user.getId()
FinanceAccount account = new FinanceAccount();
account.setUid(user.getId());
account.setAvailableMoney(new BigDecimal("0"));
financeAccountMapper.insertSelective(account);
//成功result = 1
result = 1;
}else {
//手机号存在
result = 2;
}
}
return result;
}
4.3 检查验证码是否正确 90
4.3.1 业务接口
在micr-web
SmsService
//检查验证码 90
boolean checkSmsCode(String phone,String code);
4.3.2 业务接口实现类 90
SmsCodeRegisterImpl
//检查验证码 90
@Override
public boolean checkSmsCode(String phone, String code) {
//拼接key
String key = RedisKey.KEY_SMS_CODE_REG+phone;
if(stringRedisTemplate.hasKey(key)){//redis中右key
//去除value
String querySmsCode = stringRedisTemplate.boundValueOps(key).get();
if(code.equals(querySmsCode)){//比较
return true;
}
}
return false;
}
4.4 消费者 controller 90
micr-common
micr-web
UserContorller 90-92
//用户注册 90
@ApiOperation(value = "手机号注册用户")
@PostMapping("/register")
public RespResult userRegister(@RequestParam String phone,
@RequestParam String pword,
@RequestParam String scode){
RespResult result = RespResult.fail();
//1.检查参数
if( CommonUtil.checkPhone(phone)){
if(pword !=null && pword.length() == 32 ){
//检查短信验证码
if( smsService.checkSmsCode(phone,scode)){
//可以注册
int registerResult = userService.userRegister(phone,pword);
if( registerResult == 1 ){//注册成功 92
result = RespResult.ok();
} else if( registerResult == 2 ){//手机号已注册过 92
result.setRCode(RCode.PHONE_EXISTS);
} else {//请求参数有误 92
result.setRCode(RCode.REQUEST_PARAM_ERR);
}
} else {
//短信验证码无效
result.setRCode(RCode.SMS_CODE_INVALID);
}
} else {
//请求参数有误
result.setRCode(RCode.REQUEST_PARAM_ERR);
}
} else {
//手机号格式不正确
result.setRCode(RCode.PHONE_FORMAT_ERR);
}
return result;
}
测试 92-93
使用postman
首先,获取验证码
在测试注册,填好参数
我们可以使用md5的在线工具,生成一个密码帮助我们测试
发送请求
看看数据库成功添加
如果我们用一样的手机号注册,会提示已经注册过了
如果验证码失效了,还发送请求的话会提示验证码无效
标签:功能,短信,String,bjpowernode,phone,result,注册,import,com From: https://blog.51cto.com/u_15784725/7058195