本文将讲解用户注册功能

81分布式电商项目 - 用户注册_短信验证码

工程搭建

用户服务接口层

(1)创建 pinyougou-user-interface(jar)

(2)引入 pojo 依赖

用户服务实现层

(1)创建 pinyougou-user-service(war)

(2)引入 spring dubbox activeMQ 相关依赖,引入依赖( pinyougou-user-interface pinyougou-dao pinyougou-common),运行端口为 9006

(3)添加 web.xml

(4)创建 Spring 配置文件 applicationContext-service.xml 和 applicationContent-tx.xml

<dubbo:protocol name="dubbo" port="20886" />
<dubbo:annotation package="com.pinyougou.user.service.impl" />
<dubbo:application name="pinyougou-user-service"/>
<dubbo:registry address="zookeeper://192.168.25.135:2181"/>

用户中心WEB层

创建 war 工程 pinyougou-user-web 我们将注册功能放入此工程

(1)添加 web.xml

(2)引入依赖 pinyougou-user-interface 、spring 相关依赖(参照其它 web 工程),tomcat 运行端口 9106

(3)添加 spring 配置文件

(4)拷贝静态原型页面 register.html 及相关资源

基本注册功能实现

生成和拷贝代码

81分布式电商项目 - 用户注册_验证码_02

81分布式电商项目 - 用户注册_验证码_03

后端服务实现层

修改 pinyougou-user-service 的 UserServiceImpl.java

/**
* 增加
*/
@Override
public void add(TbUser user) {
user.setCreated(new Date());//创建日期
user.setUpdated(new Date());//修改日期
String password = DigestUtils.md5Hex(user.getPassword());//对密码加密
user.setPassword(password);
userMapper.insert(user);
}

前端控制层

修改 userController.js

//控制层
app.controller('userController' ,function($scope,$controller ,userService){
//注册
$scope.reg=function(){
if($scope.entity.password!=$scope.password) {
alert("两次输入的密码不一致,请重新输入");
return ;
}
userService.add( $scope.entity ).success(
function(response){
alert(response.message);
}
);
}
});

修改页面

修改页面 register.html ,引入 js

<script type="text/javascript" src="plugins/angularjs/angular.min.js"></script> 
<script type="text/javascript" src="js/base.js"></script>
<script type="text/javascript" src="js/service/userService.js"></script>
<script type="text/javascript" src="js/controller/userController.js"></script>

指令

<body ng-app="pinyougou" ng-controller="userController" >

绑定表单

<form class="sui-form form-horizontal">
<div class="control-group">
<label class="control-label">用户名:</label>
<div class="controls">
<input type="text" placeholder="请输入你的用户名" ng-model="entity.username" class="input-xfat input-xlarge">
</div>
</div>
<div class="control-group">
<label for="inputPassword" class="control-label">登录密码:</label>
<div class="controls">
<input type="password" placeholder="设置登录密码" ng-model="entity.password" class="input-xfat input-xlarge">
</div>
</div>
<div class="control-group">
<label for="inputPassword" class="control-label">确认密码:</label>
<div class="controls">
<input type="password" placeholder="再次确认密码" ng-model="password" class="input-xfat input-xlarge">
</div>
</div>
<div class="control-group"><label class="control-label">手机号:</label>
<div class="controls"><input type="text" placeholder="请输入你的手机号" ng-model="entity.phone" class="input-xfat input-xlarge"></div>
</div>
<div class="control-group"><label for="inputPassword" class="control-label">短信验证码:</label<div class="controls"><input type="text" placeholder="短信验证码" class="input-xfat
input-xlarge"> <a href="#">获取短信验证码</a></div></div><div class="control-group"><label for="inputPassword"class="control-label">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<div class="controls"><input name="m1" type="checkbox" value="2" checked=""><span>同意协并注册《品优购用户协议》</span></div>
</div>
<div class="control-group">
<label class="control-label"></label>
<div class="controls btn-reg">
<a class="sui-btn btn-block btn-xlarge btn-danger" ng-click="reg()target=" _blank ">完成注册</a>
</div>
</div>
</form>

注册判断短信验证码

实现思路

点击页面上的”获取短信验证码”连接,向后端传递手机号。后端随机生成 6 位数字作为短信验证码,将其保存在 redis 中(手机号作为 KEY),并发送到短信网关。

用户注册时,后端根据手机号查询 redis 中的验证码与用户填写的验证码是否相同,如果不同则提示用户不能注册。

生成验证码

(1)修改 pinyougou-user-interface 工程 UserService.java ,增加方法

/**
* 生成短信验证码
* @return
*/
public void createSmsCode(String phone);

(2)修改 pinyougou-user-service 工程的 UserServiceImpl.java

@Autowiredprivate RedisTemplate<String , Object> redisTemplate;
/*** 生成短信验证码*/
public void createSmsCode(String phone){
//生成 6 位随机数String code = (long) (Math.random()*1000000)+"";System.out.println("验证码:"+code);

//存入缓存
redisTemplate.boundHashOps("smscode").put(phone, code);

//发送到 activeMQ ....
}

(3)在 pinyougou-common 添加工具类 PhoneFormatCheckUtils.java,用于验证手机号

(4)修改 pinyougou-user-web 的 UserController.java

/*
** 发送短信验证码
* @param phone
* @return
* */
@RequestMapping("/sendCode")
public Result sendCode(String phone){
//判断手机号格式
if(!PhoneFormatCheckUtils.isPhoneLegal(phone)){
return new Result(false, "手机号格式不正确");
}
try {
userService.createSmsCode(phone);//生成验证码
return new Result(true, "验证码发送成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(true, "验证码发送失败");
}
}

(5)pinyougou-user-web 的 userService.js

//发送验证码
this.sendCode=function(phone){
return $http.get("../user/sendCode.do?phone="+phone);
}

(6)pinyougou-user-web 的 userController.js

//发送验证码
$scope.sendCode=function(){
if($scope.entity.phone==null){
alert("请输入手机号!");return ;
}
userService.sendCode($scope.entity.phone).success(
function(response){
alert(response.message);
}
);
}

(7)修改页面 register.html

<a ng-click="sendCode()" >获取短信验证码</a>

用户注册判断验证码

(1)修改 pinyougou-user-interface 的UserService.java

/**
* 判断短信验证码是否存在
* @param phone
* @return
* */
public boolean checkSmsCode(String phone,String code);

(2)修改 pinyougou-user-service 的UserServiceImpl.java

/**
* 判断验证码是否正确
*/
public boolean checkSmsCode(String phone,String code){
//得到缓存中存储的验证码
String sysCode = (String) redisTemplate.boundHashOps("smscode").get(phone);
if(sysCode==null){
return false;
}
if(!sysCode.equals(code)){
return false;
}
return true;
}

(3)修改 pinyougou-user-web 的UserController.java

/**
* 增加
*
* @param user
* @return
*/
@RequestMapping("/add")
public Result add(@RequestBody TbUser user,String smscode){
boolean checkSmsCode =userService.checkSmsCode(user.getPhone(), smscode);
if(checkSmsCode==false){
return new Result(false, "验证码输入错误!");
}try {
userService.add(user);
return new Result(true, "增加成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "增加失败");
}
}

(4)修改 pinyougou-user-web 的 userService.js

//增加
this.add=function(entity,smscode){
return $http.post('../user/add.do?smscode='+smscode ,entity );
}

(5)修改 pinyougou-portal-web 的UserController.java

//保存
$scope.reg=function(){
userService.add( $scope.entity, $scope.smscode ).success(
function(response){
alert(response.message);
}
);
}

(6)修改页面,绑定变量

<input type="text" placeholder="短信验证码" ng-model="smscode" class="input-xfat input-xlarge">
<a href="#" ng-click="sendCode()">获取短信验证码</a>

短信验证码发送到手机

(1)在 pinyougou-user-service 添加配置文件 applicationContext-activemq.xml

<!-- 真正可以产生 Connection 的 ConnectionFactory,由对应的 JMS 服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.135:61616"/>
</bean>
<!-- Spring 用于管理真正的 ConnectionFactory 的 ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标 ConnectionFactory 对应真实的可以产生 JMS Connection 的 ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- Spring 提供的 JMS 工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate"
class="org.springframework.jms.core.JmsTemplate"><!-- 这个 connectionFactory 对应的是我们定义的 Spring 提供的那个 ConnectionFacto对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean><!--这个是点对点消息 -->
<bean id="smsDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="sms"/>
</bean>

(2)修改 pinyougou-user-service 的UserServiceImpl.java

@Autowiredprivate
JmsTemplate jmsTemplate;
@Autowiredprivate
Destination smsDestination;
@Value("${template_code}")
private String template_code;
@Value("${sign_name}")
private String sign_name;

/*** 生成短信验证码*/
public void createSmsCode(final String phone) {//生成 6 位随机数final String code = (long) (Math.random()*1000000)+"";System.out.println("验证码:"+code);//存入缓存redisTemplate.boundHashOps("smscode").put(phone, code);//发送到 activeMQ
jmsTemplate.send(smsDestination, new MessageCreator() {
@Overridepublic
Message createMessage(Session session) throws JMSException {
MapMessage mapMessage = session.createMapMessage();
mapMessage.setString("mobile", phone);//手机号mapMessage.setString("template_code", "SMS_85735065");//模板编号mapMessage.setString("sign_name", "黑马");//签名Map m=new HashMap<>();m.put("number", code);mapMessage.setString("param", JSON.toJSONString(m));//参数return mapMessage;}});}

}
}

(3)在 pinyougou-common 的 properties 目录下创建配置文件 sms.properties

template_code=SMS_85735065
sign_name=\u9ED1\u9A6C